diff --git a/core/iwasm/lib/native/libc/libc_wrapper_sgx.c b/core/iwasm/lib/native/libc/libc_wrapper_sgx.c new file mode 100644 index 0000000000..0b2a21bbf0 --- /dev/null +++ b/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; +} diff --git a/core/iwasm/lib/native/libc/wasm_libc.cmake b/core/iwasm/lib/native/libc/wasm_libc.cmake index 52e55123f6..f70b3b81a7 100644 --- a/core/iwasm/lib/native/libc/wasm_libc.cmake +++ b/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}) diff --git a/core/iwasm/lib/native/libc/wasm_libc_sgx.cmake b/core/iwasm/lib/native/libc/wasm_libc_sgx.cmake new file mode 100644 index 0000000000..c2f8770974 --- /dev/null +++ b/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}) + diff --git a/core/iwasm/products/linux-sgx/CMakeLists.txt b/core/iwasm/products/linux-sgx/CMakeLists.txt new file mode 100644 index 0000000000..4a53f95750 --- /dev/null +++ b/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}) diff --git a/core/iwasm/products/linux-sgx/ext_lib_export.c b/core/iwasm/products/linux-sgx/ext_lib_export.c new file mode 100644 index 0000000000..8d78f3ae14 --- /dev/null +++ b/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" diff --git a/core/iwasm/runtime/platform/include/wasm_platform_log.h b/core/iwasm/runtime/platform/include/wasm_platform_log.h index 3fe55bf59c..e74de3ff24 100644 --- a/core/iwasm/runtime/platform/include/wasm_platform_log.h +++ b/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 diff --git a/core/iwasm/runtime/platform/linux-sgx/platform.cmake b/core/iwasm/runtime/platform/linux-sgx/platform.cmake new file mode 100644 index 0000000000..c01fd0e576 --- /dev/null +++ b/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}) + diff --git a/core/iwasm/runtime/platform/linux-sgx/wasm_native.c b/core/iwasm/runtime/platform/linux-sgx/wasm_native.c new file mode 100644 index 0000000000..59b081b7b2 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include +#include + + +#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; +} diff --git a/core/shared-lib/include/bh_common.h b/core/shared-lib/include/bh_common.h index 9a3366ce16..a8176dc7f9 100755 --- a/core/shared-lib/include/bh_common.h +++ b/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; \ diff --git a/core/shared-lib/include/config.h b/core/shared-lib/include/config.h index 0cf7bd4fbf..4ece2251df 100644 --- a/core/shared-lib/include/config.h +++ b/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 diff --git a/core/shared-lib/mem-alloc/bh_memory.c b/core/shared-lib/mem-alloc/bh_memory.c index bca6970518..f0a6641e5e 100644 --- a/core/shared-lib/mem-alloc/bh_memory.c +++ b/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 #include #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*/ - diff --git a/core/shared-lib/mem-alloc/ems/ems_alloc.c b/core/shared-lib/mem-alloc/ems/ems_alloc.c index d8682b6c7b..2c27b71cf6 100644 --- a/core/shared-lib/mem-alloc/ems/ems_alloc.c +++ b/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); } diff --git a/core/shared-lib/mem-alloc/ems/ems_gc_internal.h b/core/shared-lib/mem-alloc/ems/ems_gc_internal.h index b717971aee..51308d2a9b 100644 --- a/core/shared-lib/mem-alloc/ems/ems_gc_internal.h +++ b/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 - diff --git a/core/shared-lib/mem-alloc/ems/ems_kfc.c b/core/shared-lib/mem-alloc/ems/ems_kfc.c index 791a298a50..0090c317bf 100644 --- a/core/shared-lib/mem-alloc/ems/ems_kfc.c +++ b/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; diff --git a/core/shared-lib/platform/alios/bh_platform.h b/core/shared-lib/platform/alios/bh_platform.h index e23958c95d..468d0b4e96 100644 --- a/core/shared-lib/platform/alios/bh_platform.h +++ b/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; diff --git a/core/shared-lib/platform/linux-sgx/bh_assert.c b/core/shared-lib/platform/linux-sgx/bh_assert.c new file mode 100644 index 0000000000..b52a9aa5ba --- /dev/null +++ b/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 +#include +#include + +#ifdef BH_TEST +#include +#endif + +#ifdef BH_TEST +/* for exception throwing */ +jmp_buf bh_test_jb; +#endif + +void bh_assert_internal(int v, const char *file_name, int line_number, + const char *expr_string) +{ + if (v) + return; + + if (!file_name) + file_name = "NULL FILENAME"; + if (!expr_string) + expr_string = "NULL EXPR_STRING"; + + printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string, + file_name, line_number); + +#ifdef BH_TEST + longjmp(bh_test_jb, 1); +#endif + + abort(); +} + +void bh_debug_internal(const char *file_name, int line_number, const char *fmt, + ...) +{ +#ifndef JEFF_TEST_VERIFIER + va_list args; + + va_start(args, fmt); + bh_assert(file_name); + + printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number); + vprintf(fmt, args); + + va_end(args); + printf("\n"); +#endif +} + diff --git a/core/shared-lib/platform/linux-sgx/bh_definition.c b/core/shared-lib/platform/linux-sgx/bh_definition.c new file mode 100644 index 0000000000..5105d0ff83 --- /dev/null +++ b/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; +} diff --git a/core/shared-lib/platform/linux-sgx/bh_platform.c b/core/shared-lib/platform/linux-sgx/bh_platform.c new file mode 100644 index 0000000000..2166d53abf --- /dev/null +++ b/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 +#include +#include + +#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; +} diff --git a/core/shared-lib/platform/linux-sgx/bh_platform.h b/core/shared-lib/platform/linux-sgx/bh_platform.h new file mode 100644 index 0000000000..59cbb6d598 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/core/shared-lib/platform/linux-sgx/bh_platform_log.c b/core/shared-lib/platform/linux-sgx/bh_platform_log.c new file mode 100644 index 0000000000..4ff03192a7 --- /dev/null +++ b/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 + +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); +} diff --git a/core/shared-lib/platform/linux-sgx/bh_thread.c b/core/shared-lib/platform/linux-sgx/bh_thread.c new file mode 100644 index 0000000000..8730e13cd6 --- /dev/null +++ b/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 +#include +#include + +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; +} diff --git a/core/shared-lib/platform/linux-sgx/bh_time.c b/core/shared-lib/platform/linux-sgx/bh_time.c new file mode 100644 index 0000000000..0627b08d0c --- /dev/null +++ b/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 +#include +#include +#include + +/* + * 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); +} + diff --git a/core/shared-lib/platform/linux-sgx/shared_platform.cmake b/core/shared-lib/platform/linux-sgx/shared_platform.cmake new file mode 100644 index 0000000000..5b403a09cc --- /dev/null +++ b/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}) + diff --git a/core/shared-lib/platform/linux/bh_platform.h b/core/shared-lib/platform/linux/bh_platform.h index 47172c1f68..2ee9e24f3c 100644 --- a/core/shared-lib/platform/linux/bh_platform.h +++ b/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); diff --git a/core/shared-lib/platform/vxworks/bh_platform.h b/core/shared-lib/platform/vxworks/bh_platform.h index 142583e5b5..c023549da3 100644 --- a/core/shared-lib/platform/vxworks/bh_platform.h +++ b/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); diff --git a/core/shared-lib/platform/zephyr/bh_platform.h b/core/shared-lib/platform/zephyr/bh_platform.h index 2602bee314..45f8e14eee 100644 --- a/core/shared-lib/platform/zephyr/bh_platform.h +++ b/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