فهرست منبع

Add Linux SGX support (#106)

wenyongh 6 سال پیش
والد
کامیت
5c69543c54
26فایلهای تغییر یافته به همراه2223 افزوده شده و 24 حذف شده
  1. 1026 0
      core/iwasm/lib/native/libc/libc_wrapper_sgx.c
  2. 1 1
      core/iwasm/lib/native/libc/wasm_libc.cmake
  3. 23 0
      core/iwasm/lib/native/libc/wasm_libc_sgx.cmake
  4. 89 0
      core/iwasm/products/linux-sgx/CMakeLists.txt
  5. 21 0
      core/iwasm/products/linux-sgx/ext_lib_export.c
  6. 3 1
      core/iwasm/runtime/platform/include/wasm_platform_log.h
  7. 25 0
      core/iwasm/runtime/platform/linux-sgx/platform.cmake
  8. 332 0
      core/iwasm/runtime/platform/linux-sgx/wasm_native.c
  9. 3 0
      core/shared-lib/include/bh_common.h
  10. 4 0
      core/shared-lib/include/config.h
  11. 7 8
      core/shared-lib/mem-alloc/bh_memory.c
  12. 7 7
      core/shared-lib/mem-alloc/ems/ems_alloc.c
  13. 1 1
      core/shared-lib/mem-alloc/ems/ems_gc_internal.h
  14. 6 6
      core/shared-lib/mem-alloc/ems/ems_kfc.c
  15. 2 0
      core/shared-lib/platform/alios/bh_platform.h
  16. 69 0
      core/shared-lib/platform/linux-sgx/bh_assert.c
  17. 81 0
      core/shared-lib/platform/linux-sgx/bh_definition.c
  18. 67 0
      core/shared-lib/platform/linux-sgx/bh_platform.c
  19. 115 0
      core/shared-lib/platform/linux-sgx/bh_platform.h
  20. 41 0
      core/shared-lib/platform/linux-sgx/bh_platform_log.c
  21. 190 0
      core/shared-lib/platform/linux-sgx/bh_thread.c
  22. 80 0
      core/shared-lib/platform/linux-sgx/bh_time.c
  23. 24 0
      core/shared-lib/platform/linux-sgx/shared_platform.cmake
  24. 2 0
      core/shared-lib/platform/linux/bh_platform.h
  25. 2 0
      core/shared-lib/platform/vxworks/bh_platform.h
  26. 2 0
      core/shared-lib/platform/zephyr/bh_platform.h

+ 1026 - 0
core/iwasm/lib/native/libc/libc_wrapper_sgx.c

@@ -0,0 +1,1026 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wasm_native.h"
+#include "wasm_export.h"
+#include "wasm_log.h"
+#include "wasm_platform_log.h"
+
+void
+wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
+
+uint32
+wasm_runtime_get_temp_ret(wasm_module_inst_t module);
+
+void
+wasm_runtime_set_temp_ret(wasm_module_inst_t module, uint32 temp_ret);
+
+uint32
+wasm_runtime_get_llvm_stack(wasm_module_inst_t module);
+
+void
+wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack);
+
+#define get_module_inst() \
+    wasm_runtime_get_current_module_inst()
+
+#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)
+
+typedef int (*out_func_t)(int c, void *ctx);
+
+enum pad_type {
+    PAD_NONE,
+    PAD_ZERO_BEFORE,
+    PAD_SPACE_BEFORE,
+    PAD_SPACE_AFTER,
+};
+
+typedef char *_va_list;
+#define _INTSIZEOF(n)       \
+    ((sizeof(n) +  3) & ~3)
+#define _va_arg(ap,t)       \
+    (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
+
+#if OPS_INPUT_OUTPUT
+/**
+ * @brief Output an unsigned int in hex format
+ *
+ * Output an unsigned int on output installed by platform at init time. Should
+ * be able to handle an unsigned int of any size, 32 or 64 bit.
+ * @param num Number to output
+ *
+ * @return N/A
+ */
+static void
+_printf_hex_uint(out_func_t out, void *ctx,
+                 const uint64 num, bool is_u64,
+                 enum pad_type padding,
+                 int min_width)
+{
+    int size = sizeof(num) * (is_u64 ? 2 : 1);
+    int found_largest_digit = 0;
+    int remaining = 8; /* 8 digits max */
+    int digits = 0;
+
+    for (; size; size--) {
+        char nibble = (num >> ((size - 1) << 2) & 0xf);
+
+        if (nibble || found_largest_digit || size == 1) {
+            found_largest_digit = 1;
+            nibble += nibble > 9 ? 87 : 48;
+            out((int) nibble, ctx);
+            digits++;
+            continue;
+        }
+
+        if (remaining-- <= min_width) {
+            if (padding == PAD_ZERO_BEFORE) {
+                out('0', ctx);
+            } else if (padding == PAD_SPACE_BEFORE) {
+                out(' ', ctx);
+            }
+        }
+    }
+
+    if (padding == PAD_SPACE_AFTER) {
+        remaining = min_width * 2 - digits;
+        while (remaining-- > 0) {
+            out(' ', ctx);
+        }
+    }
+}
+
+/**
+ * @brief Output an unsigned int in decimal format
+ *
+ * Output an unsigned int on output installed by platform at init time. Only
+ * works with 32-bit values.
+ * @param num Number to output
+ *
+ * @return N/A
+ */
+static void
+_printf_dec_uint(out_func_t out, void *ctx,
+                 const uint32 num,
+                 enum pad_type padding,
+                 int min_width)
+{
+    uint32 pos = 999999999;
+    uint32 remainder = num;
+    int found_largest_digit = 0;
+    int remaining = 10; /* 10 digits max */
+    int digits = 1;
+
+    /* make sure we don't skip if value is zero */
+    if (min_width <= 0) {
+        min_width = 1;
+    }
+
+    while (pos >= 9) {
+        if (found_largest_digit || remainder > pos) {
+            found_largest_digit = 1;
+            out((int) ((remainder / (pos + 1)) + 48), ctx);
+            digits++;
+        } else if (remaining <= min_width && padding < PAD_SPACE_AFTER) {
+            out((int) (padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx);
+            digits++;
+        }
+        remaining--;
+        remainder %= (pos + 1);
+        pos /= 10;
+    }
+    out((int) (remainder + 48), ctx);
+
+    if (padding == PAD_SPACE_AFTER) {
+        remaining = min_width - digits;
+        while (remaining-- > 0) {
+            out(' ', ctx);
+        }
+    }
+}
+
+static void
+print_err(out_func_t out, void *ctx)
+{
+    out('E', ctx);
+    out('R', ctx);
+    out('R', ctx);
+}
+
+static void
+_vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap,
+         wasm_module_inst_t module_inst)
+{
+    int might_format = 0; /* 1 if encountered a '%' */
+    enum pad_type padding = PAD_NONE;
+    int min_width = -1;
+    int long_ctr = 0;
+
+    /* fmt has already been adjusted if needed */
+
+    while (*fmt) {
+        if (!might_format) {
+            if (*fmt != '%') {
+                out((int) *fmt, ctx);
+            }
+            else {
+                might_format = 1;
+                min_width = -1;
+                padding = PAD_NONE;
+                long_ctr = 0;
+            }
+        }
+        else {
+            switch (*fmt) {
+            case '-':
+                padding = PAD_SPACE_AFTER;
+                goto still_might_format;
+
+            case '0':
+                if (min_width < 0 && padding == PAD_NONE) {
+                    padding = PAD_ZERO_BEFORE;
+                    goto still_might_format;
+                }
+                /* Fall through */
+            case '1' ... '9':
+                if (min_width < 0) {
+                    min_width = *fmt - '0';
+                } else {
+                    min_width = 10 * min_width + *fmt - '0';
+                }
+
+                if (padding == PAD_NONE) {
+                    padding = PAD_SPACE_BEFORE;
+                }
+                goto still_might_format;
+
+            case 'l':
+                long_ctr++;
+                /* Fall through */
+            case 'z':
+            case 'h':
+                /* FIXME: do nothing for these modifiers */
+                goto still_might_format;
+
+            case 'd':
+            case 'i': {
+                int32 d;
+
+                if (long_ctr < 2) {
+                    d = _va_arg(ap, int32);
+                }
+                else {
+                    int64 lld = _va_arg(ap, int64);
+                    if (lld > INT32_MAX || lld < INT32_MIN) {
+                        print_err(out, ctx);
+                        break;
+                    }
+                    d = (int32)lld;
+                }
+
+                if (d < 0) {
+                    out((int)'-', ctx);
+                    d = -d;
+                    min_width--;
+                }
+                _printf_dec_uint(out, ctx, d, padding, min_width);
+                break;
+            }
+            case 'u': {
+                uint32 u;
+
+                if (long_ctr < 2) {
+                    u = _va_arg(ap, uint32);
+                }
+                else {
+                    uint64 llu = _va_arg(ap, uint64);
+                    if (llu > INT32_MAX) {
+                        print_err(out, ctx);
+                        break;
+                    }
+                    u = (uint32)llu;
+                }
+                _printf_dec_uint(out, ctx, u, padding, min_width);
+                break;
+            }
+            case 'p':
+                out('0', ctx);
+                out('x', ctx);
+                /* left-pad pointers with zeros */
+                padding = PAD_ZERO_BEFORE;
+                min_width = 8;
+                /* Fall through */
+            case 'x':
+            case 'X': {
+                uint64 x;
+                bool is_ptr = (*fmt == 'p') ? true : false;
+
+                if (long_ctr < 2) {
+                    x = _va_arg(ap, uint32);
+                } else {
+                    x = _va_arg(ap, uint64);
+                }
+                _printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width);
+                break;
+            }
+
+            case 's': {
+                char *s;
+                char *start;
+                int32 s_offset = _va_arg(ap, uint32);
+
+                if (!validate_app_addr(s_offset, 1)) {
+                    wasm_runtime_set_exception(module_inst, "out of bounds memory access");
+                    return;
+                }
+
+                s = start = addr_app_to_native(s_offset);
+
+                while (*s)
+                    out((int) (*s++), ctx);
+
+                if (padding == PAD_SPACE_AFTER) {
+                    int remaining = min_width - (s - start);
+                    while (remaining-- > 0) {
+                        out(' ', ctx);
+                    }
+                }
+                break;
+            }
+
+            case 'c': {
+                int c = _va_arg(ap, int);
+                out(c, ctx);
+                break;
+            }
+
+            case '%': {
+                out((int) '%', ctx);
+                break;
+            }
+
+            default:
+                out((int) '%', ctx);
+                out((int) *fmt, ctx);
+                break;
+            }
+
+            might_format = 0;
+        }
+
+still_might_format:
+        ++fmt;
+    }
+}
+
+struct str_context {
+    char *str;
+    int max;
+    int count;
+};
+
+static int
+sprintf_out(int c, struct str_context *ctx)
+{
+    if (!ctx->str || ctx->count >= ctx->max) {
+        ctx->count++;
+        return c;
+    }
+
+    if (ctx->count == ctx->max - 1) {
+        ctx->str[ctx->count++] = '\0';
+    } else {
+        ctx->str[ctx->count++] = c;
+    }
+
+    return c;
+}
+
+static int
+printf_out(int c, struct str_context *ctx)
+{
+    bh_printf("%c", c);
+    ctx->count++;
+    return c;
+}
+
+static inline _va_list
+get_va_list(uint32 *args)
+{
+    union {
+        uint32 u;
+        _va_list v;
+    } u;
+    u.u = args[0];
+    return u.v;
+}
+
+static bool
+parse_printf_args(wasm_module_inst_t module_inst, int32 fmt_offset,
+                  int32 va_list_offset, const char **p_fmt,
+                  _va_list *p_va_args)
+{
+    const char *fmt;
+    union {
+        uintptr_t u;
+        _va_list v;
+    } u;
+
+    if (!validate_app_addr(fmt_offset, 1)
+        || !validate_app_addr(va_list_offset, sizeof(int32)))
+        return false;
+
+    fmt = (const char*) addr_app_to_native(fmt_offset);
+    u.u = (uintptr_t) addr_app_to_native(va_list_offset);
+
+    *p_fmt = fmt;
+    *p_va_args = u.v;
+    return true;
+}
+
+static int
+_printf_wrapper(int32 fmt_offset, int32 va_list_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    struct str_context ctx = { NULL, 0, 0 };
+    const char *fmt;
+    _va_list va_args;
+
+    if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
+        return 0;
+
+    _vprintf((out_func_t) printf_out, &ctx, fmt, va_args, module_inst);
+    return ctx.count;
+}
+
+static int
+_sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    struct str_context ctx;
+    char *str;
+    const char *fmt;
+    _va_list va_args;
+
+    if (!validate_app_addr(str_offset, 1))
+        return 0;
+
+    str = addr_app_to_native(str_offset);
+
+    if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
+        return 0;
+
+    ctx.str = str;
+    ctx.max = INT_MAX;
+    ctx.count = 0;
+
+    _vprintf((out_func_t) sprintf_out, &ctx, fmt, va_args, module_inst);
+
+    if (ctx.count < ctx.max) {
+        str[ctx.count] = '\0';
+    }
+
+    return ctx.count;
+}
+
+static int
+_snprintf_wrapper(int32 str_offset, int32 size, int32 fmt_offset,
+                  int32 va_list_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    struct str_context ctx;
+    char *str;
+    const char *fmt;
+    _va_list va_args;
+
+    if (!validate_app_addr(str_offset, size))
+        return 0;
+
+    str = addr_app_to_native(str_offset);
+
+    if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
+        return 0;
+
+    ctx.str = str;
+    ctx.max = size;
+    ctx.count = 0;
+
+    _vprintf((out_func_t) sprintf_out, &ctx, fmt, va_args, module_inst);
+
+    if (ctx.count < ctx.max) {
+        str[ctx.count] = '\0';
+    }
+
+    return ctx.count;
+}
+
+static int
+_puts_wrapper(int32 str_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    const char *str;
+
+    if (!validate_app_addr(str_offset, 1))
+        return 0;
+
+    str = addr_app_to_native(str_offset);
+    return bh_printf("%s\n", str);
+}
+
+static int
+_putchar_wrapper(int c)
+{
+    bh_printf("%c", c);
+    return 1;
+}
+#endif /* OPS_INPUT_OUTPUT */
+
+static int32
+_memcmp_wrapper(int32 s1_offset, int32 s2_offset, int32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *s1, *s2;
+
+    if (!validate_app_addr(s1_offset, size)
+        || !validate_app_addr(s2_offset, size))
+        return 0;
+
+    s1 = addr_app_to_native(s1_offset);
+    s2 = addr_app_to_native(s2_offset);
+    return memcmp(s1, s2, size);
+}
+
+static int32
+_memcpy_wrapper(int32 dst_offset, int32 src_offset, int32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *dst, *src;
+
+    if (size == 0)
+        return dst_offset;
+
+    if (!validate_app_addr(dst_offset, size)
+        || !validate_app_addr(src_offset, size))
+        return dst_offset;
+
+    dst = addr_app_to_native(dst_offset);
+    src = addr_app_to_native(src_offset);
+    memcpy(dst, src, size);
+    return dst_offset;
+}
+
+static int32
+_memmove_wrapper(int32 dst_offset, int32 src_offset, int32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *dst, *src;
+
+    if (!validate_app_addr(dst_offset, size)
+        || !validate_app_addr(src_offset, size))
+        return dst_offset;
+
+    dst = addr_app_to_native(dst_offset);
+    src = addr_app_to_native(src_offset);
+    memmove(dst, src, size);
+    return dst_offset;
+}
+
+static int32
+_memset_wrapper(int32 s_offset, int32 c, int32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *s;
+
+    if (!validate_app_addr(s_offset, size))
+        return s_offset;
+
+    s = addr_app_to_native(s_offset);
+    memset(s, c, size);
+    return s_offset;
+}
+
+#if OPS_UNSAFE_BUFFERS
+
+static int32
+_strdup_wrapper(int32 str_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char *str, *str_ret;
+    uint32 len;
+    int32 str_ret_offset = 0;
+
+    if (!validate_app_addr(str_offset, 1))
+        return 0;
+
+    str = addr_app_to_native(str_offset);
+
+    if (str) {
+        len = strlen(str) + 1;
+
+        str_ret_offset = module_malloc(len);
+        if (str_ret_offset) {
+            str_ret = addr_app_to_native(str_ret_offset);
+            memcpy(str_ret, str, len);
+        }
+    }
+
+    return str_ret_offset;
+}
+
+static int32
+_strchr_wrapper(int32 s_offset, int32 c)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    const char *s;
+    char *ret;
+
+    if (!validate_app_addr(s_offset, 1))
+        return s_offset;
+
+    s = addr_app_to_native(s_offset);
+    ret = strchr(s, c);
+    return ret ? addr_native_to_app(ret) : 0;
+}
+
+static int32
+_strcmp_wrapper(int32 s1_offset, int32 s2_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *s1, *s2;
+
+    if (!validate_app_addr(s1_offset, 1)
+        || !validate_app_addr(s2_offset, 1))
+        return 0;
+
+    s1 = addr_app_to_native(s1_offset);
+    s2 = addr_app_to_native(s2_offset);
+    return strcmp(s1, s2);
+}
+
+static int32
+_strncmp_wrapper(int32 s1_offset, int32 s2_offset, uint32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *s1, *s2;
+
+    if (!validate_app_addr(s1_offset, size)
+        || !validate_app_addr(s2_offset, size))
+        return 0;
+
+    s1 = addr_app_to_native(s1_offset);
+    s2 = addr_app_to_native(s2_offset);
+    return strncmp(s1, s2, size);
+}
+
+static int32
+_strcpy_wrapper(int32 dst_offset, int32 src_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char *dst, *src;
+
+    if (!validate_app_addr(dst_offset, 1)
+        || !validate_app_addr(src_offset, 1))
+        return 0;
+
+    dst = addr_app_to_native(dst_offset);
+    src = addr_app_to_native(src_offset);
+    strcpy(dst, src);
+    return dst_offset;
+}
+
+static int32
+_strncpy_wrapper(int32 dst_offset, int32 src_offset, uint32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char *dst, *src;
+
+    if (!validate_app_addr(dst_offset, size)
+        || !validate_app_addr(src_offset, size))
+        return 0;
+
+    dst = addr_app_to_native(dst_offset);
+    src = addr_app_to_native(src_offset);
+    strncpy(dst, src, size);
+    return dst_offset;
+}
+
+static uint32
+_strlen_wrapper(int32 s_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char *s;
+
+    if (!validate_app_addr(s_offset, 1))
+        return 0;
+
+    s = addr_app_to_native(s_offset);
+    return strlen(s);
+}
+
+#endif /* OPS_UNSAFE_BUFFERS */
+
+static int32
+_malloc_wrapper(uint32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    return module_malloc(size);
+}
+
+static int32
+_calloc_wrapper(uint32 nmemb, uint32 size)
+{
+    uint64 total_size = (uint64) nmemb * (uint64) size;
+    wasm_module_inst_t module_inst = get_module_inst();
+    uint32 ret_offset = 0;
+    uint8 *ret_ptr;
+
+    if (total_size > UINT32_MAX)
+        total_size = UINT32_MAX;
+
+    ret_offset = module_malloc((uint32 )total_size);
+    if (ret_offset) {
+        ret_ptr = addr_app_to_native(ret_offset);
+        memset(ret_ptr, 0, (uint32) total_size);
+    }
+
+    return ret_offset;
+}
+
+static void
+_free_wrapper(int32 ptr_offset)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+
+    if (!validate_app_addr(ptr_offset, 4))
+        return;
+    return module_free(ptr_offset);
+}
+
+static void
+setTempRet0_wrapper(uint32 temp_ret)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    wasm_runtime_set_temp_ret(module_inst, temp_ret);
+}
+
+static uint32
+getTempRet0_wrapper()
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    return wasm_runtime_get_temp_ret(module_inst);
+}
+
+static uint32
+_llvm_bswap_i16_wrapper(uint32 data)
+{
+    return (data & 0xFFFF0000)
+           | ((data & 0xFF) << 8)
+           | ((data & 0xFF00) >> 8);
+}
+
+static uint32
+_llvm_bswap_i32_wrapper(uint32 data)
+{
+    return ((data & 0xFF) << 24)
+           | ((data & 0xFF00) << 8)
+           | ((data & 0xFF0000) >> 8)
+           | ((data & 0xFF000000) >> 24);
+}
+
+static uint32
+_bitshift64Lshr_wrapper(uint32 uint64_part0, uint32 uint64_part1,
+                        uint32 bits)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    union {
+        uint64 value;
+        uint32 parts[2];
+    } u;
+
+    u.parts[0] = uint64_part0;
+    u.parts[1] = uint64_part1;
+
+    u.value >>= bits;
+    /* return low 32bit and save high 32bit to temp ret */
+    wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
+    return (uint32) u.value;
+}
+
+static uint32
+_bitshift64Shl_wrapper(uint32 int64_part0, uint32 int64_part1,
+                       uint32 bits)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    union {
+        int64 value;
+        uint32 parts[2];
+    } u;
+
+    u.parts[0] = int64_part0;
+    u.parts[1] = int64_part1;
+
+    u.value <<= bits;
+    /* return low 32bit and save high 32bit to temp ret */
+    wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
+    return (uint32) u.value;
+}
+
+static void
+_llvm_stackrestore_wrapper(uint32 llvm_stack)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    printf("_llvm_stackrestore called!\n");
+    wasm_runtime_set_llvm_stack(module_inst, llvm_stack);
+}
+
+static uint32
+_llvm_stacksave_wrapper()
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    printf("_llvm_stacksave called!\n");
+    return wasm_runtime_get_llvm_stack(module_inst);
+}
+
+static int32
+_emscripten_memcpy_big_wrapper(int32 dst_offset, int32 src_offset,
+                               uint32 size)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    void *dst, *src;
+
+    if (!validate_app_addr(dst_offset, size)
+        || !validate_app_addr(src_offset, size))
+        return dst_offset;
+
+    dst = addr_app_to_native(dst_offset);
+    src = addr_app_to_native(src_offset);
+
+    memcpy(dst, src, size);
+    return dst_offset;
+}
+
+static void
+abort_wrapper(int32 code)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char buf[32];
+    snprintf(buf, sizeof(buf), "env.abort(%i)", code);
+    wasm_runtime_set_exception(module_inst, buf);
+}
+
+static void
+abortStackOverflow_wrapper(int32 code)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char buf[32];
+    snprintf(buf, sizeof(buf), "env.abortStackOverflow(%i)", code);
+    wasm_runtime_set_exception(module_inst, buf);
+}
+
+static void
+nullFunc_X_wrapper(int32 code)
+{
+    wasm_module_inst_t module_inst = get_module_inst();
+    char buf[32];
+    snprintf(buf, sizeof(buf), "env.nullFunc_X(%i)", code);
+    wasm_runtime_set_exception(module_inst, buf);
+}
+
+/*#define ENABLE_SPEC_TEST 1*/
+
+#ifdef ENABLE_SPEC_TEST
+static void
+print_i32_wrapper(int i32)
+{
+    printf("%d\n", i32);
+}
+
+static void
+print_wrapper(int i32)
+{
+    printf("%d\n", i32);
+}
+#endif
+
+/* 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[] = {
+
+#ifdef ENABLE_SPEC_TEST
+    REG_NATIVE_FUNC(spectest, print_i32),
+    REG_NATIVE_FUNC(spectest, print),
+#endif
+
+#if OPS_INPUT_OUTPUT
+    REG_NATIVE_FUNC(env, _printf),
+    REG_NATIVE_FUNC(env, _sprintf),
+    REG_NATIVE_FUNC(env, _snprintf),
+    REG_NATIVE_FUNC(env, _puts),
+    REG_NATIVE_FUNC(env, _putchar),
+#endif
+    REG_NATIVE_FUNC(env, _memcmp),
+    REG_NATIVE_FUNC(env, _memcpy),
+    REG_NATIVE_FUNC(env, _memmove),
+    REG_NATIVE_FUNC(env, _memset),
+#if OPS_UNSAFE_BUFFERS
+    REG_NATIVE_FUNC(env, _strchr),
+    REG_NATIVE_FUNC(env, _strcmp),
+    REG_NATIVE_FUNC(env, _strcpy),
+    REG_NATIVE_FUNC(env, _strlen),
+    REG_NATIVE_FUNC(env, _strncmp),
+    REG_NATIVE_FUNC(env, _strncpy),
+    REG_NATIVE_FUNC(env, _strdup),
+#endif
+    REG_NATIVE_FUNC(env, _malloc),
+    REG_NATIVE_FUNC(env, _calloc),
+    REG_NATIVE_FUNC(env, _free),
+    REG_NATIVE_FUNC(env, setTempRet0),
+    REG_NATIVE_FUNC(env, getTempRet0),
+    REG_NATIVE_FUNC(env, _llvm_bswap_i16),
+    REG_NATIVE_FUNC(env, _llvm_bswap_i32),
+    REG_NATIVE_FUNC(env, _bitshift64Lshr),
+    REG_NATIVE_FUNC(env, _bitshift64Shl),
+    REG_NATIVE_FUNC(env, _llvm_stackrestore),
+    REG_NATIVE_FUNC(env, _llvm_stacksave),
+    REG_NATIVE_FUNC(env, _emscripten_memcpy_big),
+    REG_NATIVE_FUNC(env, abort),
+    REG_NATIVE_FUNC(env, abortStackOverflow),
+    REG_NATIVE_FUNC(env, nullFunc_X)
+};
+
+void*
+wasm_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;
+    void *ret;
+
+    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)
+                || (func_def->func_name[0] == '_'
+                    && !strcmp(func_def->func_name + 1, func_name))))
+            return (void*) (uintptr_t) func_def->func_ptr;
+        func_def++;
+    }
+
+    if ((ret = wasm_platform_native_func_lookup(module_name, func_name)))
+        return ret;
+
+    return NULL;
+}
+
+/*************************************
+ * Global Variables                  *
+ *************************************/
+
+typedef struct WASMNativeGlobalDef {
+    const char *module_name;
+    const char *global_name;
+    WASMValue global_data;
+} WASMNativeGlobalDef;
+
+static WASMNativeGlobalDef native_global_defs[] = {
+#ifdef ENABLE_SPEC_TEST
+    { "spectest", "global_i32", .global_data.u32 = 0 },
+#endif
+    { "env", "STACKTOP", .global_data.u32 = 0 },
+    { "env", "STACK_MAX", .global_data.u32 = 0 },
+    { "env", "ABORT", .global_data.u32 = 0 },
+    { "env", "memoryBase", .global_data.u32 = 0 },
+    { "env", "__memory_base", .global_data.u32 = 0 },
+    { "env", "tableBase", .global_data.u32 = 0 },
+    { "env", "__table_base", .global_data.u32 = 0 },
+    { "env", "DYNAMICTOP_PTR", .global_data.addr = 0 },
+    { "env", "tempDoublePtr", .global_data.addr = 0 },
+    { "global", "NaN", .global_data.u64 = 0x7FF8000000000000LL },
+    { "global", "Infinity", .global_data.u64 = 0x7FF0000000000000LL }
+};
+
+bool
+wasm_native_global_lookup(const char *module_name, const char *global_name,
+                          WASMGlobalImport *global)
+{
+    uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef);
+    WASMNativeGlobalDef *global_def = native_global_defs;
+    WASMNativeGlobalDef *global_def_end = global_def + size;
+
+    if (!module_name || !global_name || !global)
+        return false;
+
+    /* Lookup constant globals which can be defined by table */
+    while (global_def < global_def_end) {
+        if (!strcmp(global_def->module_name, module_name)
+            && !strcmp(global_def->global_name, global_name)) {
+            global->global_data_linked = global_def->global_data;
+            return true;
+        }
+        global_def++;
+    }
+
+    /* Lookup non-constant globals which cannot be defined by table */
+    if (!strcmp(module_name, "env")) {
+#if 0 /* unsupported in sgx */
+        if (!strcmp(global_name, "_stdin")) {
+            global->global_data_linked.addr = (uintptr_t)stdin;
+            global->is_addr = true;
+            return true;
+        } else if (!strcmp(global_name, "_stdout")) {
+            global->global_data_linked.addr = (uintptr_t)stdout;
+            global->is_addr = true;
+            return true;
+        } else if (!strcmp(global_name, "_stderr")) {
+            global->global_data_linked.addr = (uintptr_t)stderr;
+            global->is_addr = true;
+            return true;
+        }
+#endif  /* OPS_INPUT_OUTPUT */
+    }
+
+    return false;
+}
+
+bool
+wasm_native_init()
+{
+    /* TODO: qsort the function defs and global defs. */
+    return true;
+}

+ 1 - 1
core/iwasm/lib/native/libc/wasm_libc.cmake

@@ -17,7 +17,7 @@ set (WASM_LIBC_DIR ${CMAKE_CURRENT_LIST_DIR})
 include_directories(${WASM_LIBC_DIR})
 
 
-file (GLOB_RECURSE source_all ${WASM_LIBC_DIR}/*.c)
+file (GLOB_RECURSE source_all ${WASM_LIBC_DIR}/libc_wrapper.c)
 
 set (WASM_LIBC_SOURCE ${source_all})
 

+ 23 - 0
core/iwasm/lib/native/libc/wasm_libc_sgx.cmake

@@ -0,0 +1,23 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set (WASM_LIBC_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+include_directories(${WASM_LIBC_DIR})
+
+
+file (GLOB_RECURSE source_all ${WASM_LIBC_DIR}/libc_wrapper_sgx.c)
+
+set (WASM_LIBC_SOURCE ${source_all})
+

+ 89 - 0
core/iwasm/products/linux-sgx/CMakeLists.txt

@@ -0,0 +1,89 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required (VERSION 2.8)
+
+project (iwasm)
+
+set (PLATFORM "linux-sgx")
+
+# Reset default linker flags
+set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+add_definitions(-DUSE_SGX=1)
+add_definitions(-DOPS_INPUT_OUTPUT=1)
+add_definitions(-DOPS_UNSAFE_BUFFERS=0)
+add_definitions(-DWASM_ENABLE_LOG=0)
+
+# Enable repl mode if want to test spec cases
+# add_definitions(-DWASM_ENABLE_REPL)
+
+if (NOT ("$ENV{VALGRIND}" STREQUAL "YES"))
+  add_definitions(-DNVALGRIND)
+endif ()
+
+# Currently build as 64-bit by default.
+set (BUILD_AS_64BIT_SUPPORT "YES")
+
+if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES")
+  # Add -fPIC flag if build as 64-bit
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+  set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
+else ()
+  add_definitions (-m32)
+  set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
+  set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
+endif ()
+endif ()
+
+if (NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Release)
+endif (NOT CMAKE_BUILD_TYPE)
+message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
+
+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic")
+
+set (SHARED_LIB_DIR ../../../shared-lib)
+
+include_directories (.
+                     ../../runtime/include
+                     ../../runtime/platform/include
+                     ${SHARED_LIB_DIR}/include
+                     $ENV{SGX_SDK}/include)
+
+enable_language (ASM)
+
+include (../../runtime/platform/${PLATFORM}/platform.cmake)
+include (../../runtime/utils/utils.cmake)
+include (../../runtime/vmcore-wasm/vmcore.cmake)
+include (../../lib/native/base/wasm_lib_base.cmake)
+include (../../lib/native/libc/wasm_libc_sgx.cmake)
+include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
+include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake)
+
+#add_executable (iwasm main.c ext_lib_export.c)
+
+
+add_library (vmlib
+             ext_lib_export.c
+             ${WASM_PLATFORM_LIB_SOURCE}
+             ${WASM_UTILS_LIB_SOURCE}
+             ${VMCORE_LIB_SOURCE}
+             ${WASM_LIB_BASE_DIR}/base_lib_export.c
+             ${WASM_LIBC_SOURCE}
+             ${PLATFORM_SHARED_SOURCE}
+             ${MEM_ALLOC_SHARED_SOURCE})

+ 21 - 0
core/iwasm/products/linux-sgx/ext_lib_export.c

@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lib_export.h"
+
+static NativeSymbol extended_native_symbol_defs[] = { };
+
+#include "ext_lib_export.h"

+ 3 - 1
core/iwasm/runtime/platform/include/wasm_platform_log.h

@@ -17,7 +17,9 @@
 #ifndef _WASM_PLATFORM_LOG
 #define _WASM_PLATFORM_LOG
 
-#define wasm_printf printf
+#include "bh_platform.h"
+
+#define wasm_printf bh_printf
 
 #define wasm_vprintf vprintf
 

+ 25 - 0
core/iwasm/runtime/platform/linux-sgx/platform.cmake

@@ -0,0 +1,25 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L)
+
+set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+include_directories(${PLATFORM_LIB_DIR})
+include_directories(${PLATFORM_LIB_DIR}/../include)
+
+file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c)
+
+set (WASM_PLATFORM_LIB_SOURCE ${source_all})
+

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

@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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 <sys/ioctl.h>
+#include <sys/uio.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+
+#define get_module_inst() \
+    wasm_runtime_get_current_module_inst()
+
+#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(int32 arg0)
+{
+    switch (arg0) {
+        case 199: /* getuid */
+            /* TODO */
+        default:
+            bh_printf("##_syscall0 called, syscall id: %d\n", arg0);
+    }
+    return 0;
+}
+
+static int32
+__syscall1_wrapper(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(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(int32 arg0, int32 arg1, int32 arg2, int32 arg3)
+{
+    WASMModuleInstance *module_inst = get_module_inst();
+
+    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 = 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);
+
+                    memcpy(str, 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(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(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()                                     \
+  WASMModuleInstance *module_inst = get_module_inst();              \
+  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(int32 _id) {                \
+    return __syscall0_wrapper(id);                                  \
+  }
+
+#define EMCC_SYSCALL_WRAPPER1(id)                                   \
+  static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
+    GET_EMCC_SYSCALL_ARGS();                                        \
+    return __syscall1_wrapper(id, args[0]);                         \
+  }
+
+#define EMCC_SYSCALL_WRAPPER2(id)                                   \
+  static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
+    GET_EMCC_SYSCALL_ARGS();                                        \
+    return __syscall2_wrapper(id, args[0], args[1]);                \
+  }
+
+#define EMCC_SYSCALL_WRAPPER3(id)                                   \
+  static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
+    GET_EMCC_SYSCALL_ARGS();                                        \
+    return __syscall3_wrapper(id, args[0], args[1], args[2]);       \
+  }
+
+#define EMCC_SYSCALL_WRAPPER4(id)                                   \
+  static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
+    GET_EMCC_SYSCALL_ARGS();                                        \
+    return __syscall4_wrapper(id, args[0], args[1], args[2], args[3]);\
+  }
+
+#define EMCC_SYSCALL_WRAPPER5(id)                                   \
+  static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
+    GET_EMCC_SYSCALL_ARGS();                                        \
+    return __syscall5_wrapper(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 int32
+getTotalMemory_wrapper()
+{
+    WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
+    WASMMemoryInstance *memory = module_inst->default_memory;
+    return NumBytesPerPage * memory->cur_page_count;
+}
+
+static int32
+enlargeMemory_wrapper()
+{
+    bool ret;
+    WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
+    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(int32 code)
+{
+    WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
+    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_get_current_module_inst();
+    wasm_runtime_set_exception(module_inst, "abort on cannot grow memory");
+}
+
+static void
+___setErrNo_wrapper(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;
+}

+ 3 - 0
core/shared-lib/include/bh_common.h

@@ -23,6 +23,9 @@
 #include "bh_log.h"
 #include "bh_list.h"
 
+typedef void (*bh_print_function_t)(const char* message);
+void bh_set_print_function(bh_print_function_t pf);
+
 #define bh_memcpy_s(dest, dlen, src, slen) do {                         \
     int _ret = slen == 0 ? 0 : b_memcpy_s (dest, dlen, src, slen);      \
     (void)_ret;                                                         \

+ 4 - 0
core/shared-lib/include/config.h

@@ -26,7 +26,9 @@
 #define DEFAULT_MEM_ALLOCATOR MEM_ALLOCATOR_EMS
 
 /* Beihai log system */
+#ifndef BEIHAI_ENABLE_LOG
 #define BEIHAI_ENABLE_LOG 1
+#endif
 
 /* Beihai debugger support */
 #define BEIHAI_ENABLE_TOOL_AGENT 1
@@ -43,7 +45,9 @@
 #endif
 
 /* WASM VM log system */
+#ifndef WASM_ENABLE_LOG
 #define WASM_ENABLE_LOG 1
+#endif
 
 /* WASM Interpreter labels-as-values feature */
 #define WASM_ENABLE_LABELS_AS_VALUES 1

+ 7 - 8
core/shared-lib/mem-alloc/bh_memory.c

@@ -15,9 +15,9 @@
  */
 
 #include "bh_config.h"
+#include "bh_platform.h"
 #include "bh_memory.h"
 #include "mem_alloc.h"
-#include <stdio.h>
 #include <stdlib.h>
 
 #if BEIHAI_ENABLE_MEMORY_PROFILING != 0
@@ -76,7 +76,7 @@ int bh_memory_init_with_pool(void *mem, unsigned int bytes)
         global_pool_size = bytes;
         return 0;
     }
-    printf("Init memory with pool (%p, %u) failed.\n", mem, bytes);
+    bh_printf("Init memory with pool (%p, %u) failed.\n", mem, bytes);
     return -1;
 }
 
@@ -91,7 +91,7 @@ int bh_memory_init_with_allocator(void *_malloc_func, void *_free_func)
 #endif
         return 0;
     }
-    printf("Init memory with allocator (%p, %p) failed.\n", _malloc_func,
+    bh_printf("Init memory with allocator (%p, %p) failed.\n", _malloc_func,
             _free_func);
     return -1;
 }
@@ -117,7 +117,7 @@ int bh_memory_pool_size()
 void* bh_malloc_internal(unsigned int size)
 {
     if (memory_mode == MEMORY_MODE_UNKNOWN) {
-        printf("bh_malloc failed: memory hasn't been initialize.\n");
+        bh_printf("bh_malloc failed: memory hasn't been initialize.\n");
         return NULL;
     } else if (memory_mode == MEMORY_MODE_POOL) {
         return mem_allocator_malloc(pool_allocator, size);
@@ -129,7 +129,7 @@ void* bh_malloc_internal(unsigned int size)
 void bh_free_internal(void *ptr)
 {
     if (memory_mode == MEMORY_MODE_UNKNOWN) {
-        printf("bh_free failed: memory hasn't been initialize.\n");
+        bh_printf("bh_free failed: memory hasn't been initialize.\n");
     } else if (memory_mode == MEMORY_MODE_POOL) {
         mem_allocator_free(pool_allocator, ptr);
     } else {
@@ -250,7 +250,7 @@ void memory_usage_summarize()
 
     profile = memory_profiles_list;
     while (profile) {
-        printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n",
+        bh_printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n",
             profile->total_malloc,
             profile->malloc_num,
             profile->total_free,
@@ -267,7 +267,7 @@ void memory_profile_print(const char *file,
                           const char *func,
                           int alloc)
 {
-    printf("location:%s@%d:used:%d:contribution:%d\n",
+    bh_printf("location:%s@%d:used:%d:contribution:%d\n",
            func, line, memory_in_use, alloc);
 }
 
@@ -328,4 +328,3 @@ void bh_free_profile(const char *file, int line, const char *func, void *ptr)
 }
 #endif /* end of BEIHAI_ENABLE_MEMORY_PROFILING */
 #endif /* end of MALLOC_MEMORY_FROM_SYSTEM*/
-

+ 7 - 7
core/shared-lib/mem-alloc/ems/ems_alloc.c

@@ -118,7 +118,7 @@ static void unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
         }
 
         if (!node) {
-            printf("[GC_ERROR]couldn't find the node in the normal list");
+            bh_printf("[GC_ERROR]couldn't find the node in the normal list");
         }
     } else {
         remove_tree_node((hmu_tree_node_t *) hmu);
@@ -392,7 +392,7 @@ gc_object_t _gc_alloc_vo_i_heap(void *vheap,
     ret = hmu_to_obj(hmu);
 
 #if BH_ENABLE_MEMORY_PROFILING != 0
-    printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
+    bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
 #endif
 
     FINISH:
@@ -434,7 +434,7 @@ gc_object_t _gc_alloc_jo_i_heap(void *vheap,
     ret = hmu_to_obj(hmu);
 
 #if BH_ENABLE_MEMORY_PROFILING != 0
-    printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
+    bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
 #endif
 
     FINISH:
@@ -495,7 +495,7 @@ int gc_free_i_heap(void *vheap, gc_object_t obj ALLOC_EXTRA_PARAMETERS)
             heap->total_free_size += size;
 #endif
 #if BH_ENABLE_MEMORY_PROFILING != 0
-            printf("HEAP.FREE, heap: %p, size: %u\n",heap, size);
+            bh_printf("HEAP.FREE, heap: %p, size: %u\n",heap, size);
 #endif
 
             if (!hmu_get_pinuse(hmu)) {
@@ -538,12 +538,12 @@ int gc_free_i_heap(void *vheap, gc_object_t obj ALLOC_EXTRA_PARAMETERS)
 
 void gc_dump_heap_stats(gc_heap_t *heap)
 {
-    printf("heap: %p, heap start: %p\n", heap, heap->base_addr);
-    printf(
+    bh_printf("heap: %p, heap start: %p\n", heap, heap->base_addr);
+    bh_printf(
             "total malloc: totalfree: %u, current: %u, highmark: %u, gc cnt: %u\n",
             heap->total_free_size, heap->current_size, heap->highmark_size,
             heap->total_gc_count);
-    printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n",
+    bh_printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n",
             g_total_malloc, g_total_free, g_total_malloc - g_total_free);
 }
 

+ 1 - 1
core/shared-lib/mem-alloc/ems/ems_gc_internal.h

@@ -21,6 +21,7 @@
 extern "C" {
 #endif
 
+#include "bh_platform.h"
 #include "bh_thread.h"
 #include "bh_memory.h"
 #include "bh_assert.h"
@@ -279,4 +280,3 @@ extern int (*gct_vm_gc_finished)(void);
 #endif
 
 #endif
-

+ 6 - 6
core/shared-lib/mem-alloc/ems/ems_kfc.c

@@ -30,7 +30,7 @@ int gci_check_platform()
 {
 #define CHECK(x, y)  do {                                       \
   if((x) != (y)) {                                              \
-    printf("Platform checking failed on LINE %d at FILE %s.",   \
+    bh_printf("Platform checking failed on LINE %d at FILE %s.",   \
            __LINE__, __FILE__);                                 \
     return GC_ERROR;                                            \
   }                                                             \
@@ -62,12 +62,12 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
 
     /* check system compatibility*/
     if (gci_check_platform() == GC_ERROR) {
-        printf("Check platform compatibility failed");
+        bh_printf("Check platform compatibility failed");
         return NULL;
     }
 
     if (buf_size < 1024) {
-        printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size);
+        bh_printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size);
         return NULL;
     }
 
@@ -79,12 +79,12 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
 
     ret = gct_vm_mutex_init(&heap->lock);
     if (ret != BHT_OK) {
-        printf("[GC_ERROR]failed to init lock ");
+        bh_printf("[GC_ERROR]failed to init lock ");
         return NULL;
     }
 
 #ifdef BH_FOOTPRINT
-    printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size);
+    bh_printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size);
 #endif
 
     /* init all data structures*/
@@ -131,7 +131,7 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
                     && HMU_FC_NORMAL_MAX_SIZE < q->size); /*@NOTIFY*/
 
 #if BH_ENABLE_MEMORY_PROFILING != 0
-    printf("heap is successfully initialized with max_size=%u.",
+    bh_printf("heap is successfully initialized with max_size=%u.",
             heap_max_size);
 #endif
     return heap;

+ 2 - 0
core/shared-lib/platform/alios/bh_platform.h

@@ -52,6 +52,8 @@ typedef int64_t int64;
 #define wa_free bh_free
 #define wa_strdup bh_strdup
 
+#define bh_printf printf
+
 typedef aos_task_t korp_thread;
 typedef korp_thread *korp_tid;
 typedef aos_task_t *aos_tid_t;

+ 69 - 0
core/shared-lib/platform/linux-sgx/bh_assert.c

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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
+}
+

+ 81 - 0
core/shared-lib/platform/linux-sgx/bh_definition.c

@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_definition.h"
+#include "bh_platform.h"
+
+int bh_return(int ret)
+{
+    return ret;
+}
+
+#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;
+    }
+
+    strncpy(s1, s2, s1max);
+
+    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;
+}

+ 67 - 0
core/shared-lib/platform/linux-sgx/bh_platform.c

@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_common.h"
+#include "bh_platform.h"
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define FIXED_BUFFER_SIZE (1<<14)
+static bh_print_function_t print_function = NULL;
+
+char *bh_strdup(const char *s)
+{
+    char *s1 = NULL;
+    if (s && (s1 = bh_malloc(strlen(s) + 1)))
+        memcpy(s1, s, strlen(s) + 1);
+    return s1;
+}
+
+int bh_platform_init()
+{
+    return 0;
+}
+
+int putchar(int c)
+{
+    return 0;
+}
+
+int puts(const char *s)
+{
+    return 0;
+}
+
+void bh_set_print_function(bh_print_function_t pf)
+{
+    print_function = pf;
+}
+
+int bh_printf(const char *message, ...)
+{
+    if (print_function != NULL) {
+        char msg[FIXED_BUFFER_SIZE] = { '\0' };
+        va_list ap;
+        va_start(ap, message);
+        vsnprintf(msg, FIXED_BUFFER_SIZE, message, ap);
+        va_end(ap);
+        print_function(msg);
+    }
+
+    return 0;
+}

+ 115 - 0
core/shared-lib/platform/linux-sgx/bh_platform.h

@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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 <limits.h>
+#include <errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int bh_printf(const char *message, ...);
+
+typedef uint64_t uint64;
+typedef int64_t int64;
+
+#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)
+
+#define BH_PLATFORM "Linux-SGX"
+
+/* 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 int korp_tid;
+typedef int korp_mutex;
+typedef int korp_sem;
+typedef int korp_cond;
+typedef int korp_thread;
+typedef void* (*thread_start_routine_t)(void*);
+
+#define wa_malloc bh_malloc
+#define wa_free bh_free
+#define wa_strdup bh_strdup
+
+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);
+
+char *bh_strdup(const char *s);
+
+int bh_platform_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 41 - 0
core/shared-lib/platform/linux-sgx/bh_platform_log.c

@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_platform.h"
+#include <stdio.h>
+
+void bh_log_emit(const char *fmt, va_list ap)
+{
+    vprintf(fmt, ap);
+    fflush(stdout);
+}
+
+int bh_fprintf(FILE *stream, const char *fmt, ...)
+{
+    va_list ap;
+    int ret;
+
+    va_start(ap, fmt);
+    ret = vfprintf(stream ? stream : stdout, fmt, ap);
+    va_end(ap);
+
+    return ret;
+}
+
+int bh_fflush(void *stream)
+{
+    return fflush(stream ? stream : stdout);
+}

+ 190 - 0
core/shared-lib/platform/linux-sgx/bh_thread.c

@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_thread.h"
+#include "bh_assert.h"
+#include "bh_memory.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+int _vm_thread_sys_init()
+{
+    return 0;
+}
+
+void vm_thread_sys_destroy(void)
+{
+}
+
+int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
+        void *arg, unsigned int stack_size, int prio)
+{
+    return BHT_ERROR;
+    // 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 0;
+}
+
+void vm_thread_exit(void * code)
+{
+}
+
+// storage for one thread
+static void *_tls_store = NULL;
+
+void *_vm_tls_get(unsigned idx)
+{
+    return _tls_store;
+}
+
+int _vm_tls_put(unsigned idx, void * tls)
+{
+    _tls_store = tls;
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_mutex_init(korp_mutex *mutex)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_recursive_mutex_init(korp_mutex *mutex)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_mutex_destroy(korp_mutex *mutex)
+{
+    return BHT_OK;
+    //return 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 vm_mutex_trylock(korp_mutex *mutex)
+{
+    return BHT_OK;
+    //return 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 _vm_sem_init(korp_sem* sem, unsigned int c)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_sem_destroy(korp_sem *sem)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_sem_wait(korp_sem *sem)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_sem_reltimedwait(korp_sem *sem, int mills)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_sem_post(korp_sem *sem)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_cond_init(korp_cond *cond)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_cond_destroy(korp_cond *cond)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_cond_signal(korp_cond *cond)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_cond_broadcast(korp_cond *cond)
+{
+    return BHT_OK;
+    //return BHT_ERROR;
+}
+
+int _vm_thread_cancel(korp_tid thread)
+{
+    return 0;
+}
+
+int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
+{
+    return 0;
+}
+
+int _vm_thread_detach(korp_tid thread)
+{
+    return 0;
+}

+ 80 - 0
core/shared-lib/platform/linux-sgx/bh_time.c

@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_time.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/timeb.h>
+#include <time.h>
+
+/*
+ * This function returns milliseconds per tick.
+ * @return milliseconds per tick.
+ */
+uint64 _bh_time_get_tick_millisecond()
+{
+    return 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 + ts.tv_nsec / (1000 * 1000);
+}
+
+uint32 bh_get_tick_sec()
+{
+    return _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 timeb tp;
+    ftime(&tp);
+
+    return ((uint64) tp.time) * 1000 + tp.millitm
+            - (tp.dstflag == 0 ? 0 : 60 * 60 * 1000) + tp.timezone * 60 * 1000;
+}
+
+size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
+{
+    time_t time_sec = time / 1000;
+    struct timeb tp;
+    struct tm *ltp;
+
+    ftime(&tp);
+    time_sec -= tp.timezone * 60;
+
+    ltp = localtime(&time_sec);
+    if (ltp == NULL) {
+        return 0;
+    }
+    return strftime(s, max, format, ltp);
+}
+

+ 24 - 0
core/shared-lib/platform/linux-sgx/shared_platform.cmake

@@ -0,0 +1,24 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+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})
+

+ 2 - 0
core/shared-lib/platform/linux/bh_platform.h

@@ -77,6 +77,8 @@ typedef void* (*thread_start_routine_t)(void*);
 #define wa_free bh_free
 #define wa_strdup bh_strdup
 
+#define bh_printf printf
+
 int snprintf(char *buffer, size_t count, const char *format, ...);
 double fmod(double x, double y);
 float fmodf(float x, float y);

+ 2 - 0
core/shared-lib/platform/vxworks/bh_platform.h

@@ -75,6 +75,8 @@ typedef void* (*thread_start_routine_t)(void*);
 #define wa_free bh_free
 #define wa_strdup bh_strdup
 
+#define bh_printf printf
+
 int snprintf(char *buffer, size_t count, const char *format, ...);
 double fmod(double x, double y);
 float fmodf(float x, float y);

+ 2 - 0
core/shared-lib/platform/zephyr/bh_platform.h

@@ -78,6 +78,8 @@ typedef void* (*thread_start_routine_t)(void*);
 #define wa_malloc bh_malloc
 #define wa_free bh_free
 
+#define bh_printf printf
+
 /* Unit test framework is based on C++, where the declaration of
  snprintf is different.  */
 #ifndef __cplusplus