From 8d6539536ee53730f5365ec7b9a90c850069e44d Mon Sep 17 00:00:00 2001 From: wenyongh Date: Thu, 23 May 2019 17:59:42 +0800 Subject: [PATCH 01/18] Implement memory profiler, optimize memory usage, modify code indent --- core/iwasm/lib/native/base/timer_wrapper.c | 23 +- .../native/extension/sensor/sensor_mgr_ref.c | 22 +- core/iwasm/runtime/vmcore-wasm/wasm.h | 13 ++ core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 21 +- core/iwasm/runtime/vmcore-wasm/wasm_loader.c | 143 +++++++++--- core/iwasm/runtime/vmcore-wasm/wasm_loader.h | 7 +- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 11 +- core/iwasm/runtime/vmcore-wasm/wasm_runtime.h | 8 +- core/shared-lib/include/bh_memory.h | 28 +++ core/shared-lib/include/config.h | 17 +- core/shared-lib/mem-alloc/bh_memory.c | 219 +++++++++++++++++- core/shared-lib/platform/linux/bh_thread.c | 2 +- doc/memory_usage.txt | 13 ++ samples/littlevgl/README.md | 2 +- .../src/platform/linux/iwasm_main.c | 2 +- .../src/platform/zephyr/XPT2046.c | 15 +- .../src/platform/zephyr/iwasm_main.c | 21 +- samples/littlevgl/wasm-apps/Makefile_wasm_app | 2 +- 18 files changed, 463 insertions(+), 106 deletions(-) create mode 100644 doc/memory_usage.txt diff --git a/core/iwasm/lib/native/base/timer_wrapper.c b/core/iwasm/lib/native/base/timer_wrapper.c index f2a8f23c2e..da5c8943fa 100644 --- a/core/iwasm/lib/native/base/timer_wrapper.c +++ b/core/iwasm/lib/native/base/timer_wrapper.c @@ -55,8 +55,8 @@ void * thread_modulers_timer_check(void * arg) while (1) { ms_to_expiry = -1; vm_mutex_lock(&g_timer_ctx_list_mutex); - timer_ctx_node_t* elem = (timer_ctx_node_t*) bh_list_first_elem( - &g_timer_ctx_list); + timer_ctx_node_t* elem = (timer_ctx_node_t*) + bh_list_first_elem(&g_timer_ctx_list); while (elem) { int next = check_app_timers(elem->timer_ctx); if (next != -1) { @@ -72,7 +72,7 @@ void * thread_modulers_timer_check(void * arg) ms_to_expiry = 60 * 1000; vm_mutex_lock(&g_timer_ctx_list_mutex); vm_cond_reltimedwait(&g_timer_ctx_list_cond, &g_timer_ctx_list_mutex, - ms_to_expiry); + ms_to_expiry); vm_mutex_unlock(&g_timer_ctx_list_mutex); } } @@ -94,20 +94,21 @@ void init_wasm_timer() vm_recursive_mutex_init(&g_timer_ctx_list_mutex); vm_thread_create(&tm_tid, thread_modulers_timer_check, - NULL, - BH_APPLET_PRESERVED_STACK_SIZE); + NULL, BH_APPLET_PRESERVED_STACK_SIZE); } timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num) { timer_ctx_t ctx = create_timer_ctx(wasm_timer_callback, - wakeup_modules_timer_thread, prealloc_num, module_id); + wakeup_modules_timer_thread, + prealloc_num, + module_id); if (ctx == NULL) return NULL; - timer_ctx_node_t * node = (timer_ctx_node_t*) bh_malloc( - sizeof(timer_ctx_node_t)); + timer_ctx_node_t * node = (timer_ctx_node_t*) + bh_malloc(sizeof(timer_ctx_node_t)); if (node == NULL) { destroy_timer_ctx(ctx); return NULL; @@ -125,8 +126,8 @@ timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num) void destory_module_timer_ctx(unsigned int module_id) { vm_mutex_lock(&g_timer_ctx_list_mutex); - timer_ctx_node_t* elem = (timer_ctx_node_t*) bh_list_first_elem( - &g_timer_ctx_list); + timer_ctx_node_t* elem = (timer_ctx_node_t*) + bh_list_first_elem(&g_timer_ctx_list); while (elem) { if (timer_ctx_get_owner(elem->timer_ctx) == module_id) { bh_list_remove(&g_timer_ctx_list, elem); @@ -151,7 +152,7 @@ timer_ctx_t get_wasm_timer_ctx() timer_id_t wasm_create_timer(int interval, bool is_period, bool auto_start) { return sys_create_timer(get_wasm_timer_ctx(), interval, is_period, - auto_start); + auto_start); } void wasm_timer_destory(timer_id_t timer_id) diff --git a/core/iwasm/lib/native/extension/sensor/sensor_mgr_ref.c b/core/iwasm/lib/native/extension/sensor/sensor_mgr_ref.c index b2cd53d316..a509313528 100644 --- a/core/iwasm/lib/native/extension/sensor/sensor_mgr_ref.c +++ b/core/iwasm/lib/native/extension/sensor/sensor_mgr_ref.c @@ -40,13 +40,13 @@ void app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg) wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data; wasm_module_inst_t inst = wasm_app_data->wasm_module_inst; - sensor_event_data_t *payload = (sensor_event_data_t*) bh_message_payload( - msg); + sensor_event_data_t *payload = (sensor_event_data_t*) + bh_message_payload(msg); if (payload == NULL) return; func_onSensorEvent = wasm_runtime_lookup_function(inst, "_on_sensor_event", - "(i32i32i32)"); + "(i32i32i32)"); if (!func_onSensorEvent) { printf("Cannot find function onRequest\n"); } else { @@ -54,18 +54,17 @@ void app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg) uint32 sensor_data_len; if (payload->data_fmt == FMT_ATTR_CONTAINER) { - sensor_data_len = attr_container_get_serialize_length( - payload->data); + sensor_data_len = attr_container_get_serialize_length(payload->data); } else { printf("Unsupported sensor data format: %d\n", payload->data_fmt); return; } sensor_data_offset = wasm_runtime_module_dup_data(inst, payload->data, - sensor_data_len); + sensor_data_len); if (sensor_data_offset == 0) { printf("Got exception running wasm code: %s\n", - wasm_runtime_get_exception(inst)); + wasm_runtime_get_exception(inst)); wasm_runtime_clear_exception(inst); return; } @@ -76,7 +75,7 @@ void app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg) if (!wasm_runtime_call_wasm(inst, NULL, func_onSensorEvent, 3, argv)) { printf(":Got exception running wasm code: %s\n", - wasm_runtime_get_exception(inst)); + wasm_runtime_get_exception(inst)); wasm_runtime_clear_exception(inst); wasm_runtime_module_free(inst, sensor_data_offset); return; @@ -130,17 +129,16 @@ void init_sensor_framework() // add the sys sensor objects add_sys_sensor("sensor_test", "This is a sensor for test", 0, 1000, - read_test_sensor, config_test_sensor); + read_test_sensor, config_test_sensor); set_sensor_reshceduler(cb_wakeup_thread); wasm_register_msg_callback(SENSOR_EVENT_WASM, - app_mgr_sensor_event_callback); + app_mgr_sensor_event_callback); wasm_register_cleanup_callback(sensor_cleanup_callback); vm_thread_create(&tid, (void *)thread_sensor_check, NULL, - BH_APPLET_PRESERVED_STACK_SIZE); - + BH_APPLET_PRESERVED_STACK_SIZE); } diff --git a/core/iwasm/runtime/vmcore-wasm/wasm.h b/core/iwasm/runtime/vmcore-wasm/wasm.h index 6917183b13..e493da9901 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm.h @@ -219,6 +219,15 @@ typedef struct WASMDataSeg { uint8 *data; } WASMDataSeg; +typedef struct BlockAddr { + const uint8 *start_addr; + uint8 *else_addr; + uint8 *end_addr; +} BlockAddr; + +#define BLOCK_ADDR_CACHE_SIZE 64 +#define BLOCK_ADDR_CONFLICT_SIZE 4 + typedef struct WASMModule { uint32 type_count; uint32 import_count; @@ -252,7 +261,11 @@ typedef struct WASMModule { uint32 start_function; HashMap *const_str_set; +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 HashMap *branch_set; +#else + BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE]; +#endif } WASMModule; typedef struct WASMBranchBlock { diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index f883587e89..ab715a477e 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -760,11 +760,12 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_BLOCK): read_leb_uint32(frame_ip, frame_ip_end, block_ret_type); - if (!wasm_loader_find_block_addr(module->branch_set, frame_ip, - frame_ip_end, BLOCK_TYPE_BLOCK, + if (!wasm_loader_find_block_addr(module->module, + frame_ip, frame_ip_end, + BLOCK_TYPE_BLOCK, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "wasm loader find block addr failed"); + wasm_runtime_set_exception(module, "find block addr failed"); goto got_exception; } @@ -774,11 +775,12 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_LOOP): read_leb_uint32(frame_ip, frame_ip_end, block_ret_type); - if (!wasm_loader_find_block_addr(module->branch_set, frame_ip, - frame_ip_end, BLOCK_TYPE_LOOP, + if (!wasm_loader_find_block_addr(module->module, + frame_ip, frame_ip_end, + BLOCK_TYPE_LOOP, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "wasm loader find block addr failed"); + wasm_runtime_set_exception(module, "find block addr failed"); goto got_exception; } @@ -788,11 +790,12 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_IF): read_leb_uint32(frame_ip, frame_ip_end, block_ret_type); - if (!wasm_loader_find_block_addr(module->branch_set, frame_ip, - frame_ip_end, BLOCK_TYPE_IF, + if (!wasm_loader_find_block_addr(module->module, + frame_ip, frame_ip_end, + BLOCK_TYPE_IF, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "wasm loader find block addr failed"); + wasm_runtime_set_exception(module, "find block addr failed"); goto got_exception; } diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index c37a12dfef..1af9278e1e 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -1180,10 +1180,11 @@ load_from_sections(WASMModule *module, WASMSection *sections, return true; } +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 static uint32 branch_set_hash(const void *key) { - return ((uintptr_t)key >> 4) ^ ((uintptr_t)key >> 14); + return ((uintptr_t)key) ^ ((uintptr_t)key >> 16); } static bool @@ -1197,6 +1198,16 @@ branch_set_value_destroy(void *value) { wasm_free(value); } +#endif + +#if BEIHAI_ENABLE_MEMORY_PROFILING != 0 +static void wasm_loader_free(void *ptr) +{ + wasm_free(ptr); +} +#else +#define wasm_loader_free wasm_free +#endif static WASMModule* create_module(char *error_buf, uint32 error_buf_size) @@ -1218,15 +1229,17 @@ create_module(char *error_buf, uint32 error_buf_size) (HashFunc)wasm_string_hash, (KeyEqualFunc)wasm_string_equal, NULL, - wasm_free))) + wasm_loader_free))) goto fail; +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 if (!(module->branch_set = wasm_hash_map_create(64, true, branch_set_hash, branch_set_key_equal, NULL, branch_set_value_destroy))) goto fail; +#endif return module; @@ -1361,15 +1374,17 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu (HashFunc)wasm_string_hash, (KeyEqualFunc)wasm_string_equal, NULL, - wasm_free))) + wasm_loader_free))) goto fail; +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 if (!(module->branch_set = wasm_hash_map_create(64, true, branch_set_hash, branch_set_key_equal, NULL, branch_set_value_destroy))) goto fail; +#endif if (!load(buf, size, module, error_buf, error_buf_size)) goto fail; @@ -1440,20 +1455,24 @@ wasm_loader_unload(WASMModule *module) if (module->const_str_set) wasm_hash_map_destroy(module->const_str_set); +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 if (module->branch_set) wasm_hash_map_destroy(module->branch_set); +#endif wasm_free(module); } +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 typedef struct block_addr { uint8 block_type; - uint8 *else_addr; uint8 *end_addr; + uint8 *else_addr; } block_addr; +#endif bool -wasm_loader_find_block_addr(HashMap *branch_set, +wasm_loader_find_block_addr(WASMModule *module, const uint8 *start_addr, const uint8 *code_end_addr, uint8 block_type, @@ -1466,8 +1485,10 @@ wasm_loader_find_block_addr(HashMap *branch_set, uint8 *else_addr = NULL; uint32 block_nested_depth = 1, count, i, u32, u64; uint8 opcode, u8; - block_addr *block; +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 + HashMap *branch_set = module->branch_set; + block_addr *block; if ((block = wasm_hash_map_find(branch_set, (void*)start_addr))) { if (block->block_type != block_type) return false; @@ -1476,6 +1497,25 @@ wasm_loader_find_block_addr(HashMap *branch_set, *p_end_addr = block->end_addr; return true; } +#else + BlockAddr block_stack[16] = { 0 }, *block; + uint32 j, t; + + i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16); + i = i % BLOCK_ADDR_CACHE_SIZE; + block = module->block_addr_cache[i]; + for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) { + if (block[j].start_addr == start_addr) { + /* Cache hit */ + *p_else_addr = block[j].else_addr; + *p_end_addr = block[j].end_addr; + return true; + } + } + + /* Cache unhit */ + block_stack[0].start_addr = start_addr; +#endif while (p < code_end_addr) { opcode = *p++; @@ -1489,12 +1529,22 @@ wasm_loader_find_block_addr(HashMap *branch_set, case WASM_OP_LOOP: case WASM_OP_IF: read_leb_uint32(p, p_end, u32); /* blocktype */ +#if WASM_ENABLE_HASH_BLOCK_ADDR == 0 + if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) { + block_stack[block_nested_depth].start_addr = p; + block_stack[block_nested_depth].else_addr = NULL; + } +#endif block_nested_depth++; break; case WASM_OP_ELSE: if (block_type == BLOCK_TYPE_IF && block_nested_depth == 1) else_addr = (uint8*)(p - 1); +#if WASM_ENABLE_HASH_BLOCK_ADDR == 0 + if (block_nested_depth - 1 < sizeof(block_stack)/sizeof(BlockAddr)) + block_stack[block_nested_depth - 1].else_addr = (uint8*)(p - 1); +#endif break; case WASM_OP_END: @@ -1503,7 +1553,13 @@ wasm_loader_find_block_addr(HashMap *branch_set, *p_else_addr = else_addr; *p_end_addr = (uint8*)(p - 1); - if ((block = wasm_malloc(sizeof(block_addr)))) { +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 + if (block_type == BLOCK_TYPE_IF) + block = wasm_malloc(sizeof(block_addr)); + else + block = wasm_malloc(offsetof(block_addr, else_addr)); + + if (block) { block->block_type = block_type; if (block_type == BLOCK_TYPE_IF) block->else_addr = else_addr; @@ -1512,11 +1568,41 @@ wasm_loader_find_block_addr(HashMap *branch_set, if (!wasm_hash_map_insert(branch_set, (void*)start_addr, block)) wasm_free(block); } - +#else + block_stack[0].end_addr = (uint8*)(p - 1); + for (t = 0; t < sizeof(block_stack)/sizeof(BlockAddr); t++) { + start_addr = block_stack[t].start_addr; + if (start_addr) { + i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16); + i = i % BLOCK_ADDR_CACHE_SIZE; + block = module->block_addr_cache[i]; + for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) + if (!block[j].start_addr) + break; + + if (j == BLOCK_ADDR_CONFLICT_SIZE) { + memmove(block + 1, block, (BLOCK_ADDR_CONFLICT_SIZE - 1) * + sizeof(BlockAddr)); + j = 0; + + } + block[j].start_addr = block_stack[t].start_addr; + block[j].else_addr = block_stack[t].else_addr; + block[j].end_addr = block_stack[t].end_addr; + } + else + break; + } +#endif return true; } - else + else { block_nested_depth--; +#if WASM_ENABLE_HASH_BLOCK_ADDR == 0 + if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) + block_stack[block_nested_depth].end_addr = (uint8*)(p - 1); +#endif + } break; case WASM_OP_BR: @@ -2079,14 +2165,13 @@ static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, char *error_buf, uint32 error_buf_size) { - HashMap *branch_set = module->branch_set; +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 block_addr *block; +#endif uint8 *p = func->code, *p_end = func->code + func->code_size; - uint8 *frame_lp_ref_bottom = NULL; uint8 *frame_ref_bottom = NULL, *frame_ref_boundary, *frame_ref; BranchBlock *frame_csp_bottom = NULL, *frame_csp_boundary, *frame_csp; uint32 param_count, local_count, global_count; - uint32 param_cell_num, local_cell_num; uint32 max_stack_cell_num = 0, max_csp_num = 0; uint32 stack_cell_num = 0, csp_num = 0; uint32 frame_ref_size, frame_csp_size; @@ -2107,16 +2192,6 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, local_count = func->local_count; local_types = func->local_types; - param_cell_num = wasm_get_cell_num(param_types, param_count); - local_cell_num = wasm_get_cell_num(local_types, local_count); - - if (!(frame_lp_ref_bottom = wasm_malloc(param_cell_num + local_cell_num))) { - set_error_buf(error_buf, error_buf_size, - "WASM loader prepare bytecode failed: alloc memory failed"); - goto fail; - } - memset(frame_lp_ref_bottom, 0, param_cell_num + local_cell_num); - frame_ref_size = 32; if (!(frame_ref_bottom = frame_ref = wasm_malloc(frame_ref_size))) { set_error_buf(error_buf, error_buf_size, @@ -2167,7 +2242,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, (frame_csp - 1)->jumped_by_br = true; else { if (!i32_const) { - if(!wasm_loader_find_block_addr(branch_set, + if(!wasm_loader_find_block_addr(module, (frame_csp - 1)->start_addr, p_end, (frame_csp - 1)->block_type, @@ -2210,10 +2285,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, if (csp_num > 0) { frame_csp->end_addr = p - 1; - if (wasm_hash_map_find(branch_set, (void*)frame_csp->start_addr)) +#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 + if (wasm_hash_map_find(module->branch_set, (void*)frame_csp->start_addr)) break; - if (!(block = wasm_malloc(sizeof(block_addr)))) { + if (frame_csp->block_type == BLOCK_TYPE_IF) + block = wasm_malloc(sizeof(block_addr)); + else + block = wasm_malloc(offsetof(block_addr, else_addr)); + + if (!block) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " "alloc memory failed"); @@ -2221,10 +2302,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } block->block_type = frame_csp->block_type; - block->else_addr = (void*)frame_csp->else_addr; + if (frame_csp->block_type == BLOCK_TYPE_IF) + block->else_addr = (void*)frame_csp->else_addr; block->end_addr = (void*)frame_csp->end_addr; - if (!wasm_hash_map_insert(branch_set, (void*)frame_csp->start_addr, + if (!wasm_hash_map_insert(module->branch_set, (void*)frame_csp->start_addr, block)) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " @@ -2232,6 +2314,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, wasm_free(block); goto fail; } +#endif } break; } @@ -2248,7 +2331,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, block_return_type = (frame_csp - i)->return_type; - if(!wasm_loader_find_block_addr(branch_set, + if(!wasm_loader_find_block_addr(module, (frame_csp - i)->start_addr, p_end, (frame_csp - i)->block_type, @@ -2304,7 +2387,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, POP_TYPE(ret_type); PUSH_TYPE(ret_type); - if(!wasm_loader_find_block_addr(branch_set, + if(!wasm_loader_find_block_addr(module, (frame_csp - 1)->start_addr, p_end, (frame_csp - 1)->block_type, @@ -2862,8 +2945,6 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, return_value = true; fail: - if (frame_lp_ref_bottom) - wasm_free(frame_lp_ref_bottom); if (frame_ref_bottom) wasm_free(frame_ref_bottom); if (frame_csp_bottom) diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.h b/core/iwasm/runtime/vmcore-wasm/wasm_loader.h index 98bc06df13..1a39396053 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.h @@ -61,10 +61,7 @@ wasm_loader_unload(WASMModule *module); * Find address of related else opcode and end opcode of opcode block/loop/if * according to the start address of opcode. * - * @param branch_set the hashtable to store the else/end adress info of - * block/loop/if opcode. The function will lookup the hashtable firstly, - * if not found, it will then search the code from start_addr, and if success, - * stores the result to the hashtable. + * @param module the module to find * @param start_addr the next address of opcode block/loop/if * @param code_end_addr the end address of function code block * @param block_type the type of block, 0/1/2 denotes block/loop/if @@ -76,7 +73,7 @@ wasm_loader_unload(WASMModule *module); * @return true if success, false otherwise */ bool -wasm_loader_find_block_addr(HashMap *map, +wasm_loader_find_block_addr(WASMModule *module, const uint8 *start_addr, const uint8 *code_end_addr, uint8 block_type, diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index f6c3c5cce1..b12256d37b 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -706,7 +706,7 @@ execute_start_function(WASMModuleInstance *module_inst) * Instantiate module */ WASMModuleInstance* -wasm_runtime_instantiate(const WASMModule *module, +wasm_runtime_instantiate(WASMModule *module, uint32 stack_size, uint32 heap_size, char *error_buf, uint32 error_buf_size) { @@ -726,9 +726,11 @@ wasm_runtime_instantiate(const WASMModule *module, /* Check heap size */ heap_size = align_uint(heap_size, 8); if (heap_size == 0) - heap_size = DEFAULT_WASM_HEAP_SIZE; - if (heap_size < MIN_WASM_HEAP_SIZE) - heap_size = MIN_WASM_HEAP_SIZE; + heap_size = APP_HEAP_SIZE_DEFAULT; + if (heap_size < APP_HEAP_SIZE_MIN) + heap_size = APP_HEAP_SIZE_MIN; + if (heap_size > APP_HEAP_SIZE_MAX) + heap_size = APP_HEAP_SIZE_MAX; /* Instantiate global firstly to get the mutable data size */ global_count = module->import_global_count + module->global_count; @@ -909,7 +911,6 @@ wasm_runtime_instantiate(const WASMModule *module, &module_inst->functions[module->start_function]; } - module_inst->branch_set = module->branch_set; module_inst->module = module; /* module instance type */ diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h index 8a2e87fa0f..649f8308da 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h @@ -25,11 +25,6 @@ extern "C" { #endif - -#define DEFAULT_WASM_STACK_SIZE (8 * 1024) -#define DEFAULT_WASM_HEAP_SIZE (8 * 1024) -#define MIN_WASM_HEAP_SIZE (1 * 1024) - typedef struct WASMMemoryInstance { /* Current page count */ uint32 cur_page_count; @@ -153,8 +148,7 @@ typedef struct WASMModuleInstance { WASMFunctionInstance *start_function; - HashMap *branch_set; - const WASMModule *module; + WASMModule *module; uint32 DYNAMICTOP_PTR_offset; uint32 temp_ret; diff --git a/core/shared-lib/include/bh_memory.h b/core/shared-lib/include/bh_memory.h index c24b132a7c..51312cbf14 100644 --- a/core/shared-lib/include/bh_memory.h +++ b/core/shared-lib/include/bh_memory.h @@ -52,6 +52,8 @@ int bh_memory_init_with_allocator(void *malloc_func, void *free_func); */ void bh_memory_destroy(); +#if BEIHAI_ENABLE_MEMORY_PROFILING == 0 + /** * This function allocates a memory chunk from system * @@ -68,6 +70,32 @@ void* bh_malloc(unsigned int size); */ void bh_free(void *ptr); +#else + +void* bh_malloc_profile(const char *file, int line, const char *func, unsigned int size); +void bh_free_profile(const char *file, int line, const char *func, void *ptr); + +#define bh_malloc(size) bh_malloc_profile(__FILE__, __LINE__, __func__, size) +#define bh_free(ptr) bh_free_profile(__FILE__, __LINE__, __func__, ptr) + +/** + * Print current memory profiling data + * + * @param file file name of the caller + * @param line line of the file of the caller + * @param func function name of the caller + */ +void memory_profile_print(const char *file, int line, const char *func, int alloc); + +/** + * Summarize memory usage and print it out + * Can use awk to analyze the output like below: + * awk -F: '{print $2,$4,$6,$8,$9}' OFS="\t" ./out.txt | sort -n -r -k 1 + */ +void memory_usage_summarize(); + +#endif + #ifdef __cplusplus } #endif diff --git a/core/shared-lib/include/config.h b/core/shared-lib/include/config.h index 8ca0e01e21..e1926a4bb8 100644 --- a/core/shared-lib/include/config.h +++ b/core/shared-lib/include/config.h @@ -48,6 +48,9 @@ /* WASM Interpreter labels-as-values feature */ #define WASM_ENABLE_LABELS_AS_VALUES 1 +/* WASM Branch Block address hashmap */ +#define WASM_ENABLE_HASH_BLOCK_ADDR 0 + /* Heap and stack profiling */ #define BEIHAI_ENABLE_MEMORY_PROFILING 0 @@ -77,14 +80,22 @@ #define WORKING_FLOW_HEAP_SIZE 0 */ -/* Default/min/max heap size of each app */ -#define APP_HEAP_SIZE_DEFAULT (48 * 1024) +/* Default min/max heap size of each app */ +#define APP_HEAP_SIZE_DEFAULT (8 * 1024) #define APP_HEAP_SIZE_MIN (2 * 1024) #define APP_HEAP_SIZE_MAX (1024 * 1024) +/* Default wasm stack size of each app */ +#define DEFAULT_WASM_STACK_SIZE (8 * 1024) + /* Default/min/max stack size of each app thread */ +#ifndef __ZEPHYR__ #define APP_THREAD_STACK_SIZE_DEFAULT (20 * 1024) #define APP_THREAD_STACK_SIZE_MIN (16 * 1024) #define APP_THREAD_STACK_SIZE_MAX (256 * 1024) - +#else +#define APP_THREAD_STACK_SIZE_DEFAULT (4 * 1024) +#define APP_THREAD_STACK_SIZE_MIN (2 * 1024) +#define APP_THREAD_STACK_SIZE_MAX (256 * 1024) +#endif #endif diff --git a/core/shared-lib/mem-alloc/bh_memory.c b/core/shared-lib/mem-alloc/bh_memory.c index 46dd1fd8da..92b1fdd470 100644 --- a/core/shared-lib/mem-alloc/bh_memory.c +++ b/core/shared-lib/mem-alloc/bh_memory.c @@ -14,11 +14,38 @@ * limitations under the License. */ +#include "bh_config.h" #include "bh_memory.h" #include "mem_alloc.h" #include #include +#if BEIHAI_ENABLE_MEMORY_PROFILING != 0 +#include "bh_thread.h" + +/* Memory profile data of a function */ +typedef struct memory_profile { + struct memory_profile *next; + const char *function_name; + const char *file_name; + int line_in_file; + int malloc_num; + int free_num; + int total_malloc; + int total_free; +} memory_profile_t; + +/* Memory in use which grows when bh_malloc was called + * and decreases when bh_free was called */ +static unsigned int memory_in_use = 0; + +/* Memory profile data list */ +static memory_profile_t *memory_profiles_list = NULL; + +/* Lock of the memory profile list */ +static korp_mutex profile_lock; +#endif + #ifndef MALLOC_MEMORY_FROM_SYSTEM typedef enum Memory_Mode { @@ -39,6 +66,9 @@ int bh_memory_init_with_pool(void *mem, unsigned int bytes) if (_allocator) { memory_mode = MEMORY_MODE_POOL; pool_allocator = _allocator; +#if BEIHAI_ENABLE_MEMORY_PROFILING != 0 + vm_mutex_init(&profile_lock); +#endif return 0; } printf("Init memory with pool (%p, %u) failed.\n", mem, bytes); @@ -51,6 +81,9 @@ int bh_memory_init_with_allocator(void *_malloc_func, void *_free_func) memory_mode = MEMORY_MODE_ALLOCATOR; malloc_func = _malloc_func; free_func = _free_func; +#if BEIHAI_ENABLE_MEMORY_PROFILING != 0 + vm_mutex_init(&profile_lock); +#endif return 0; } printf("Init memory with allocator (%p, %p) failed.\n", _malloc_func, @@ -60,12 +93,15 @@ int bh_memory_init_with_allocator(void *_malloc_func, void *_free_func) void bh_memory_destroy() { +#if BEIHAI_ENABLE_MEMORY_PROFILING != 0 + vm_mutex_destroy(&profile_lock); +#endif if (memory_mode == MEMORY_MODE_POOL) mem_allocator_destroy(pool_allocator); memory_mode = MEMORY_MODE_UNKNOWN; } -void* bh_malloc(unsigned int size) +void* bh_malloc_internal(unsigned int size) { if (memory_mode == MEMORY_MODE_UNKNOWN) { printf("bh_malloc failed: memory hasn't been initialize.\n"); @@ -77,7 +113,7 @@ void* bh_malloc(unsigned int size) } } -void bh_free(void *ptr) +void bh_free_internal(void *ptr) { if (memory_mode == MEMORY_MODE_UNKNOWN) { printf("bh_free failed: memory hasn't been initialize.\n"); @@ -88,8 +124,157 @@ void bh_free(void *ptr) } } +#if BEIHAI_ENABLE_MEMORY_PROFILING != 0 +void* bh_malloc_profile(const char *file, + int line, + const char *func, + unsigned int size) +{ + void *p = bh_malloc_internal(size + 8); + + if (p) { + memory_profile_t *profile; + + vm_mutex_lock(&profile_lock); + + profile = memory_profiles_list; + while (profile) { + if (strcmp(profile->function_name, func) == 0 + && strcmp(profile->file_name, file) == 0) { + break; + } + profile = profile->next; + } + + if (profile) { + profile->total_malloc += size;/* TODO: overflow check */ + profile->malloc_num++; + } else { + profile = bh_malloc_internal(sizeof(memory_profile_t)); + if (!profile) { + vm_mutex_unlock(&profile_lock); + memcpy(p, &size, sizeof(size)); + return (char *)p + 8; + } + + memset(profile, 0, sizeof(memory_profile_t)); + profile->file_name = file; + profile->line_in_file = line; + profile->function_name = func; + profile->malloc_num = 1; + profile->total_malloc = size; + profile->next = memory_profiles_list; + memory_profiles_list = profile; + } + + vm_mutex_unlock(&profile_lock); + + memcpy(p, &size, sizeof(size)); + memory_in_use += size; + + memory_profile_print(file, line, func, size); + + return (char *)p + 8; + } + + return NULL; +} + +void bh_free_profile(const char *file, int line, const char *func, void *ptr) +{ + unsigned int size = *(unsigned int *)((char *)ptr - 8); + memory_profile_t *profile; + + bh_free_internal((char *)ptr - 8); + + if (memory_in_use >= size) + memory_in_use -= size; + + vm_mutex_lock(&profile_lock); + + profile = memory_profiles_list; + while (profile) { + if (strcmp(profile->function_name, func) == 0 + && strcmp(profile->file_name, file) == 0) { + break; + } + profile = profile->next; + } + + if (profile) { + profile->total_free += size;/* TODO: overflow check */ + profile->free_num++; + } else { + profile = bh_malloc_internal(sizeof(memory_profile_t)); + if (!profile) { + vm_mutex_unlock(&profile_lock); + return; + } + + memset(profile, 0, sizeof(memory_profile_t)); + profile->file_name = file; + profile->line_in_file = line; + profile->function_name = func; + profile->free_num = 1; + profile->total_free = size; + profile->next = memory_profiles_list; + memory_profiles_list = profile; + } + + vm_mutex_unlock(&profile_lock); +} + +/** + * Summarize memory usage and print it out + * Can use awk to analyze the output like below: + * awk -F: '{print $2,$4,$6,$8,$9}' OFS="\t" ./out.txt | sort -n -r -k 1 + */ +void memory_usage_summarize() +{ + memory_profile_t *profile; + + vm_mutex_lock(&profile_lock); + + profile = memory_profiles_list; + while (profile) { + printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n", + profile->total_malloc, + profile->malloc_num, + profile->total_free, + profile->free_num, + profile->function_name); + profile = profile->next; + } + + vm_mutex_unlock(&profile_lock); +} + +void memory_profile_print(const char *file, + int line, + const char *func, + int alloc) +{ + printf("location:%s@%d:used:%d:contribution:%d\n", + func, line, memory_in_use, alloc); +} + +#else + +void* bh_malloc(unsigned int size) +{ + return bh_malloc_internal(size); +} + +void bh_free(void *ptr) +{ + bh_free_internal(ptr); +} +#endif + #else /* else of MALLOC_MEMORY_FROM_SYSTEM */ +#if BEIHAI_ENABLE_MEMORY_PROFILING == 0 + void* bh_malloc(unsigned int size) { return malloc(size); @@ -98,8 +283,36 @@ void* bh_malloc(unsigned int size) void bh_free(void *ptr) { if (ptr) - free(ptr); + free(ptr); +} + +#else /* else of BEIHAI_ENABLE_MEMORY_PROFILING */ + +void* bh_malloc_profile(const char *file, + int line, + const char *func, + unsigned int size) +{ + (void)file; + (void)line; + (void)func; + + (void)memory_profiles_list; + (void)profile_lock; + (void)memory_in_use; + + return malloc(size); } +void bh_free_profile(const char *file, int line, const char *func, void *ptr) +{ + (void)file; + (void)line; + (void)func; + + if (ptr) + free(ptr); +} +#endif /* end of BEIHAI_ENABLE_MEMORY_PROFILING */ #endif /* end of MALLOC_MEMORY_FROM_SYSTEM*/ diff --git a/core/shared-lib/platform/linux/bh_thread.c b/core/shared-lib/platform/linux/bh_thread.c index 9d45b147f0..201c9b5e68 100755 --- a/core/shared-lib/platform/linux/bh_thread.c +++ b/core/shared-lib/platform/linux/bh_thread.c @@ -128,7 +128,7 @@ 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); + BH_THREAD_DEFAULT_PRIORITY); } korp_tid _vm_self_thread() diff --git a/doc/memory_usage.txt b/doc/memory_usage.txt new file mode 100644 index 0000000000..ecc64a9715 --- /dev/null +++ b/doc/memory_usage.txt @@ -0,0 +1,13 @@ +Current memory usage, take samples/littlevgl in Zephyr for example: +(1) WASM app binary: 142K for littlevgl ui_app.wasm +(2) WASM app memory space: 64K for littlevgl ui_app.wasm +(3) WASM app heap space: 8K by default +(4) WASM app thread native stack: 4K by default +(5) WASM interpreter stack: 8K by default +(6) WASM block address hash cache: 3K +(7) timer thread stack: 4K +(8) sensor thread stack: 4K +(9) touch screen thread stack: 4K +(10) others: vm, app mgr, queue, native lib: ~22K + +Total memory usage: ~263K diff --git a/samples/littlevgl/README.md b/samples/littlevgl/README.md index 81db08863b..006b6624c6 100644 --- a/samples/littlevgl/README.md +++ b/samples/littlevgl/README.md @@ -75,7 +75,7 @@ https://docs.zephyrproject.org/latest/getting_started/index.html
However, nucleo_f767zi is almost the same as nucleo_f746zg, except FLASH and SRAM size. So we changed the DTS setting of nucleo_f746zg boards for a workaround.
- `Modify zephyr/dts/arm/st/f7/stm32f746xg.dtsi, change DT_SIZE_K(320) to DT_SIZE_K(512)`
+ `Modify zephyr/dts/arm/st/f7/stm32f746Xg.dtsi, change DT_SIZE_K(320) to DT_SIZE_K(512)`
`mkdir build && cd build`
`source ../../../../zephyr-env.sh`
`cmake -GNinja -DBOARD=nucleo_f746zg ..`
diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c index cbb894100e..c5d23b0579 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c @@ -342,7 +342,7 @@ static host_interface interface = { .send = uart_send, .destroy = uart_destroy } #endif -static char global_heap_buf[1024 * 1024] = { 0 }; +static char global_heap_buf[270 * 1024] = { 0 }; static void showUsage() { diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c index 5d408b562d..6d9048d4df 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c @@ -152,7 +152,7 @@ void xpt2046_init(void) return; } gpio_pin_configure(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, - GPIO_DIR_OUT); + GPIO_DIR_OUT); gpio_pin_write(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, 1); xpt2046_cs_ctrl.gpio_pin = XPT2046_CS_GPIO_PIN; xpt2046_cs_ctrl.delay = 0; @@ -169,14 +169,15 @@ void xpt2046_init(void) } /* Setup GPIO input */ ret = gpio_pin_configure(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN, - (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW - | GPIO_INT_DEBOUNCE)); + (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE + | GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE) + ); if (ret) { printk("Error configuring pin %d!\n", XPT2046_PEN_GPIO_PIN); } gpio_init_callback(&gpio_cb, xpt2046_pen_gpio_callback, - BIT(XPT2046_PEN_GPIO_PIN)); + BIT(XPT2046_PEN_GPIO_PIN)); ret = gpio_add_callback(xpt2046_pen_gpio_dev, &gpio_cb); if (ret) { @@ -191,10 +192,10 @@ void xpt2046_init(void) k_sem_init(&sem_touch_read, 0, 1); k_thread_create(&touch_thread_data, touch_read_thread_stack, - TOUCH_READ_THREAD_STACK_SIZE, touch_screen_read_thread, NULL, NULL, NULL, 5, - 0, K_NO_WAIT); + TOUCH_READ_THREAD_STACK_SIZE, touch_screen_read_thread, + NULL, NULL, NULL, 5, + 0, K_NO_WAIT); printf("xpt2046_init ok \n"); - } /** diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c index dc0d745c39..1fc3eb941d 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c @@ -43,7 +43,6 @@ static void uart_irq_callback(struct device *dev) int size = 0; while (uart_poll_in(dev, &ch) == 0) { - uart_char_cnt++; aee_host_msg_callback(&ch, 1); } @@ -66,24 +65,27 @@ static bool host_init() int host_send(void * ctx, const char *buf, int size) { for (int i = 0; i < size; i++) - uart_poll_out(uart_dev, buf[i]); + uart_poll_out(uart_dev, buf[i]); return size; } void host_destroy() { - } +host_interface interface = { + .init = host_init, + .send = host_send, + .destroy = host_destroy +}; -#define DEFAULT_THREAD_STACKSIZE (8 * 1024) - -host_interface interface = { .init = host_init, .send = - host_send, .destroy = host_destroy }; timer_ctx_t timer_ctx; -static char global_heap_buf[ 498*1024] = { 0 }; + +static char global_heap_buf[270 * 1024] = { 0 }; + extern void display_init(void); + int iwasm_main() { korp_thread tid, tm_tid; @@ -108,6 +110,7 @@ int iwasm_main() // TODO: app_manager_startup(&interface); - fail1: bh_memory_destroy(); +fail1: + bh_memory_destroy(); return -1; } diff --git a/samples/littlevgl/wasm-apps/Makefile_wasm_app b/samples/littlevgl/wasm-apps/Makefile_wasm_app index 801aed4adf..dcf7f17243 100644 --- a/samples/littlevgl/wasm-apps/Makefile_wasm_app +++ b/samples/littlevgl/wasm-apps/Makefile_wasm_app @@ -50,6 +50,6 @@ SRCS += ../../../core/iwasm/lib/app-libs/base/timer.c all: @$(CC) $(CFLAGS) $(SRCS) \ -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=131072 -s TOTAL_STACK=8096 \ + -s TOTAL_MEMORY=65536 -s TOTAL_STACK=2048\ -s "EXPORTED_FUNCTIONS=['_on_init', '_on_request', '_on_sensor_event', '_on_timer_callback']" \ -o ui_app.wasm From f32965bb5948d479cdcd3f8482092908f7d31724 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Fri, 31 May 2019 14:15:44 +0800 Subject: [PATCH 02/18] Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default --- README.md | 2 +- core/iwasm/products/linux/CMakeLists.txt | 9 +- core/iwasm/products/linux/main.c | 41 ++-- core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 65 +++--- core/iwasm/runtime/vmcore-wasm/wasm_loader.c | 24 ++- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 186 +++++++++++------- core/iwasm/runtime/vmcore-wasm/wasm_runtime.h | 18 +- core/shared-lib/include/bh_memory.h | 6 + core/shared-lib/include/config.h | 9 + core/shared-lib/mem-alloc/bh_memory.c | 15 +- core/shared-lib/platform/linux/bh_thread.c | 2 +- 11 files changed, 237 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index 1fe9e8bf69..2e85545277 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ cd iwasm/products/linux/bin You will get the following output: ``` Hello world! -buf ptr: 0x000101ac +buf ptr: 0x400002b0 buf: 1234 ``` If you would like to run the test app on Zephyr, we have embedded a test sample into its OS image. You will need to execute: diff --git a/core/iwasm/products/linux/CMakeLists.txt b/core/iwasm/products/linux/CMakeLists.txt index 72926661bb..a2510790e4 100644 --- a/core/iwasm/products/linux/CMakeLists.txt +++ b/core/iwasm/products/linux/CMakeLists.txt @@ -29,8 +29,8 @@ if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) add_definitions(-DNVALGRIND) endif () -# Currently build as 32-bit by default. -set (BUILD_AS_64BIT_SUPPORT "NO") +# 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") @@ -44,6 +44,11 @@ else () 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") diff --git a/core/iwasm/products/linux/main.c b/core/iwasm/products/linux/main.c index 7a87d8b0a7..22fe692c0e 100644 --- a/core/iwasm/products/linux/main.c +++ b/core/iwasm/products/linux/main.c @@ -35,15 +35,14 @@ static int print_help() { wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n"); wasm_printf("options:\n"); - wasm_printf(" -f|--function name Specify function name to run " - "in module rather than main\n"); + wasm_printf(" -f|--function name Specify function name to run in module\n" + " rather than main\n"); #if WASM_ENABLE_LOG != 0 - wasm_printf( - " -v=X Set log verbose level (0 to 2, default is 1), larger level with more log\n"); + wasm_printf(" -v=X Set log verbose level (0 to 2, default is 1),\n" + " larger level with more log\n"); #endif - wasm_printf( - " --repl Start a very simple REPL (read-eval-print-loop) mode \n" - " that runs commands in the form of `FUNC ARG...`\n"); + wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" + " that runs commands in the form of `FUNC ARG...`\n"); return 1; } @@ -64,7 +63,7 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name) const char *exception; wasm_application_execute_func(module_inst, func_name, app_argc - 1, - app_argv + 1); + app_argv + 1); if ((exception = wasm_runtime_get_exception(module_inst))) wasm_printf("%s\n", exception); return NULL; @@ -122,7 +121,7 @@ app_instance_repl(wasm_module_inst_t module_inst) } if (app_argc != 0) { wasm_application_execute_func(module_inst, app_argv[0], - app_argc - 1, app_argv + 1); + app_argc - 1, app_argv + 1); } free(app_argv); } @@ -177,7 +176,7 @@ int main(int argc, char *argv[]) app_argv = argv; if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) - != 0) { + != 0) { wasm_printf("Init global heap failed.\n"); return -1; } @@ -190,19 +189,22 @@ int main(int argc, char *argv[]) /* load WASM byte buffer from WASM bin file */ if (!(wasm_file_buf = (uint8*) wasm_read_file_to_buffer(wasm_file, - &wasm_file_size))) + &wasm_file_size))) goto fail2; /* load WASM module */ if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, - error_buf, sizeof(error_buf)))) { + error_buf, sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); goto fail3; } /* instantiate the module */ - if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024, - 8 * 1024, error_buf, sizeof(error_buf)))) { + if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, + 16 * 1024, /* stack size */ + 8 * 1024, /* heap size */ + error_buf, + sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); goto fail4; } @@ -217,21 +219,20 @@ int main(int argc, char *argv[]) /* destroy the module instance */ wasm_runtime_deinstantiate(wasm_module_inst); - fail4: +fail4: /* unload the module */ wasm_runtime_unload(wasm_module); - fail3: +fail3: /* free the file buffer */ wasm_free(wasm_file_buf); - fail2: +fail2: /* destroy runtime environment */ wasm_runtime_destroy(); - fail1: bh_memory_destroy(); - - (void) func_name; +fail1: + bh_memory_destroy(); return 0; } diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index ab715a477e..73163f32ca 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -74,26 +74,28 @@ GET_F64_FROM_ADDR (uint32 *addr) } #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ -#define is_valid_addr(memory, heap, addr) \ - (memory->base_addr <= addr && addr <= memory->end_addr) \ - #define CHECK_MEMORY_OVERFLOW() do { \ + uint32 offset1 = offset + addr; \ uint8 *maddr1; \ if (flags != 2) \ LOG_VERBOSE("unaligned load/store in wasm interp, flag is: %d.\n", flags);\ - if (offset + addr < addr) { \ - wasm_runtime_set_exception(module, "out of bounds memory access"); \ - goto got_exception; \ - } \ - maddr = memory->memory_data + (offset + addr); \ - if (!is_valid_addr(memory, NULL, maddr)) { \ - wasm_runtime_set_exception(module, "out of bounds memory access"); \ - goto got_exception; \ + if (offset1 < offset) \ + goto out_of_bounds; \ + if (offset1 < heap_base_offset) { \ + maddr = memory->memory_data + offset1; \ + if (maddr < memory->base_addr) \ + goto out_of_bounds; \ + maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ + if (maddr1 > memory->end_addr) \ + goto out_of_bounds; \ } \ - maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ - if (!is_valid_addr(memory, NULL, maddr1)) { \ - wasm_runtime_set_exception(module, "out of bounds memory access"); \ - goto got_exception; \ + else { \ + maddr = memory->heap_data + offset1 - memory->heap_base_offset; \ + if (maddr < memory->heap_data) \ + goto out_of_bounds; \ + maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ + if (maddr1 > memory->heap_data_end) \ + goto out_of_bounds; \ } \ } while (0) @@ -712,6 +714,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, { WASMModuleInstance *module = self->module_inst; WASMMemoryInstance *memory = module->default_memory; + int32 heap_base_offset = memory ? memory->heap_base_offset : 0; WASMTableInstance *table = module->default_table; uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2; WASMInterpFrame *frame = NULL; @@ -1247,26 +1250,25 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_MEMORY_GROW): { - uint32 reserved, prev_page_count, delta, tmp; + uint32 reserved, delta, prev_page_count = memory->cur_page_count; read_leb_uint32(frame_ip, frame_ip_end, reserved); - prev_page_count = memory->cur_page_count; delta = POP_I32(); - PUSH_I32(prev_page_count); - if (delta == 0) - HANDLE_OP_END (); - else if (delta + prev_page_count > memory->max_page_count || - delta + prev_page_count < prev_page_count) { - tmp = POP_I32(); + + if (!wasm_runtime_enlarge_memory(module, delta)) { + /* fail to memory.grow, return -1 */ PUSH_I32(-1); - (void)tmp; - HANDLE_OP_END (); + if (wasm_runtime_get_exception(module)) { + printf("%s\n", wasm_runtime_get_exception(module)); + wasm_runtime_set_exception(module, NULL); + } + } + else { + /* success, return previous page count */ + PUSH_I32(prev_page_count); + /* update the memory instance ptr */ + memory = module->default_memory; } - - if (!wasm_runtime_enlarge_memory(module, delta)) - goto got_exception; - - memory = module->default_memory; (void)reserved; HANDLE_OP_END (); @@ -2093,6 +2095,9 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP_END (); } + out_of_bounds: + wasm_runtime_set_exception(module, "out of bounds memory access"); + got_exception: if (depths && depths != depth_buf) { wasm_free(depths); diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index 1af9278e1e..c03ddc3a31 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -314,14 +314,20 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end, char *error_buf, uint32 error_buf_size) { const uint8 *p = *p_buf, *p_end = buf_end; + uint32 pool_size = bh_memory_pool_size(); + uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT + / NumBytesPerPage; read_leb_uint32(p, p_end, memory->flags); read_leb_uint32(p, p_end, memory->init_page_count); - if (memory->flags & 1) + if (memory->flags & 1) { read_leb_uint32(p, p_end, memory->max_page_count); + if (memory->max_page_count > max_page_count) + memory->max_page_count = max_page_count; + } else - /* Limit the maximum memory size to 4GB */ - memory->max_page_count = 0x10000; + /* Limit the maximum memory size to max_page_count */ + memory->max_page_count = max_page_count; *p_buf = p; return true; @@ -351,14 +357,20 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory, char *error_buf, uint32 error_buf_size) { const uint8 *p = *p_buf, *p_end = buf_end; + uint32 pool_size = bh_memory_pool_size(); + uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT + / NumBytesPerPage; read_leb_uint32(p, p_end, memory->flags); read_leb_uint32(p, p_end, memory->init_page_count); - if (memory->flags & 1) + if (memory->flags & 1) { read_leb_uint32(p, p_end, memory->max_page_count); + if (memory->max_page_count > max_page_count) + memory->max_page_count = max_page_count; + } else - /* Limit the maximum memory size to 4GB */ - memory->max_page_count = 0x10000; + /* Limit the maximum memory size to max_page_count */ + memory->max_page_count = max_page_count; *p_buf = p; return true; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index b12256d37b..ebfe14b57d 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -163,6 +163,7 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count) if (memories[i]) { if (memories[i]->heap_handle) mem_allocator_destroy(memories[i]->heap_handle); + wasm_free(memories[i]->heap_data); wasm_free(memories[i]); } wasm_free(memories); @@ -177,10 +178,10 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count, { WASMMemoryInstance *memory; uint32 total_size = offsetof(WASMMemoryInstance, base_addr) + - NumBytesPerPage * init_page_count + - addr_data_size + global_data_size + - heap_size; + NumBytesPerPage * init_page_count + + addr_data_size + global_data_size; + /* Allocate memory space, addr data and global data */ if (!(memory = wasm_malloc(total_size))) { set_error_buf(error_buf, error_buf_size, "Instantiate memory failed: allocate memory failed."); @@ -190,28 +191,46 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count, memset(memory, 0, total_size); memory->cur_page_count = init_page_count; memory->max_page_count = max_page_count; + memory->addr_data = memory->base_addr; memory->addr_data_size = addr_data_size; memory->memory_data = memory->addr_data + addr_data_size; - memory->heap_data = memory->memory_data + - NumBytesPerPage * memory->cur_page_count;; - memory->heap_data_size = heap_size; - - memory->global_data = memory->heap_data + memory->heap_data_size; + memory->global_data = memory->memory_data + + NumBytesPerPage * memory->cur_page_count;; memory->global_data_size = global_data_size; memory->end_addr = memory->global_data + global_data_size; + /* Allocate heap space */ + if (!(memory->heap_data = wasm_malloc(heap_size))) { + set_error_buf(error_buf, error_buf_size, + "Instantiate memory failed: allocate memory failed."); + goto fail1; + } + memory->heap_data_end = memory->heap_data + heap_size; + /* Initialize heap */ if (!(memory->heap_handle = mem_allocator_create - (memory->heap_data, memory->heap_data_size))) { - wasm_free(memory); - return NULL; + (memory->heap_data, heap_size))) { + goto fail2; } +#if WASM_ENABLE_MEMORY_GROW != 0 + memory->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET; +#else + memory->heap_base_offset = memory->end_addr - memory->memory_data; +#endif + return memory; + +fail2: + wasm_free(memory->heap_data); + +fail1: + wasm_free(memory); + return NULL; } /** @@ -975,58 +994,65 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst) bool wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count) { -#if 1 - wasm_runtime_set_exception(module, "unsupported operation: enlarge memory."); - return false; -#else +#if WASM_ENABLE_MEMORY_GROW != 0 WASMMemoryInstance *memory = module->default_memory; WASMMemoryInstance *new_memory; uint32 total_page_count = inc_page_count + memory->cur_page_count; uint32 total_size = offsetof(WASMMemoryInstance, base_addr) + memory->addr_data_size + NumBytesPerPage * total_page_count + - memory->global_data_size + - memory->thunk_argv_data_size + - sizeof(uint32) * memory->thunk_argc; + memory->global_data_size; + + if (inc_page_count <= 0) + /* No need to enlarge memory */ + return true; + + if (total_page_count < memory->cur_page_count /* integer overflow */ + || total_page_count > memory->max_page_count) { + wasm_runtime_set_exception(module, "fail to enlarge memory."); + return false; + } if (!(new_memory = wasm_malloc(total_size))) { - wasm_runtime_set_exception(module, "alloc memory for enlarge memory failed."); + wasm_runtime_set_exception(module, "fail to enlarge memory."); return false; } new_memory->cur_page_count = total_page_count; - new_memory->max_page_count = memory->max_page_count > total_page_count - ? memory->max_page_count : total_page_count; + new_memory->max_page_count = memory->max_page_count; + new_memory->addr_data = new_memory->base_addr; new_memory->addr_data_size = memory->addr_data_size; - new_memory->thunk_argv_data = new_memory->addr_data + memory->addr_data_size; - new_memory->thunk_argv_data_size = memory->thunk_argv_data_size; - new_memory->thunk_argc = memory->thunk_argc; - new_memory->thunk_argv_offsets = new_memory->thunk_argv_data + - memory->thunk_argv_data_size; + new_memory->memory_data = new_memory->addr_data + new_memory->addr_data_size; - new_memory->memory_data = new_memory->thunk_argv_offsets + - sizeof(uint32) * memory->thunk_argc; new_memory->global_data = new_memory->memory_data + - NumBytesPerPage * new_memory->cur_page_count; + NumBytesPerPage * total_page_count; new_memory->global_data_size = memory->global_data_size; new_memory->end_addr = new_memory->global_data + memory->global_data_size; - /* Copy addr data, thunk argv data, thunk argv offsets and memory data */ + /* Copy addr data and memory data */ memcpy(new_memory->addr_data, memory->addr_data, memory->global_data - memory->addr_data); /* Copy global data */ memcpy(new_memory->global_data, memory->global_data, - memory->end_addr - memory->global_data); + memory->global_data_size); /* Init free space of new memory */ memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count, - 0, NumBytesPerPage * (total_page_count - memory->cur_page_count)); + 0, NumBytesPerPage * (total_page_count - memory->cur_page_count)); + + new_memory->heap_data = memory->heap_data; + new_memory->heap_data_end = memory->heap_data_end; + new_memory->heap_handle = memory->heap_handle; + new_memory->heap_base_offset = memory->heap_base_offset; - wasm_free(memory); module->memories[0] = module->default_memory = new_memory; + wasm_free(memory); return true; +#else + wasm_runtime_set_exception(module, "unsupported operation: enlarge memory."); + return false; #endif } @@ -1098,29 +1124,29 @@ wasm_runtime_get_current_module_inst() int32 wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size) { - uint8 *memory_base = module_inst->default_memory->memory_data; - void *heap = module_inst->default_memory->heap_handle; - uint8 *addr = mem_allocator_malloc(heap, size); - if (!addr) + WASMMemoryInstance *memory = module_inst->default_memory; + uint8 *addr = mem_allocator_malloc(memory->heap_handle, size); + if (!addr) { wasm_runtime_set_exception(module_inst, "out of memory"); - return addr ? addr - memory_base : 0; + return 0; + } + return memory->heap_base_offset + (addr - memory->heap_data); } void wasm_runtime_module_free(WASMModuleInstance *module_inst, int32 ptr) { - uint8 *memory_base = module_inst->default_memory->memory_data; - uint8 *heap_base = module_inst->default_memory->heap_data; - uint32 heap_size = module_inst->default_memory->heap_data_size; - void *heap = module_inst->default_memory->heap_handle; - uint8 *addr = ptr ? memory_base + ptr : NULL; - if (addr && (heap_base < addr && addr < heap_base + heap_size)) - mem_allocator_free(heap, addr); + if (ptr) { + WASMMemoryInstance *memory = module_inst->default_memory; + uint8 *addr = memory->heap_data + (ptr - memory->heap_base_offset); + if (memory->heap_data < addr && addr < memory->heap_data_end) + mem_allocator_free(memory->heap_handle, addr); + } } - int32 +int32 wasm_runtime_module_dup_data(WASMModuleInstance *module_inst, - const char *src, uint32 size) + const char *src, uint32 size) { int32 buffer_offset = wasm_runtime_module_malloc(module_inst, size); if (buffer_offset != 0) { @@ -1135,22 +1161,32 @@ bool wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst, int32 app_offset, uint32 size) { + WASMMemoryInstance *memory; + uint8 *addr; + /* integer overflow check */ if(app_offset < 0 || - app_offset + size < size) { - wasm_runtime_set_exception(module_inst, "out of bounds memory access"); - return false; + app_offset + size < app_offset) { + goto fail; } - uint8 *memory_base = module_inst->default_memory->memory_data; - uint8 *addr = memory_base + app_offset; - uint8 *base_addr = module_inst->default_memory->base_addr; - uint8 *end_addr = module_inst->default_memory->end_addr; - bool ret = (base_addr <= addr - && addr + size <= end_addr); - if (!ret) - wasm_runtime_set_exception(module_inst, "out of bounds memory access"); - return ret; + memory = module_inst->default_memory; + if (app_offset < memory->heap_base_offset) { + addr = memory->memory_data + app_offset; + if (!(memory->base_addr <= addr && addr + size <= memory->end_addr)) + goto fail; + return true; + } + else { + addr = memory->heap_data + (app_offset - memory->heap_base_offset); + if (!(memory->heap_data <= addr && addr + size <= memory->heap_data_end)) + goto fail; + return true; + } + +fail: + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; } bool @@ -1158,26 +1194,42 @@ wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst, void *native_ptr, uint32 size) { uint8 *addr = native_ptr; - uint8 *base_addr = module_inst->default_memory->base_addr; - uint8 *end_addr = module_inst->default_memory->end_addr; - bool ret = (base_addr <= addr && addr + size <= end_addr); - if (!ret || (addr + size < addr)/* integer overflow */) - wasm_runtime_set_exception(module_inst, "out of bounds memory access"); - return ret; + WASMMemoryInstance *memory = module_inst->default_memory; + + if (addr + size < addr) { + goto fail; + } + + if ((memory->base_addr <= addr && addr + size <= memory->end_addr) + || (memory->heap_data <= addr && addr + size <= memory->heap_data_end)) + return true; + +fail: + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; } void * wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst, int32 app_offset) { - return module_inst->default_memory->memory_data + app_offset; + WASMMemoryInstance *memory = module_inst->default_memory; + if (app_offset < memory->heap_base_offset) + return memory->memory_data + app_offset; + else + return memory->heap_data + (app_offset - memory->heap_base_offset); } int32 wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst, void *native_ptr) { - return (uint8*)native_ptr - module_inst->default_memory->memory_data; + WASMMemoryInstance *memory = module_inst->default_memory; + if ((uint8*)native_ptr < memory->heap_data) + return (uint8*)native_ptr - memory->memory_data; + else + return memory->heap_base_offset + + ((uint8*)native_ptr - memory->heap_data); } uint32 diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h index 649f8308da..56e806b94c 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h @@ -37,20 +37,14 @@ typedef struct WASMMemoryInstance { /* Size of addr_data */ uint32 addr_data_size; - /* Thunk data of argument strings */ - uint8 *thunk_argv_data; - uint32 thunk_argv_data_size; - /* Thunk argument count */ - uint32 thunk_argc; - /* Thunk argument offsets */ - uint8 *thunk_argv_offsets; - - /* Heap data */ + /* Heap data base address */ uint8 *heap_data; - /* Heap size */ - uint32 heap_data_size; + /* Heap data end address */ + uint8 *heap_data_end; /* The heap created */ void *heap_handle; + /* Heap base offset of wasm app */ + int32 heap_base_offset; /* Memory data */ uint8 *memory_data; @@ -63,7 +57,7 @@ typedef struct WASMMemoryInstance { /* Base address, the layout is: addr_data + thunk_argv data + thunk arg offsets + - heap data + memory data + global data + memory data + global data memory data init size is: NumBytesPerPage * cur_page_count addr data size and global data size is calculated in module instantiating Note: when memory is re-allocated, the addr data, thunk argv data, thunk diff --git a/core/shared-lib/include/bh_memory.h b/core/shared-lib/include/bh_memory.h index 51312cbf14..352137a347 100644 --- a/core/shared-lib/include/bh_memory.h +++ b/core/shared-lib/include/bh_memory.h @@ -52,6 +52,12 @@ int bh_memory_init_with_allocator(void *malloc_func, void *free_func); */ void bh_memory_destroy(); +/** + * Get the pool size of memory, if memory is initialized with allocator, + * return 1GB by default. + */ +int bh_memory_pool_size(); + #if BEIHAI_ENABLE_MEMORY_PROFILING == 0 /** diff --git a/core/shared-lib/include/config.h b/core/shared-lib/include/config.h index e1926a4bb8..0c270cbc70 100644 --- a/core/shared-lib/include/config.h +++ b/core/shared-lib/include/config.h @@ -80,6 +80,15 @@ #define WORKING_FLOW_HEAP_SIZE 0 */ +/* Support memory.grow opcode and enlargeMemory function */ +#define WASM_ENABLE_MEMORY_GROW 1 + +/* The max percentage of global heap that app memory space can grow */ +#define APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT 1 / 3 + +/* Default base offset of app heap space */ +#define DEFAULT_APP_HEAP_BASE_OFFSET (1 * BH_GB) + /* Default min/max heap size of each app */ #define APP_HEAP_SIZE_DEFAULT (8 * 1024) #define APP_HEAP_SIZE_MIN (2 * 1024) diff --git a/core/shared-lib/mem-alloc/bh_memory.c b/core/shared-lib/mem-alloc/bh_memory.c index 92b1fdd470..bca6970518 100644 --- a/core/shared-lib/mem-alloc/bh_memory.c +++ b/core/shared-lib/mem-alloc/bh_memory.c @@ -49,7 +49,9 @@ static korp_mutex profile_lock; #ifndef MALLOC_MEMORY_FROM_SYSTEM typedef enum Memory_Mode { - MEMORY_MODE_UNKNOWN = 0, MEMORY_MODE_POOL, MEMORY_MODE_ALLOCATOR + MEMORY_MODE_UNKNOWN = 0, + MEMORY_MODE_POOL, + MEMORY_MODE_ALLOCATOR } Memory_Mode; static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN; @@ -59,6 +61,8 @@ static mem_allocator_t pool_allocator = NULL; static void *(*malloc_func)(unsigned int size) = NULL; static void (*free_func)(void *ptr) = NULL; +static unsigned int global_pool_size; + int bh_memory_init_with_pool(void *mem, unsigned int bytes) { mem_allocator_t _allocator = mem_allocator_create(mem, bytes); @@ -69,6 +73,7 @@ int bh_memory_init_with_pool(void *mem, unsigned int bytes) #if BEIHAI_ENABLE_MEMORY_PROFILING != 0 vm_mutex_init(&profile_lock); #endif + global_pool_size = bytes; return 0; } printf("Init memory with pool (%p, %u) failed.\n", mem, bytes); @@ -101,6 +106,14 @@ void bh_memory_destroy() memory_mode = MEMORY_MODE_UNKNOWN; } +int bh_memory_pool_size() +{ + if (memory_mode == MEMORY_MODE_POOL) + return global_pool_size; + else + return 1 * BH_GB; +} + void* bh_malloc_internal(unsigned int size) { if (memory_mode == MEMORY_MODE_UNKNOWN) { diff --git a/core/shared-lib/platform/linux/bh_thread.c b/core/shared-lib/platform/linux/bh_thread.c index 201c9b5e68..d2cdd087c8 100755 --- a/core/shared-lib/platform/linux/bh_thread.c +++ b/core/shared-lib/platform/linux/bh_thread.c @@ -75,7 +75,7 @@ static void *vm_thread_wrapper(void *arg) { thread_wrapper_arg * targ = arg; LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ); - targ->stack = (void *) ((unsigned int) (&arg) & ~0xfff); + targ->stack = (void *)((uintptr_t)(&arg) & ~0xfff); _vm_tls_put(1, targ); targ->start(targ->arg); bh_free(targ); From 177218332506d9183af6028ef2e88092d9554a49 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Tue, 11 Jun 2019 10:43:12 +0800 Subject: [PATCH 03/18] Add a new extension library: connection --- README.md | 27 +- core/app-mgr/app-manager/module_wasm_app.h | 6 +- core/iwasm/lib/app-libs/base/wasm_app.h | 1 + .../extension/connection/connection.c | 130 ++++ .../extension/connection/connection.h | 106 ++++ .../lib/native-interface/connection_api.h | 38 ++ .../lib/native-interface/native_interface.h | 12 +- .../extension/connection/connection.inl | 20 + .../extension/connection/connection_lib.h | 86 +++ .../extension/connection/connection_wrapper.c | 84 +++ .../extension/connection/linux/conn_tcp.c | 62 ++ .../extension/connection/linux/conn_tcp.h | 37 ++ .../extension/connection/linux/conn_uart.c | 110 ++++ .../extension/connection/linux/conn_uart.h | 37 ++ .../extension/connection/linux/conn_udp.c | 68 +++ .../extension/connection/linux/conn_udp.h | 37 ++ .../connection/linux/connection_mgr.c | 572 ++++++++++++++++++ .../connection/linux/connection_mgr.cmake | 24 + .../extension/connection/wasm_lib_conn.cmake | 23 + .../connection/zephyr/connection_lib_impl.c | 34 ++ core/shared-lib/include/config.h | 3 + .../littlevgl/vgl-wasm-runtime/CMakeLists.txt | 4 + .../vgl-wasm-runtime/src/ext_lib_export.c | 3 + .../src/platform/linux/iwasm_main.c | 7 + .../zephyr-build/CMakeLists.txt | 3 + samples/littlevgl/wasm-apps/Makefile_wasm_app | 17 +- samples/simple/CMakeLists.txt | 4 + samples/simple/README.md | 26 +- samples/simple/build.sh | 63 +- samples/simple/src/ext_lib_export.c | 2 + samples/simple/src/iwasm_main.c | 8 +- samples/simple/wasm-apps/connection.c | 93 +++ .../{event_publisher => }/event_publisher.c | 0 .../{event_subscriber => }/event_subscriber.c | 0 .../{request_handler => }/request_handler.c | 0 .../{request_sender => }/request_sender.c | 0 .../simple/wasm-apps/{sensor => }/sensor.c | 0 samples/simple/wasm-apps/{timer => }/timer.c | 0 38 files changed, 1677 insertions(+), 70 deletions(-) create mode 100644 core/iwasm/lib/app-libs/extension/connection/connection.c create mode 100644 core/iwasm/lib/app-libs/extension/connection/connection.h create mode 100644 core/iwasm/lib/native-interface/connection_api.h create mode 100644 core/iwasm/lib/native/extension/connection/connection.inl create mode 100644 core/iwasm/lib/native/extension/connection/connection_lib.h create mode 100644 core/iwasm/lib/native/extension/connection/connection_wrapper.c create mode 100644 core/iwasm/lib/native/extension/connection/linux/conn_tcp.c create mode 100644 core/iwasm/lib/native/extension/connection/linux/conn_tcp.h create mode 100644 core/iwasm/lib/native/extension/connection/linux/conn_uart.c create mode 100644 core/iwasm/lib/native/extension/connection/linux/conn_uart.h create mode 100644 core/iwasm/lib/native/extension/connection/linux/conn_udp.c create mode 100644 core/iwasm/lib/native/extension/connection/linux/conn_udp.h create mode 100644 core/iwasm/lib/native/extension/connection/linux/connection_mgr.c create mode 100644 core/iwasm/lib/native/extension/connection/linux/connection_mgr.cmake create mode 100644 core/iwasm/lib/native/extension/connection/wasm_lib_conn.cmake create mode 100644 core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c create mode 100644 samples/simple/wasm-apps/connection.c rename samples/simple/wasm-apps/{event_publisher => }/event_publisher.c (100%) rename samples/simple/wasm-apps/{event_subscriber => }/event_subscriber.c (100%) rename samples/simple/wasm-apps/{request_handler => }/request_handler.c (100%) rename samples/simple/wasm-apps/{request_sender => }/request_sender.c (100%) rename samples/simple/wasm-apps/{sensor => }/sensor.c (100%) rename samples/simple/wasm-apps/{timer => }/timer.c (100%) diff --git a/README.md b/README.md index fed5aa90a0..a687f6dec0 100644 --- a/README.md +++ b/README.md @@ -339,12 +339,35 @@ void api_timer_restart(user_timer_t timer, int interval); Currently we provide the sensor API's as one library extension sample. In the header file ```lib/app-libs/extension/sensor/sensor.h```, the API set is defined as below: ``` C sensor_t sensor_open(const char* name, int index, - void(*on_sensor_event)(sensor_t, attr_container_t *, void *), - void *user_data); + void(*on_sensor_event)(sensor_t, attr_container_t *, void *), + void *user_data); bool sensor_config(sensor_t sensor, int interval, int bit_cfg, int delay); bool sensor_config_with_attr_container(sensor_t sensor, attr_container_t *cfg); bool sensor_close(sensor_t sensor); ``` +We provide the connection API's as another sample. In the header file `lib/app-libs/extension/connection/connection.h.`, the API set is defined as below: +``` C +/* Connection event type */ +typedef enum { + /* Data is received */ + CONN_EVENT_TYPE_DATA = 1, + /* Connection is disconnected */ + CONN_EVENT_TYPE_DISCONNECT +} conn_event_type_t; + +typedef void (*on_connection_event_f)(connection_t *conn, + conn_event_type_t type, + const char *data, + uint32 len, + void *user_data); +connection_t *api_open_connection(const char *name, + attr_container_t *args, + on_connection_event_f on_event, + void *user_data); +void api_close_connection(connection_t *conn); +int api_send_on_connection(connection_t *conn, const char *data, uint32 len); +bool api_config_connection(connection_t *conn, attr_container_t *cfg); +``` The mechanism of exporting native API to WASM application ======================================================= diff --git a/core/app-mgr/app-manager/module_wasm_app.h b/core/app-mgr/app-manager/module_wasm_app.h index dbdf805270..e63a6d3c9f 100644 --- a/core/app-mgr/app-manager/module_wasm_app.h +++ b/core/app-mgr/app-manager/module_wasm_app.h @@ -39,8 +39,10 @@ extern "C" { #define SECTION_TYPE_DATA 11 enum { - WASM_Msg_Start = BASE_EVENT_MAX, TIMER_EVENT_WASM, SENSOR_EVENT_WASM, - + WASM_Msg_Start = BASE_EVENT_MAX, + TIMER_EVENT_WASM, + SENSOR_EVENT_WASM, + CONNECTION_EVENT_WASM, WASM_Msg_End = WASM_Msg_Start + 100 }; diff --git a/core/iwasm/lib/app-libs/base/wasm_app.h b/core/iwasm/lib/app-libs/base/wasm_app.h index 03c8460ba9..0aa223c65c 100644 --- a/core/iwasm/lib/app-libs/base/wasm_app.h +++ b/core/iwasm/lib/app-libs/base/wasm_app.h @@ -37,6 +37,7 @@ #include "attr_container.h" #include "request.h" #include "sensor.h" +#include "connection.h" #include "timer_wasm_app.h" #ifdef __cplusplus diff --git a/core/iwasm/lib/app-libs/extension/connection/connection.c b/core/iwasm/lib/app-libs/extension/connection/connection.c new file mode 100644 index 0000000000..1c7845d4b6 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/connection/connection.c @@ -0,0 +1,130 @@ +/* + * 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 "connection.h" +#include "native_interface.h" + +/* Raw connection structure */ +typedef struct _connection { + /* Next connection */ + struct _connection *next; + + /* Handle of the connection */ + uint32 handle; + + /* Callback function called when event on this connection occurs */ + on_connection_event_f on_event; + + /* User data */ + void *user_data; +} connection_t; + +/* Raw connections list */ +static connection_t *g_conns = NULL; + +connection_t *api_open_connection(const char *name, + attr_container_t *args, + on_connection_event_f on_event, + void *user_data) +{ + connection_t *conn; + char *args_buffer = (char *)args; + uint32 handle, args_len = attr_container_get_serialize_length(args); + + handle = wasm_open_connection((int32)name, (int32)args_buffer, args_len); + if (handle == -1) + return NULL; + + conn = (connection_t *)malloc(sizeof(*conn)); + if (conn == NULL) { + wasm_close_connection(handle); + return NULL; + } + + memset(conn, 0, sizeof(*conn)); + conn->handle = handle; + conn->on_event = on_event; + conn->user_data = user_data; + + if (g_conns != NULL) { + conn->next = g_conns; + g_conns = conn; + } else { + g_conns = conn; + } + + return conn; +} + +void api_close_connection(connection_t *c) +{ + connection_t *conn = g_conns, *prev = NULL; + + while (conn) { + if (conn == c) { + wasm_close_connection(c->handle); + if (prev != NULL) + prev->next = conn->next; + else + g_conns = conn->next; + free(conn); + return; + } else { + prev = conn; + conn = conn->next; + } + } +} + +int api_send_on_connection(connection_t *conn, const char *data, uint32 len) +{ + return wasm_send_on_connection(conn->handle, (int32)data, len); +} + +bool api_config_connection(connection_t *conn, attr_container_t *cfg) +{ + char *cfg_buffer = (char *)cfg; + uint32 cfg_len = attr_container_get_serialize_length(cfg); + + return wasm_config_connection(conn->handle, (int32)cfg_buffer, cfg_len); +} + +void on_connection_data(uint32 handle, char *buffer, uint32 len) +{ + connection_t *conn = g_conns; + + while (conn != NULL) { + if (conn->handle == handle) { + if (len == 0) { + conn->on_event(conn, + CONN_EVENT_TYPE_DISCONNECT, + NULL, + 0, + conn->user_data); + } else { + conn->on_event(conn, + CONN_EVENT_TYPE_DATA, + buffer, + len, + conn->user_data); + } + + return; + } + conn = conn->next; + } +} + diff --git a/core/iwasm/lib/app-libs/extension/connection/connection.h b/core/iwasm/lib/app-libs/extension/connection/connection.h new file mode 100644 index 0000000000..d87352a2bc --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/connection/connection.h @@ -0,0 +1,106 @@ +/* + * 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 _CONNECTION_H_ +#define _CONNECTION_H_ + +#include "attr_container.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct _connection; +typedef struct _connection connection_t; + +/* Connection event type */ +typedef enum { + /* Data is received */ + CONN_EVENT_TYPE_DATA = 1, + /* Connection is disconnected */ + CONN_EVENT_TYPE_DISCONNECT +} conn_event_type_t; + +/* + * @typedef on_connection_event_f + * + * @param conn the connection that the event belongs to + * @param type event type + * @param data the data received for CONN_EVENT_TYPE_DATA event + * @param len length of the data in byte + * @param user_data user data + */ +typedef void (*on_connection_event_f)(connection_t *conn, + conn_event_type_t type, + const char *data, + uint32 len, + void *user_data); + +/* + ***************** + * Connection API's + ***************** + */ + +/* + * @brief Open a connection. + * + * @param name name of the connection, "TCP", "UDP" or "UART" + * @param args connection arguments, such as: ip:127.0.0.1, port:8888 + * @param on_event callback function called when event occurs + * @param user_data user data + * + * @return the connection or NULL means fail + */ +connection_t *api_open_connection(const char *name, + attr_container_t *args, + on_connection_event_f on_event, + void *user_data); + +/* + * @brief Close a connection. + * + * @param conn connection + */ +void api_close_connection(connection_t *conn); + +/* + * Send data to the connection in non-blocking manner which returns immediately + * + * @param conn the connection + * @param data data buffer to be sent + * @param len length of the data in byte + * + * @return actual length sent, or -1 if fail(maybe underlying buffer is full) + */ +int api_send_on_connection(connection_t *conn, const char *data, uint32 len); + +/* + * @brief Configure connection. + * + * @param conn the connection + * @param cfg configurations + * + * @return true if success, false otherwise + */ +bool api_config_connection(connection_t *conn, attr_container_t *cfg); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/iwasm/lib/native-interface/connection_api.h b/core/iwasm/lib/native-interface/connection_api.h new file mode 100644 index 0000000000..f55583bd9e --- /dev/null +++ b/core/iwasm/lib/native-interface/connection_api.h @@ -0,0 +1,38 @@ +/* + * 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 CONNECTION_API_H_ +#define CONNECTION_API_H_ +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len); + +void wasm_close_connection(uint32 handle); + +int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len); + +bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len); + +#ifdef __cplusplus +} +#endif + + +#endif /* CONNECTION_API_H_ */ diff --git a/core/iwasm/lib/native-interface/native_interface.h b/core/iwasm/lib/native-interface/native_interface.h index a538330b78..a3c022d100 100644 --- a/core/iwasm/lib/native-interface/native_interface.h +++ b/core/iwasm/lib/native-interface/native_interface.h @@ -75,4 +75,14 @@ void wasm_timer_destory(timer_id_t timer_id); void wasm_timer_cancel(timer_id_t timer_id); void wasm_timer_restart(timer_id_t timer_id, int interval); uint32 wasm_get_sys_tick_ms(void); -#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ */ + +/* + * *** connection interface *** + */ +uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len); +void wasm_close_connection(uint32 handle); +int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len); +bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len); + +#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_PO +C_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ */ diff --git a/core/iwasm/lib/native/extension/connection/connection.inl b/core/iwasm/lib/native/extension/connection/connection.inl new file mode 100644 index 0000000000..e736650931 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/connection.inl @@ -0,0 +1,20 @@ +/* +* 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. +*/ + +EXPORT_WASM_API(wasm_open_connection), +EXPORT_WASM_API(wasm_close_connection), +EXPORT_WASM_API(wasm_send_on_connection), +EXPORT_WASM_API(wasm_config_connection), diff --git a/core/iwasm/lib/native/extension/connection/connection_lib.h b/core/iwasm/lib/native/extension/connection/connection_lib.h new file mode 100644 index 0000000000..49d2e3970b --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/connection_lib.h @@ -0,0 +1,86 @@ +/* + * 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 CONNECTION_LIB_H_ +#define CONNECTION_LIB_H_ + +#include "attr_container.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ***************** + * This file defines connection library which should be implemented by different platforms + ***************** + */ + +/* + * @brief Open a connection. + * + * @param name name of the connection, "TCP", "UDP" or "UART" + * @param args connection arguments, such as: ip:127.0.0.1, port:8888 + * + * @return 0~0xFFFFFFFE means id of the connection, otherwise(-1) means fail + */ +typedef uint32 (*connection_open_f)(const char *name, attr_container_t *args); + +/* + * @brief Close a connection. + * + * @param handle of the connection + */ +typedef void (*connection_close_f)(uint32 handle); + +/* + * @brief Send data to the connection in non-blocking manner. + * + * @param handle of the connection + * @param data data buffer to be sent + * @param len length of the data in byte + * + * @return actual length sent, -1 if fail + */ +typedef int (*connection_send_f)(uint32 handle, const char *data, int len); + +/* + * @brief Configure connection. + * + * @param handle of the connection + * @param cfg configurations + * + * @return true if success, false otherwise + */ +typedef bool (*connection_config_f)(uint32 handle, attr_container_t *cfg); + +/* Raw connection interface for platform to implement */ +typedef struct _connection_interface { + connection_open_f _open; + connection_close_f _close; + connection_send_f _send; + connection_config_f _config; +} connection_interface_t; + +/* Platform must define this interface */ +extern connection_interface_t connection_impl; + +#ifdef __cplusplus +} +#endif + + +#endif /* CONNECTION_LIB_H_ */ diff --git a/core/iwasm/lib/native/extension/connection/connection_wrapper.c b/core/iwasm/lib/native/extension/connection/connection_wrapper.c new file mode 100644 index 0000000000..7bcf5860d1 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/connection_wrapper.c @@ -0,0 +1,84 @@ +/* + * 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 "connection_lib.h" +#include "wasm_export.h" +#include "native_interface.h" + +/* Note: + * + * This file is the consumer of connection lib which is implemented by different platforms + */ + + +uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + attr_container_t *args; + char *name, *args_buf; + + if (!validate_app_addr(name_offset, 1) || + !validate_app_addr(args_offset, len) || + !(name = addr_app_to_native(name_offset)) || + !(args_buf = addr_app_to_native(args_offset))) + return -1; + + args = (attr_container_t *)args_buf; + + if (connection_impl._open != NULL) + return connection_impl._open(name, args); + + return -1; +} + +void wasm_close_connection(uint32 handle) +{ + if (connection_impl._close != NULL) + connection_impl._close(handle); +} + +int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + char *data; + + if (!validate_app_addr(data_offset, len) || + !(data = addr_app_to_native(data_offset))) + return -1; + + if (connection_impl._send != NULL) + return connection_impl._send(handle, data, len); + + return -1; +} + +bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + char *cfg_buf; + attr_container_t *cfg; + + if (!validate_app_addr(cfg_offset, len) || + !(cfg_buf = addr_app_to_native(cfg_offset))) + return false; + + cfg = (attr_container_t *)cfg_buf; + + if (connection_impl._config != NULL) + return connection_impl._config(handle, cfg); + + return false; +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_tcp.c b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.c new file mode 100644 index 0000000000..3a6bded260 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.c @@ -0,0 +1,62 @@ +/* + * 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 "conn_tcp.h" + +#include +#include +#include +#include +#include + +int tcp_open(char *address, uint16 port) +{ + int sock, ret; + struct sockaddr_in servaddr; + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr(address); + servaddr.sin_port = htons(port); + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == -1) + return -1; + + ret = connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)); + if (ret == -1) { + close(sock); + return -1; + } + + /* Put the socket in non-blocking mode */ + if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { + close(sock); + return -1; + } + + return sock; +} + +int tcp_send(int sock, const char *data, int size) +{ + return send(sock, data, size, 0); +} + +int tcp_recv(int sock, char *buffer, int buf_size) +{ + return recv(sock, buffer, buf_size, 0); +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_tcp.h b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.h new file mode 100644 index 0000000000..84caf2a131 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.h @@ -0,0 +1,37 @@ +/* + * 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 CONN_LINUX_TCP_H_ +#define CONN_LINUX_TCP_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int tcp_open(char *address, uint16 port); + +int tcp_send(int sock, const char *data, int size); + +int tcp_recv(int sock, char *buffer, int buf_size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_uart.c b/core/iwasm/lib/native/extension/connection/linux/conn_uart.c new file mode 100644 index 0000000000..6ca848b6ed --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_uart.c @@ -0,0 +1,110 @@ +/* + * 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 "conn_uart.h" + +#include +#include +#include + +static int parse_baudrate(int baud) +{ + switch (baud) { + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + case 230400: + return B230400; + case 460800: + return B460800; + case 500000: + return B500000; + case 576000: + return B576000; + case 921600: + return B921600; + case 1000000: + return B1000000; + case 1152000: + return B1152000; + case 1500000: + return B1500000; + case 2000000: + return B2000000; + case 2500000: + return B2500000; + case 3000000: + return B3000000; + case 3500000: + return B3500000; + case 4000000: + return B4000000; + default: + return -1; + } +} + +int uart_open(char* device, int baudrate) +{ + int uart_fd; + struct termios uart_term; + + uart_fd = open(device, O_RDWR | O_NOCTTY); + + if (uart_fd <= 0) + return -1; + + memset(&uart_term, 0, sizeof(uart_term)); + uart_term.c_cflag = parse_baudrate(baudrate) | CS8 | CLOCAL | CREAD; + uart_term.c_iflag = IGNPAR; + uart_term.c_oflag = 0; + + /* set noncanonical mode */ + uart_term.c_lflag = 0; + uart_term.c_cc[VTIME] = 30; + uart_term.c_cc[VMIN] = 1; + tcflush(uart_fd, TCIFLUSH); + + if (tcsetattr(uart_fd, TCSANOW, &uart_term) != 0) { + close(uart_fd); + return -1; + } + + /* Put the fd in non-blocking mode */ + if (fcntl(uart_fd, F_SETFL, fcntl(uart_fd, F_GETFL) | O_NONBLOCK) < 0) { + close(uart_fd); + return -1; + } + + return uart_fd; +} + +int uart_send(int fd, const char *data, int size) +{ + return write(fd, data, size); +} + +int uart_recv(int fd, char *buffer, int buf_size) +{ + return read(fd, buffer, buf_size); +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_uart.h b/core/iwasm/lib/native/extension/connection/linux/conn_uart.h new file mode 100644 index 0000000000..1e67811d64 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_uart.h @@ -0,0 +1,37 @@ +/* + * 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 CONN_LINUX_UART_H_ +#define CONN_LINUX_UART_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int uart_open(char* device, int baudrate); + +int uart_send(int fd, const char *data, int size); + +int uart_recv(int fd, char *buffer, int buf_size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_udp.c b/core/iwasm/lib/native/extension/connection/linux/conn_udp.c new file mode 100644 index 0000000000..d93c23f8ca --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_udp.c @@ -0,0 +1,68 @@ +/* + * 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 "conn_udp.h" + +#include +#include +#include +#include +#include + +int udp_open(uint16 port) +{ + int sock, ret; + struct sockaddr_in addr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + return -1; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + ret = bind(sock, (struct sockaddr*)&addr, sizeof(addr)); + if (ret == -1) + return -1; + + /* Put the socket in non-blocking mode */ + if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { + close(sock); + return -1; + } + + return sock; +} + +int udp_send(int sock, struct sockaddr *dest, const char *data, int size) +{ + return sendto(sock, data, size, MSG_CONFIRM, dest, sizeof(*dest)); +} + +int udp_recv(int sock, char *buffer, int buf_size) +{ + struct sockaddr_in remaddr; + socklen_t addrlen = sizeof(remaddr); + + return recvfrom(sock, + buffer, + buf_size, + 0, + (struct sockaddr *)&remaddr, + &addrlen); +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_udp.h b/core/iwasm/lib/native/extension/connection/linux/conn_udp.h new file mode 100644 index 0000000000..f3cbf4b199 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_udp.h @@ -0,0 +1,37 @@ +/* + * 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 CONN_LINUX_UDP_H_ +#define CONN_LINUX_UDP_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int udp_open(uint16 port); + +int udp_send(int sock, struct sockaddr *dest, const char *data, int size); + +int udp_recv(int sock, char *buffer, int buf_size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/core/iwasm/lib/native/extension/connection/linux/connection_mgr.c b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.c new file mode 100644 index 0000000000..27c18cd775 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.c @@ -0,0 +1,572 @@ +/* + * 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. + */ + +/* + * Note: + * This file implements the linux version connection library which is + * defined in connection_lib.h. + * It also provides a reference implementation of connections manager. + */ + +#include "connection_lib.h" +#include "bh_thread.h" +#include "app_manager_export.h" +#include "module_wasm_app.h" +#include "conn_tcp.h" +#include "conn_udp.h" +#include "conn_uart.h" +#include "bh_definition.h" + +#include +#include +#include +#include +#include + +#define MAX_EVENTS 10 +#define IO_BUF_SIZE 256 + +/* Connection type */ +typedef enum conn_type { + CONN_TYPE_TCP, + CONN_TYPE_UDP, + CONN_TYPE_UART, + CONN_TYPE_UNKNOWN +} conn_type_t; + +/* Sys connection */ +typedef struct sys_connection { + /* Next connection */ + struct sys_connection *next; + + /* Type */ + conn_type_t type; + + /* Handle to interact with wasm app */ + uint32 handle; + + /* Underlying connection ID, may be socket fd */ + int fd; + + /* Module id that the connection belongs to */ + uint32 module_id; + + /* Argument, such as dest addr for udp */ + void *arg; +} sys_connection_t; + +/* Epoll instance */ +static int epollfd; + +/* Connections list */ +static sys_connection_t *g_connections = NULL; + +/* Max handle */ +static uint32 g_handle_max = 0; + +/* Lock to protect g_connections and g_handle_max */ +static korp_mutex g_lock; + +/* Epoll events */ +static struct epoll_event epoll_events[MAX_EVENTS]; + +/* Buffer to receive data */ +static char io_buf[IO_BUF_SIZE]; + +static uint32 _conn_open(const char *name, attr_container_t *args); +static void _conn_close(uint32 handle); +static int _conn_send(uint32 handle, const char *data, int len); +static bool _conn_config(uint32 handle, attr_container_t *cfg); + +/* + * Platform implementation of connection library + */ +connection_interface_t connection_impl = { + ._open = _conn_open, + ._close = _conn_close, + ._send = _conn_send, + ._config = _conn_config +}; + +static void add_connection(sys_connection_t *conn) +{ + vm_mutex_lock(&g_lock); + + g_handle_max++; + if (g_handle_max == -1) + g_handle_max++; + conn->handle = g_handle_max; + + if (g_connections) { + conn->next = g_connections; + g_connections = conn; + } else { + g_connections = conn; + } + + vm_mutex_unlock(&g_lock); +} + +#define FREE_CONNECTION(conn) do { \ + if (conn->arg) \ + bh_free(conn->arg); \ + bh_free(conn); \ +} while (0) + +static int get_app_conns_num(uint32 module_id) +{ + sys_connection_t *conn; + int num = 0; + + vm_mutex_lock(&g_lock); + + conn = g_connections; + while (conn) { + if (conn->module_id == module_id) + num++; + conn = conn->next; + } + + vm_mutex_unlock(&g_lock); + + return num; +} + +static sys_connection_t *find_connection(uint32 handle, bool remove_found) +{ + sys_connection_t *conn, *prev = NULL; + + vm_mutex_lock(&g_lock); + + conn = g_connections; + while (conn) { + if (conn->handle == handle) { + if (remove_found) { + if (prev != NULL) { + prev->next = conn->next; + } else { + g_connections = conn->next; + } + } + vm_mutex_unlock(&g_lock); + return conn; + } else { + prev = conn; + conn = conn->next; + } + } + + vm_mutex_unlock(&g_lock); + + return NULL; +} + +static void cleanup_connections(uint32 module_id) +{ + sys_connection_t *conn, *prev = NULL; + + vm_mutex_lock(&g_lock); + + conn = g_connections; + while (conn) { + if (conn->module_id == module_id) { + epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL); + close(conn->fd); + + if (prev != NULL) { + prev->next = conn->next; + FREE_CONNECTION(conn); + conn = prev->next; + } else { + g_connections = conn->next; + FREE_CONNECTION(conn); + conn = g_connections; + } + } else { + prev = conn; + conn = conn->next; + } + } + + vm_mutex_unlock(&g_lock); +} + +static conn_type_t get_conn_type(const char *name) +{ + if (strcmp(name, "TCP") == 0) + return CONN_TYPE_TCP; + if (strcmp(name, "UDP") == 0) + return CONN_TYPE_UDP; + if (strcmp(name, "UART") == 0) + return CONN_TYPE_UART; + + return CONN_TYPE_UNKNOWN; +} + +/* --- connection lib function --- */ +static uint32 _conn_open(const char *name, attr_container_t *args) +{ + int fd; + sys_connection_t *conn; + struct epoll_event ev; + uint32 module_id = app_manager_get_module_id(Module_WASM_App); + + if (get_app_conns_num(module_id) >= MAX_CONNECTION_PER_APP) + return -1; + + conn = (sys_connection_t *)bh_malloc(sizeof(*conn)); + if (conn == NULL) + return -1; + + memset(conn, 0, sizeof(*conn)); + conn->module_id = module_id; + conn->type = get_conn_type(name); + + /* Generate a handle and add to list */ + add_connection(conn); + + if (conn->type == CONN_TYPE_TCP) { + char *address; + uint16 port; + + /* Check and parse connection parameters */ + if (!attr_container_contain_key(args, "address") || + !attr_container_contain_key(args, "port")) + goto fail; + + address = attr_container_get_as_string(args, "address"); + port = attr_container_get_as_uint16(args, "port"); + + /* Connect to TCP server */ + if ((fd = tcp_open(address, port)) == -1) + goto fail; + + } else if (conn->type == CONN_TYPE_UDP) { + uint16 port; + + /* Check and parse connection parameters */ + if (!attr_container_contain_key(args, "bind port")) + goto fail; + port = attr_container_get_as_uint16(args, "bind port"); + + /* Bind port */ + if ((fd = udp_open(port)) == -1) + goto fail; + + } else if (conn->type == CONN_TYPE_UART) { + char *device; + int baud; + + /* Check and parse connection parameters */ + if (!attr_container_contain_key(args, "device") || + !attr_container_contain_key(args, "baudrate")) + goto fail; + device = attr_container_get_as_string(args, "device"); + baud = attr_container_get_as_int(args, "baudrate"); + + /* Open device */ + if ((fd = uart_open(device, baud)) == -1) + goto fail; + + } + + conn->fd = fd; + + /* Set current connection as event data */ + ev.events = EPOLLIN; + ev.data.ptr = conn; + + /* Monitor incoming data */ + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { + close(fd); + goto fail; + } + + return conn->handle; + +fail: + find_connection(conn->handle, true); + bh_free(conn); + return -1; +} + +/* --- connection lib function --- */ +static void _conn_close(uint32 handle) +{ + sys_connection_t *conn = find_connection(handle, true); + + if (conn != NULL) { + epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL); + close(conn->fd); + FREE_CONNECTION(conn); + } +} + +/* --- connection lib function --- */ +static int _conn_send(uint32 handle, const char *data, int len) +{ + sys_connection_t *conn = find_connection(handle, false); + + if (conn == NULL) + return -1; + + if (conn->type == CONN_TYPE_TCP) + return tcp_send(conn->fd, data, len); + + if (conn->type == CONN_TYPE_UDP) { + struct sockaddr *addr = (struct sockaddr *)conn->arg; + return udp_send(conn->fd, addr, data, len); + } + + if (conn->type == CONN_TYPE_UART) + return uart_send(conn->fd, data, len); + + return -1; +} + +/* --- connection lib function --- */ +static bool _conn_config(uint32 handle, attr_container_t *cfg) +{ + sys_connection_t *conn = find_connection(handle, false); + + if (conn == NULL) + return false; + + if (conn->type == CONN_TYPE_UDP) { + char *address; + uint16_t port; + struct sockaddr_in *addr; + + /* Parse remote address/port */ + if (!attr_container_contain_key(cfg, "address") || + !attr_container_contain_key(cfg, "port")) + return false; + address = attr_container_get_as_string(cfg, "address"); + port = attr_container_get_as_uint16(cfg, "port"); + + if (conn->arg == NULL) { + addr = (struct sockaddr_in *)bh_malloc(sizeof(*addr)); + if (addr == NULL) + return false; + + memset(addr, 0, sizeof(*addr)); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(address); + addr->sin_port = htons(port); + + /* Set remote address as connection arg */ + conn->arg = addr; + } else { + addr = (struct sockaddr_in *)conn->arg; + addr->sin_addr.s_addr = inet_addr(address); + addr->sin_port = htons(port); + } + + return true; + } + + return false; +} + +/* --- connection manager reference implementation ---*/ + +typedef struct connection_event { + uint32 handle; + char *data; + uint32 len; +} connection_event_t; + +static void connection_event_cleaner(connection_event_t *conn_event) +{ + if (conn_event->data != NULL) + bh_free(conn_event->data); + bh_free(conn_event); +} + +static void post_msg_to_module(sys_connection_t *conn, + char *data, + uint32 len) +{ + module_data *module = module_data_list_lookup_id(conn->module_id); + char *data_copy = NULL; + connection_event_t *conn_data_event; + bh_message_t msg; + + if (module == NULL) + return; + + conn_data_event = (connection_event_t *)bh_malloc(sizeof(*conn_data_event)); + if (conn_data_event == NULL) + return; + + if (len > 0) { + data_copy = (char *)bh_malloc(len); + if (data_copy == NULL) { + bh_free(conn_data_event); + return; + } + memcpy(data_copy, data, len); + } + + memset(conn_data_event, 0, sizeof(*conn_data_event)); + conn_data_event->handle = conn->handle; + conn_data_event->data = data_copy; + conn_data_event->len = len; + + msg = bh_new_msg(CONNECTION_EVENT_WASM, + conn_data_event, + sizeof(*conn_data_event), + connection_event_cleaner); + if (!msg) { + connection_event_cleaner(conn_data_event); + return; + } + + bh_post_msg2(module->queue, msg); +} + +static void* polling_thread_routine (void *arg) +{ + while (true) { + int i, n; + + n = epoll_wait(epollfd, epoll_events, MAX_EVENTS, -1); + + if (n == -1 && errno != EINTR) + continue; + + for (i = 0; i < n; i++) { + sys_connection_t *conn + = (sys_connection_t *)epoll_events[i].data.ptr; + + if (conn->type == CONN_TYPE_TCP) { + int count = tcp_recv(conn->fd, io_buf, IO_BUF_SIZE); + if (count <= 0) { + /* Connection is closed by peer */ + post_msg_to_module(conn, NULL, 0); + _conn_close(conn->handle); + } else { + /* Data is received */ + post_msg_to_module(conn, io_buf, count); + } + } else if (conn->type == CONN_TYPE_UDP) { + int count = udp_recv(conn->fd, io_buf, IO_BUF_SIZE); + if (count > 0) + post_msg_to_module(conn, io_buf, count); + } else if (conn->type == CONN_TYPE_UART) { + int count = uart_recv(conn->fd, io_buf, IO_BUF_SIZE); + if (count > 0) + post_msg_to_module(conn, io_buf, count); + } + } + } + + return NULL; +} + +void app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg) +{ + uint32 argv[3]; + wasm_function_inst_t func_on_conn_data; + bh_assert(CONNECTION_EVENT_WASM == bh_message_type(msg)); + wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data; + wasm_module_inst_t inst = wasm_app_data->wasm_module_inst; + connection_event_t *conn_event + = (connection_event_t *)bh_message_payload(msg); + int32 data_offset; + + if (conn_event == NULL) + return; + + func_on_conn_data = wasm_runtime_lookup_function(inst, "_on_connection_data", + "(i32i32i32)"); + if (!func_on_conn_data) { + printf("Cannot find function _on_connection_data\n"); + return; + } + + /* 0 len means connection closed */ + if (conn_event->len == 0) { + argv[0] = conn_event->handle; + argv[1] = 0; + argv[2] = 0; + if (!wasm_runtime_call_wasm(inst, NULL, func_on_conn_data, 3, argv)) { + printf(":Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + return; + } + } else { + data_offset = wasm_runtime_module_dup_data(inst, + conn_event->data, + conn_event->len); + if (data_offset == 0) { + printf("Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + return; + } + + argv[0] = conn_event->handle; + argv[1] = (uint32) data_offset; + argv[2] = conn_event->len; + if (!wasm_runtime_call_wasm(inst, NULL, func_on_conn_data, 3, argv)) { + printf(":Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + wasm_runtime_module_free(inst, data_offset); + return; + } + wasm_runtime_module_free(inst, data_offset); + } +} + +bool init_connection_framework() +{ + korp_thread tid; + + epollfd = epoll_create(MAX_EVENTS); + if (epollfd == -1) + return false; + + if (vm_mutex_init(&g_lock) != BH_SUCCESS) { + close(epollfd); + return false; + } + + if (!wasm_register_cleanup_callback(cleanup_connections)) { + goto fail; + } + + if (!wasm_register_msg_callback(CONNECTION_EVENT_WASM, + app_mgr_connection_event_callback)) { + goto fail; + } + + if (vm_thread_create(&tid, + polling_thread_routine, + NULL, + BH_APPLET_PRESERVED_STACK_SIZE) != BH_SUCCESS) { + goto fail; + } + + return true; + +fail: + vm_mutex_destroy(&g_lock); + close(epollfd); + return false; +} diff --git a/core/iwasm/lib/native/extension/connection/linux/connection_mgr.cmake b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.cmake new file mode 100644 index 0000000000..72ab4554d4 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.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 (WASM_LIB_CONN_MGR_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${WASM_LIB_CONN_MGR_DIR}) + + +file (GLOB_RECURSE source_all ${WASM_LIB_CONN_MGR_DIR}/*.c) + +set (WASM_LIB_CONN_MGR_SOURCE ${source_all}) + + diff --git a/core/iwasm/lib/native/extension/connection/wasm_lib_conn.cmake b/core/iwasm/lib/native/extension/connection/wasm_lib_conn.cmake new file mode 100644 index 0000000000..2018706e80 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/wasm_lib_conn.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_LIB_CONN_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${WASM_LIB_CONN_DIR}) + + +file (GLOB source_all ${WASM_LIB_CONN_DIR}/*.c) + +set (WASM_LIB_CONN_SOURCE ${source_all}) + diff --git a/core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c b/core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c new file mode 100644 index 0000000000..379437076f --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/* + * Note: + * This file implements the linux version connection library which is + * defined in connection_lib.h. + * It also provides a reference impl of connections manager. + */ + +#include "connection_lib.h" + +/* + * Platform implementation of connection library + */ +connection_interface_t connection_impl = { + ._open = NULL, + ._close = NULL, + ._send = NULL, + ._config = NULL +}; diff --git a/core/shared-lib/include/config.h b/core/shared-lib/include/config.h index 0c270cbc70..14f379c7e4 100644 --- a/core/shared-lib/include/config.h +++ b/core/shared-lib/include/config.h @@ -63,6 +63,9 @@ /* Max timer number in one app */ #define MAX_TIMERS_PER_APP 30 +/* Max connection number in one app */ +#define MAX_CONNECTION_PER_APP 20 + /* Max resource registration number in one app */ #define RESOURCE_REGISTRATION_NUM_MAX 16 diff --git a/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt b/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt index 719f866b40..9f2f29a7d0 100644 --- a/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt +++ b/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt @@ -57,6 +57,8 @@ include (${WASM_DIR}/runtime/vmcore-wasm/vmcore.cmake) include (${WASM_DIR}/lib/native/base/wasm_lib_base.cmake) include (${WASM_DIR}/lib/native/libc/wasm_libc.cmake) include (${WASM_DIR}/lib/native/extension/sensor/wasm_lib_sensor.cmake) +include (${WASM_DIR}/lib/native/extension/connection/wasm_lib_conn.cmake) +include (${WASM_DIR}/lib/native/extension/connection/${TARGET_PLATFORM}/connection_mgr.cmake) include (${WASM_DIR}/lib/native-interface/native_interface.cmake) include (${APP_MGR_DIR}/app-manager/app_mgr.cmake) include (${APP_MGR_DIR}/app-mgr-shared/app_mgr_shared.cmake) @@ -81,6 +83,8 @@ add_library (vmlib ${WASM_LIB_BASE_SOURCE} ${WASM_LIB_EXT_SOURCE} ${WASM_LIB_SENSOR_SOURCE} + ${WASM_LIB_CONN_SOURCE} + ${WASM_LIB_CONN_MGR_SOURCE} ${PLATFORM_SHARED_SOURCE} ${UTILS_SHARED_SOURCE} ${MEM_ALLOC_SHARED_SOURCE} diff --git a/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c b/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c index 8927493a8f..3897b3b0b4 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c @@ -1,8 +1,11 @@ #include "lib_export.h" #include "native_interface.h" +#include "connection_api.h" #include "display_indev.h" + static NativeSymbol extended_native_symbol_defs[] = { #include "runtime_sensor.inl" +#include "connection.inl" EXPORT_WASM_API(display_init), EXPORT_WASM_API(display_input_read), EXPORT_WASM_API(display_flush), diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c index c5d23b0579..15d94d3033 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c @@ -46,6 +46,7 @@ static int baudrate = B115200; extern void * thread_timer_check(void *); extern void init_sensor_framework(); extern int aee_host_msg_callback(void *msg, uint16_t msg_len); +extern bool init_connection_framework(); #ifndef CONNECTION_UART int listenfd = -1; @@ -441,6 +442,12 @@ int iwasm_main(int argc, char *argv[]) if (vm_thread_sys_init() != 0) { goto fail1; } + + if (!init_connection_framework()) { + vm_thread_sys_destroy(); + goto fail1; + } + extern void display_SDL_init(); display_SDL_init(); diff --git a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt index bb5948ed9c..bd7c016989 100644 --- a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt +++ b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt @@ -38,6 +38,7 @@ target_include_directories(app PRIVATE ${IWASM_ROOT}/runtime/include ${IWASM_ROOT}/lib/native/base ${IWASM_ROOT}/lib/native/libc ${IWASM_ROOT}/lib/native/extension/sensor + ${IWASM_ROOT}/lib/native/extension/connection ${IWASM_ROOT}/lib/native-interface ${APP_MGR_ROOT}/app-manager ${APP_MGR_ROOT}/app-mgr-shared @@ -69,6 +70,8 @@ set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c ${IWASM_ROOT}/lib/native/base/timer_wrapper.c ${IWASM_ROOT}/lib/native/libc/libc_wrapper.c ${IWASM_ROOT}/lib/native/extension/sensor/runtime_sensor.c + ${IWASM_ROOT}/lib/native/extension/connection/connection_wrapper.c + ${IWASM_ROOT}/lib/native/extension/connection/zephyr/connection_lib_impl.c ${IWASM_ROOT}/lib/native-interface/attr_container.c ${IWASM_ROOT}/lib/native-interface/restful_utils.c ${APP_MGR_ROOT}/app-manager/app_manager.c diff --git a/samples/littlevgl/wasm-apps/Makefile_wasm_app b/samples/littlevgl/wasm-apps/Makefile_wasm_app index dcf7f17243..03671e1d44 100644 --- a/samples/littlevgl/wasm-apps/Makefile_wasm_app +++ b/samples/littlevgl/wasm-apps/Makefile_wasm_app @@ -14,7 +14,17 @@ CC = emcc LVGL_DIR = ${shell pwd} -CFLAGS += -O3 -DLV_CONF_INCLUDE_SIMPLE=1 -I$(LVGL_DIR)/ -I$(LVGL_DIR)/lvgl/ -I$(LVGL_DIR)/lv_drivers/ -I$(LVGL_DIR)/src/ -I../../../core/iwasm/lib/app-libs/base/ -I../../../core/iwasm/lib/native-interface/ -I../../../core/iwasm/lib/app-libs/extension/sensor +IWASM_DIR=../../../core/iwasm +CFLAGS += -O3 \ + -DLV_CONF_INCLUDE_SIMPLE=1 \ + -I$(LVGL_DIR)/ \ + -I$(LVGL_DIR)/lvgl/ \ + -I$(LVGL_DIR)/lv_drivers/ \ + -I$(LVGL_DIR)/src/ \ + -I$(IWASM_DIR)/lib/app-libs/base/ \ + -I$(IWASM_DIR)/lib/native-interface/ \ + -I$(IWASM_DIR)/lib/app-libs/extension/sensor \ + -I$(IWASM_DIR)/lib/app-libs/extension/connection SRCS += lvgl/lv_draw/lv_draw_line.c lvgl/lv_draw/lv_draw_rbasic.c SRCS += lvgl/lv_draw/lv_draw_img.c lvgl/lv_draw/lv_draw_arc.c @@ -46,10 +56,11 @@ SRCS += lvgl/lv_core/lv_group.c lvgl/lv_core/lv_style.c lvgl/lv_core/lv_indev.c SRCS += lvgl/lv_core/lv_vdb.c lvgl/lv_core/lv_obj.c lvgl/lv_core/lv_refr.c SRCS += $(LVGL_DIR)/src/main.c -SRCS += ../../../core/iwasm/lib/app-libs/base/timer.c +# For app size consideration, not all but necessary app libs are included +SRCS += $(IWASM_DIR)/lib/app-libs/base/timer.c all: @$(CC) $(CFLAGS) $(SRCS) \ -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ -s TOTAL_MEMORY=65536 -s TOTAL_STACK=2048\ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_request', '_on_sensor_event', '_on_timer_callback']" \ + -s "EXPORTED_FUNCTIONS=['_on_init', '_on_timer_callback']" \ -o ui_app.wasm diff --git a/samples/simple/CMakeLists.txt b/samples/simple/CMakeLists.txt index 01fade4447..53fa768ea1 100644 --- a/samples/simple/CMakeLists.txt +++ b/samples/simple/CMakeLists.txt @@ -57,6 +57,8 @@ include (${WASM_DIR}/runtime/vmcore-wasm/vmcore.cmake) include (${WASM_DIR}/lib/native/base/wasm_lib_base.cmake) include (${WASM_DIR}/lib/native/libc/wasm_libc.cmake) include (${WASM_DIR}/lib/native/extension/sensor/wasm_lib_sensor.cmake) +include (${WASM_DIR}/lib/native/extension/connection/wasm_lib_conn.cmake) +include (${WASM_DIR}/lib/native/extension/connection/${TARGET_PLATFORM}/connection_mgr.cmake) include (${WASM_DIR}/lib/native-interface/native_interface.cmake) include (${APP_MGR_DIR}/app-manager/app_mgr.cmake) include (${APP_MGR_DIR}/app-mgr-shared/app_mgr_shared.cmake) @@ -83,6 +85,8 @@ add_library (vmlib ${WASM_LIB_BASE_SOURCE} ${WASM_LIB_EXT_SOURCE} ${WASM_LIB_SENSOR_SOURCE} + ${WASM_LIB_CONN_SOURCE} + ${WASM_LIB_CONN_MGR_SOURCE} ${PLATFORM_SHARED_SOURCE} ${UTILS_SHARED_SOURCE} ${MEM_ALLOC_SHARED_SOURCE} diff --git a/samples/simple/README.md b/samples/simple/README.md index b17dd9eb8e..aca5a50c80 100644 --- a/samples/simple/README.md +++ b/samples/simple/README.md @@ -16,18 +16,13 @@ simple/ │   ├── iwasm_main.c │   └── main.c └── wasm-apps - ├── event_publisher - │   └── event_publisher.c - ├── event_subscriber - │   └── event_subscriber.c - ├── request_handler - │   └── request_handler.c - ├── request_sender - │   └── request_sender.c - ├── sensor - │   └── sensor.c - └── timer -    └── timer.c + ├── connection.c + ├── event_publisher.c + ├── event_subscriber.c + ├── request_handler.c + ├── request_sender.c + ├── sensor.c + └── timer.c ``` - build.sh
@@ -75,18 +70,19 @@ Execute the build.sh script then all binaries including wasm application files w Out directory structure ------------------------------ - ``` +``` out/ ├── host_tool ├── simple └── wasm-apps + ├── connection.wasm ├── event_publisher.wasm ├── event_subscriber.wasm ├── request_handler.wasm ├── request_sender.wasm ├── sensor.wasm └── timer.wasm - ``` +``` - host_tool: A small testing tool to interact with WAMR. See the usage of this tool by executing "./host_tool -h". @@ -100,6 +96,8 @@ out/ - wasm-apps: Sample wasm applications that demonstrate all APIs of the WAMR programming model. The source codes are in the wasm-apps directory under the root of this project. + + connection.wasm
+ This application shows the connection programming model. It connects to a TCP server on 127.0.0.1:7777 and periodically sends message to it. + event_publisher.wasm
This application shows the sub/pub programming model. The pub application publishes the event "alert/overheat" by calling api_publish_event() API. The subscriber could be host_tool or other wasm application. + event_subscriber.wasm
diff --git a/samples/simple/build.sh b/samples/simple/build.sh index 1d8b8e1b16..453f1271f4 100755 --- a/samples/simple/build.sh +++ b/samples/simple/build.sh @@ -8,7 +8,7 @@ BUILD_DIR=${PWD}/build IWASM_ROOT=${PWD}/../../core/iwasm APP_LIBS=${IWASM_ROOT}/lib/app-libs NATIVE_LIBS=${IWASM_ROOT}/lib/native-interface -APP_LIB_SRC="${APP_LIBS}/base/*.c ${APP_LIBS}/extension/sensor/*.c ${NATIVE_LIBS}/*.c" +APP_LIB_SRC="${APP_LIBS}/base/*.c ${APP_LIBS}/extension/sensor/*.c ${APP_LIBS}/extension/connection/*.c ${NATIVE_LIBS}/*.c" WASM_APPS=${PWD}/wasm-apps rm -rf ${OUT_DIR} @@ -49,54 +49,23 @@ echo "#####################build host-tool success" echo "#####################build wasm apps" -cd ${CURR_DIR} - -APP_SRC="${WASM_APPS}/timer/timer.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/timer.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/request_handler/request_handler.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/request_handler.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/request_sender/request_sender.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/request_sender.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/event_publisher/event_publisher.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/event_publisher.wasm ${APP_SRC} +cd ${WASM_APPS} -APP_SRC="${WASM_APPS}/event_subscriber/event_subscriber.c ${APP_LIB_SRC}" +for i in `ls *.c` +do +APP_SRC="$i ${APP_LIB_SRC}" +OUT_FILE=${i%.*}.wasm emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ + -I${APP_LIBS}/extension/connection \ -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/event_subscriber.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/sensor/sensor.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/sensor.wasm ${APP_SRC} - -echo "#####################build wasm apps success" + '_on_sensor_event', '_on_timer_callback', '_on_connection_data']" \ + -o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC} +if [ -f ${OUT_DIR}/wasm-apps/${OUT_FILE} ]; then + echo "build ${OUT_FILE} success" +else + echo "build ${OUT_FILE} fail" +fi +done +echo "#####################build wasm apps done" diff --git a/samples/simple/src/ext_lib_export.c b/samples/simple/src/ext_lib_export.c index 89e572005d..24782b5e87 100644 --- a/samples/simple/src/ext_lib_export.c +++ b/samples/simple/src/ext_lib_export.c @@ -1,8 +1,10 @@ #include "lib_export.h" #include "sensor_api.h" +#include "connection_api.h" static NativeSymbol extended_native_symbol_defs[] = { #include "runtime_sensor.inl" +#include "connection.inl" }; #include "ext_lib_export.h" diff --git a/samples/simple/src/iwasm_main.c b/samples/simple/src/iwasm_main.c index d70b7e4d3c..141aa51403 100644 --- a/samples/simple/src/iwasm_main.c +++ b/samples/simple/src/iwasm_main.c @@ -46,6 +46,7 @@ static int baudrate = B115200; extern void * thread_timer_check(void *); extern void init_sensor_framework(); extern int aee_host_msg_callback(void *msg, uint16_t msg_len); +extern bool init_connection_framework(); #ifndef CONNECTION_UART int listenfd = -1; @@ -213,7 +214,7 @@ void* func_server_mode(void* arg) sockfd = -1; pthread_mutex_unlock(&sock_lock); - sleep(2); + sleep(1); break; } @@ -442,6 +443,11 @@ int iwasm_main(int argc, char *argv[]) goto fail1; } + if (!init_connection_framework()) { + vm_thread_sys_destroy(); + goto fail1; + } + init_sensor_framework(); // timer manager diff --git a/samples/simple/wasm-apps/connection.c b/samples/simple/wasm-apps/connection.c new file mode 100644 index 0000000000..89aed5170e --- /dev/null +++ b/samples/simple/wasm-apps/connection.c @@ -0,0 +1,93 @@ +/* + * 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_app.h" + +/* User global variable */ +static int num = 0; +static user_timer_t g_timer; +static connection_t *g_conn = NULL; + +void on_data1(connection_t *conn, + conn_event_type_t type, + const char *data, + uint32 len, + void *user_data) +{ + if (type == CONN_EVENT_TYPE_DATA) { + char message[64] = {0}; + memcpy(message, data, len); + printf("Client got a message from server -> %s\n", message); + } else if (type == CONN_EVENT_TYPE_DISCONNECT) { + printf("connection is close by server!\n"); + } else { + printf("error: got unknown event type!!!\n"); + } +} + +/* Timer callback */ +void timer1_update(user_timer_t timer) +{ + char message[64] = {0}; + /* Reply to server */ + snprintf(message, sizeof(message), "Hello %d", num++); + api_send_on_connection(g_conn, message, strlen(message)); +} + +void my_close_handler(request_t * request) +{ + response_t response[1]; + + if (g_conn != NULL) { + api_timer_cancel(g_timer); + api_close_connection(g_conn); + } + + make_response_for_request(request, response); + set_response(response, DELETED_2_02, 0, NULL, 0); + api_response_send(response); +} + +void on_init() +{ + user_timer_t timer; + attr_container_t *args; + char *str = "this is client!"; + + api_register_resource_handler("/close", my_close_handler); + + args = attr_container_create(""); + attr_container_set_string(&args, "address", "127.0.0.1"); + attr_container_set_uint16(&args, "port", 7777); + + g_conn = api_open_connection("TCP", args, on_data1, NULL); + if (g_conn == NULL) { + printf("connect to server fail!\n"); + return; + } + + printf("connect to server success! handle: %p\n", g_conn); + + /* set up a timer */ + timer = api_timer_create(1000, true, false, timer1_update); + api_timer_restart(timer, 1000); +} + +void on_destroy() +{ + /* real destroy work including killing timer and closing sensor is + accomplished in wasm app library version of on_destroy() */ +} diff --git a/samples/simple/wasm-apps/event_publisher/event_publisher.c b/samples/simple/wasm-apps/event_publisher.c similarity index 100% rename from samples/simple/wasm-apps/event_publisher/event_publisher.c rename to samples/simple/wasm-apps/event_publisher.c diff --git a/samples/simple/wasm-apps/event_subscriber/event_subscriber.c b/samples/simple/wasm-apps/event_subscriber.c similarity index 100% rename from samples/simple/wasm-apps/event_subscriber/event_subscriber.c rename to samples/simple/wasm-apps/event_subscriber.c diff --git a/samples/simple/wasm-apps/request_handler/request_handler.c b/samples/simple/wasm-apps/request_handler.c similarity index 100% rename from samples/simple/wasm-apps/request_handler/request_handler.c rename to samples/simple/wasm-apps/request_handler.c diff --git a/samples/simple/wasm-apps/request_sender/request_sender.c b/samples/simple/wasm-apps/request_sender.c similarity index 100% rename from samples/simple/wasm-apps/request_sender/request_sender.c rename to samples/simple/wasm-apps/request_sender.c diff --git a/samples/simple/wasm-apps/sensor/sensor.c b/samples/simple/wasm-apps/sensor.c similarity index 100% rename from samples/simple/wasm-apps/sensor/sensor.c rename to samples/simple/wasm-apps/sensor.c diff --git a/samples/simple/wasm-apps/timer/timer.c b/samples/simple/wasm-apps/timer.c similarity index 100% rename from samples/simple/wasm-apps/timer/timer.c rename to samples/simple/wasm-apps/timer.c From 624c58f6fda5d3be46868efbd419304b44ae96d2 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Fri, 14 Jun 2019 11:24:35 +0800 Subject: [PATCH 04/18] Fix bug of reading magic number and version in big endian platform --- core/iwasm/runtime/vmcore-wasm/wasm_loader.c | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index c03ddc3a31..debdb256e0 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -1335,6 +1335,18 @@ create_sections(const uint8 *buf, uint32 size, return true; } +static void +exchange32(uint8* p_data) +{ + uint8 value = *p_data; + *p_data = *(p_data + 3); + *(p_data + 3) = value; + + value = *(p_data + 1); + *(p_data + 1) = *(p_data + 2); + *(p_data + 2) = value; +} + static bool load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf, uint32 error_buf_size) @@ -1345,13 +1357,21 @@ load(const uint8 *buf, uint32 size, WASMModule *module, WASMSection *section_list = NULL; CHECK_BUF(p, p_end, sizeof(uint32)); - if ((magic_number = read_uint32(p)) != WASM_MAGIC_NUMBER) { + magic_number = read_uint32(p); + if (!is_little_endian) + exchange32((uint8*)&magic_number); + + if (magic_number != WASM_MAGIC_NUMBER) { set_error_buf(error_buf, error_buf_size, "magic header not detected"); return false; } CHECK_BUF(p, p_end, sizeof(uint32)); - if ((version = read_uint32(p)) != WASM_CURRENT_VERSION) { + version = read_uint32(p); + if (!is_little_endian) + exchange32((uint8*)&version); + + if (version != WASM_CURRENT_VERSION) { set_error_buf(error_buf, error_buf_size, "unknown binary version"); return false; } From c290de77e281da436c1aec1eea37fa1c0d84daf9 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Mon, 22 Jul 2019 11:26:47 +0800 Subject: [PATCH 05/18] Re-org platform APIs: move most platform APIs from iwasm to shared-lib --- core/iwasm/products/alios-things/iwasm.mk | 5 +- core/iwasm/products/alios-things/src/main.c | 2 +- core/iwasm/products/linux/main.c | 6 +- core/iwasm/products/vxworks/main.c | 4 +- .../products/zephyr/simple/CMakeLists.txt | 3 +- core/iwasm/products/zephyr/simple/src/main.c | 2 +- .../wasm_platform.c => include/wasm_dlfcn.h} | 28 ++--- core/iwasm/runtime/include/wasm_hashmap.h | 2 +- core/iwasm/runtime/include/wasm_log.h | 2 +- core/iwasm/runtime/include/wasm_vector.h | 2 +- .../alios/{wasm-native.c => wasm_native.c} | 0 .../runtime/platform/alios/wasm_platform.h | 104 ----------------- .../runtime/platform/include/wasm_types.h | 38 ------- .../runtime/platform/linux/wasm_platform.c | 96 ---------------- .../runtime/platform/linux/wasm_platform.h | 104 ----------------- .../runtime/platform/vxworks/wasm_platform.c | 96 ---------------- .../runtime/platform/vxworks/wasm_platform.h | 104 ----------------- .../runtime/platform/zephyr/wasm_platform.c | 56 ---------- .../runtime/platform/zephyr/wasm_platform.h | 105 ------------------ core/iwasm/runtime/utils/wasm_dlfcn.c | 2 +- core/iwasm/runtime/vmcore-wasm/wasm.h | 2 +- .../runtime/vmcore-wasm/wasm_application.c | 11 +- core/iwasm/runtime/vmcore-wasm/wasm_loader.c | 12 +- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 2 +- .../platform/alios/COPYRIGHT | 0 .../platform/alios/bh_math.c} | 66 +++++------ core/shared-lib/platform/alios/bh_platform.c | 6 + core/shared-lib/platform/alios/bh_platform.h | 28 ++++- core/shared-lib/platform/include/bh_types.h | 2 + core/shared-lib/platform/linux/bh_platform.c | 59 +++++++++- core/shared-lib/platform/linux/bh_platform.h | 79 ++++++------- .../shared-lib/platform/vxworks/bh_platform.c | 59 ++++++++++ .../shared-lib/platform/vxworks/bh_platform.h | 70 ++++++------ .../platform/zephyr/COPYRIGHT | 0 .../platform/zephyr/bh_math.c} | 66 +++++------ core/shared-lib/platform/zephyr/bh_platform.c | 22 ++++ core/shared-lib/platform/zephyr/bh_platform.h | 35 +++++- .../src/platform/zephyr/main.c | 2 +- .../zephyr-build/CMakeLists.txt | 4 +- 39 files changed, 387 insertions(+), 899 deletions(-) rename core/iwasm/runtime/{platform/alios/wasm_platform.c => include/wasm_dlfcn.h} (69%) rename core/iwasm/runtime/platform/alios/{wasm-native.c => wasm_native.c} (100%) delete mode 100644 core/iwasm/runtime/platform/alios/wasm_platform.h delete mode 100644 core/iwasm/runtime/platform/include/wasm_types.h delete mode 100644 core/iwasm/runtime/platform/linux/wasm_platform.c delete mode 100644 core/iwasm/runtime/platform/linux/wasm_platform.h delete mode 100644 core/iwasm/runtime/platform/vxworks/wasm_platform.c delete mode 100644 core/iwasm/runtime/platform/vxworks/wasm_platform.h delete mode 100644 core/iwasm/runtime/platform/zephyr/wasm_platform.c delete mode 100644 core/iwasm/runtime/platform/zephyr/wasm_platform.h rename core/{iwasm/runtime => shared-lib}/platform/alios/COPYRIGHT (100%) rename core/{iwasm/runtime/platform/alios/wasm_math.c => shared-lib/platform/alios/bh_math.c} (90%) rename core/{iwasm/runtime => shared-lib}/platform/zephyr/COPYRIGHT (100%) rename core/{iwasm/runtime/platform/zephyr/wasm_math.c => shared-lib/platform/zephyr/bh_math.c} (91%) diff --git a/core/iwasm/products/alios-things/iwasm.mk b/core/iwasm/products/alios-things/iwasm.mk index 030502ef0b..803578c151 100644 --- a/core/iwasm/products/alios-things/iwasm.mk +++ b/core/iwasm/products/alios-things/iwasm.mk @@ -28,9 +28,7 @@ GLOBAL_INCLUDES += ${IWASM_ROOT}/runtime/include \ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \ ${IWASM_ROOT}/runtime/utils/wasm_log.c \ ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c \ - ${IWASM_ROOT}/runtime/platform/alios/wasm_math.c \ - ${IWASM_ROOT}/runtime/platform/alios/wasm_platform.c \ - ${IWASM_ROOT}/runtime/platform/alios/wasm-native.c \ + ${IWASM_ROOT}/runtime/platform/alios/wasm_native.c \ ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c \ ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c \ ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_loader.c \ @@ -41,6 +39,7 @@ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_platform.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_assert.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_thread.c \ + ${SHARED_LIB_ROOT}/platform/alios/bh_math.c \ ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c \ ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c \ ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c \ diff --git a/core/iwasm/products/alios-things/src/main.c b/core/iwasm/products/alios-things/src/main.c index f9b19c478a..395c9b852b 100644 --- a/core/iwasm/products/alios-things/src/main.c +++ b/core/iwasm/products/alios-things/src/main.c @@ -16,9 +16,9 @@ #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" diff --git a/core/iwasm/products/linux/main.c b/core/iwasm/products/linux/main.c index 22fe692c0e..9b0dc08ccc 100644 --- a/core/iwasm/products/linux/main.c +++ b/core/iwasm/products/linux/main.c @@ -19,9 +19,9 @@ #endif #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" @@ -188,8 +188,8 @@ int main(int argc, char *argv[]) wasm_log_set_verbose_level(log_verbose_level); /* load WASM byte buffer from WASM bin file */ - if (!(wasm_file_buf = (uint8*) wasm_read_file_to_buffer(wasm_file, - &wasm_file_size))) + if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file, + &wasm_file_size))) goto fail2; /* load WASM module */ diff --git a/core/iwasm/products/vxworks/main.c b/core/iwasm/products/vxworks/main.c index 22fe692c0e..dc26304288 100644 --- a/core/iwasm/products/vxworks/main.c +++ b/core/iwasm/products/vxworks/main.c @@ -188,8 +188,8 @@ int main(int argc, char *argv[]) wasm_log_set_verbose_level(log_verbose_level); /* load WASM byte buffer from WASM bin file */ - if (!(wasm_file_buf = (uint8*) wasm_read_file_to_buffer(wasm_file, - &wasm_file_size))) + if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file, + &wasm_file_size))) goto fail2; /* load WASM module */ diff --git a/core/iwasm/products/zephyr/simple/CMakeLists.txt b/core/iwasm/products/zephyr/simple/CMakeLists.txt index d9e91e4cb1..0363741ba3 100644 --- a/core/iwasm/products/zephyr/simple/CMakeLists.txt +++ b/core/iwasm/products/zephyr/simple/CMakeLists.txt @@ -35,8 +35,6 @@ include_directories (${IWASM_ROOT}/runtime/include set (IWASM_SRCS ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c ${IWASM_ROOT}/runtime/utils/wasm_log.c ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c - ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c - ${IWASM_ROOT}/runtime/platform/zephyr/wasm_platform.c ${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c @@ -48,6 +46,7 @@ set (IWASM_SRCS ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_platform.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_assert.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c diff --git a/core/iwasm/products/zephyr/simple/src/main.c b/core/iwasm/products/zephyr/simple/src/main.c index fb183e3875..a6a9260a79 100644 --- a/core/iwasm/products/zephyr/simple/src/main.c +++ b/core/iwasm/products/zephyr/simple/src/main.c @@ -16,9 +16,9 @@ #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" diff --git a/core/iwasm/runtime/platform/alios/wasm_platform.c b/core/iwasm/runtime/include/wasm_dlfcn.h similarity index 69% rename from core/iwasm/runtime/platform/alios/wasm_platform.c rename to core/iwasm/runtime/include/wasm_dlfcn.h index e643377cd7..ce45de2b19 100644 --- a/core/iwasm/runtime/platform/alios/wasm_platform.c +++ b/core/iwasm/runtime/include/wasm_dlfcn.h @@ -14,27 +14,19 @@ * limitations under the License. */ -#include "wasm_platform.h" +#ifndef _WASM_DLFCN_H +#define _WASM_DLFCN_H -bool is_little_endian = false; +#ifdef __cplusplus +extern "C" { +#endif -bool __is_little_endian() -{ - union w - { - int a; - char b; - }c; +void * +wasm_dlsym(void *handle, const char *symbol); - c.a = 1; - return (c.b == 1); +#ifdef __cplusplus } +#endif -int wasm_platform_init() -{ - if (__is_little_endian()) - is_little_endian = true; - - return 0; -} +#endif /* end of _WASM_DLFCN_H */ diff --git a/core/iwasm/runtime/include/wasm_hashmap.h b/core/iwasm/runtime/include/wasm_hashmap.h index c9f7191220..2296b1c3cd 100644 --- a/core/iwasm/runtime/include/wasm_hashmap.h +++ b/core/iwasm/runtime/include/wasm_hashmap.h @@ -17,7 +17,7 @@ #ifndef WASM_HASHMAP_H #define WASM_HASHMAP_H -#include "wasm_platform.h" +#include "bh_platform.h" #ifdef __cplusplus diff --git a/core/iwasm/runtime/include/wasm_log.h b/core/iwasm/runtime/include/wasm_log.h index 112db2f14a..cba03b0441 100644 --- a/core/iwasm/runtime/include/wasm_log.h +++ b/core/iwasm/runtime/include/wasm_log.h @@ -30,7 +30,7 @@ #ifndef _WASM_LOG_H #define _WASM_LOG_H -#include "wasm_platform.h" +#include "bh_platform.h" #ifdef __cplusplus diff --git a/core/iwasm/runtime/include/wasm_vector.h b/core/iwasm/runtime/include/wasm_vector.h index 4723ff6875..e11832ede2 100644 --- a/core/iwasm/runtime/include/wasm_vector.h +++ b/core/iwasm/runtime/include/wasm_vector.h @@ -17,7 +17,7 @@ #ifndef _WASM_VECTOR_H #define _WASM_VECTOR_H -#include "wasm_platform.h" +#include "bh_platform.h" #ifdef __cplusplus diff --git a/core/iwasm/runtime/platform/alios/wasm-native.c b/core/iwasm/runtime/platform/alios/wasm_native.c similarity index 100% rename from core/iwasm/runtime/platform/alios/wasm-native.c rename to core/iwasm/runtime/platform/alios/wasm_native.c diff --git a/core/iwasm/runtime/platform/alios/wasm_platform.h b/core/iwasm/runtime/platform/alios/wasm_platform.h deleted file mode 100644 index 50bba6de09..0000000000 --- a/core/iwasm/runtime/platform/alios/wasm_platform.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include "wasm_config.h" -#include "wasm_types.h" -#include -#include - -#include -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "AliOS" -#define __ALIOS__ 1 - -#include -#include -#include -#include -#include -#include - -/** - * 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 - -typedef aos_task_t korp_thread; -typedef korp_thread *korp_tid; -typedef aos_mutex_t korp_mutex; - -int wasm_platform_init(); - -extern bool is_little_endian; - -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* math functions */ -double sqrt(double x); -double floor(double x); -double ceil(double x); -double fmin(double x, double y); -double fmax(double x, double y); -double rint(double x); -double fabs(double x); -double trunc(double x); -int signbit(double x); -int isnan(double x); - -void* -wasm_dlsym(void *handle, const char *symbol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/iwasm/runtime/platform/include/wasm_types.h b/core/iwasm/runtime/platform/include/wasm_types.h deleted file mode 100644 index a0bdbc1691..0000000000 --- a/core/iwasm/runtime/platform/include/wasm_types.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 _WASM_TYPES_H -#define _WASM_TYPES_H - -#include "wasm_config.h" - -typedef unsigned char uint8; -typedef char int8; -typedef unsigned short uint16; -typedef short int16; -typedef unsigned int uint32; -typedef int int32; - -#include "wasm_platform.h" - -#ifndef __cplusplus -#define true 1 -#define false 0 -#define inline __inline -#endif - -#endif /* end of _WASM_TYPES_H */ - diff --git a/core/iwasm/runtime/platform/linux/wasm_platform.c b/core/iwasm/runtime/platform/linux/wasm_platform.c deleted file mode 100644 index 53600a25b9..0000000000 --- a/core/iwasm/runtime/platform/linux/wasm_platform.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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_log.h" -#include "wasm_platform.h" -#include "wasm_memory.h" - -#include -#include -#include -#include -#include - -bool is_little_endian = false; - -bool __is_little_endian() -{ - union w - { - int a; - char b; - }c; - - c.a = 1; - return (c.b == 1); -} - -int -wasm_platform_init() -{ - if (__is_little_endian()) - is_little_endian = true; - - return 0; -} - -char* -wasm_read_file_to_buffer(const char *filename, int *ret_size) -{ - char *buffer; - int file; - int file_size, read_size; - struct stat stat_buf; - - if (!filename || !ret_size) { - LOG_ERROR("Read file to buffer failed: invalid filename or ret size.\n"); - return NULL; - } - - if ((file = open(filename, O_RDONLY, 0)) == -1) { - LOG_ERROR("Read file to buffer failed: open file %s failed.\n", - filename); - return NULL; - } - - if (fstat(file, &stat_buf) != 0) { - LOG_ERROR("Read file to buffer failed: fstat file %s failed.\n", - filename); - close(file); - return NULL; - } - - file_size = stat_buf.st_size; - - if (!(buffer = wasm_malloc(file_size))) { - LOG_ERROR("Read file to buffer failed: alloc memory failed.\n"); - close(file); - return NULL; - } - - read_size = read(file, buffer, file_size); - close(file); - - if (read_size < file_size) { - LOG_ERROR("Read file to buffer failed: read file content failed.\n"); - wasm_free(buffer); - return NULL; - } - - *ret_size = file_size; - return buffer; -} - diff --git a/core/iwasm/runtime/platform/linux/wasm_platform.h b/core/iwasm/runtime/platform/linux/wasm_platform.h deleted file mode 100644 index 7a63209572..0000000000 --- a/core/iwasm/runtime/platform/linux/wasm_platform.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include "wasm_config.h" -#include "wasm_types.h" - -#include -#include -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "Linux" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * 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 - -typedef pthread_t korp_tid; -typedef pthread_mutex_t korp_mutex; - -int wasm_platform_init(); - -extern bool is_little_endian; - -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* #include */ - -#ifndef __cplusplus -double sqrt(double x); -#endif - -#include -extern int fopen_s(FILE ** pFile, const char *filename, const char *mode); - -char* -wasm_read_file_to_buffer(const char *filename, int *ret_size); - -void* -wasm_dlsym(void *handle, const char *symbol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/iwasm/runtime/platform/vxworks/wasm_platform.c b/core/iwasm/runtime/platform/vxworks/wasm_platform.c deleted file mode 100644 index 53600a25b9..0000000000 --- a/core/iwasm/runtime/platform/vxworks/wasm_platform.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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_log.h" -#include "wasm_platform.h" -#include "wasm_memory.h" - -#include -#include -#include -#include -#include - -bool is_little_endian = false; - -bool __is_little_endian() -{ - union w - { - int a; - char b; - }c; - - c.a = 1; - return (c.b == 1); -} - -int -wasm_platform_init() -{ - if (__is_little_endian()) - is_little_endian = true; - - return 0; -} - -char* -wasm_read_file_to_buffer(const char *filename, int *ret_size) -{ - char *buffer; - int file; - int file_size, read_size; - struct stat stat_buf; - - if (!filename || !ret_size) { - LOG_ERROR("Read file to buffer failed: invalid filename or ret size.\n"); - return NULL; - } - - if ((file = open(filename, O_RDONLY, 0)) == -1) { - LOG_ERROR("Read file to buffer failed: open file %s failed.\n", - filename); - return NULL; - } - - if (fstat(file, &stat_buf) != 0) { - LOG_ERROR("Read file to buffer failed: fstat file %s failed.\n", - filename); - close(file); - return NULL; - } - - file_size = stat_buf.st_size; - - if (!(buffer = wasm_malloc(file_size))) { - LOG_ERROR("Read file to buffer failed: alloc memory failed.\n"); - close(file); - return NULL; - } - - read_size = read(file, buffer, file_size); - close(file); - - if (read_size < file_size) { - LOG_ERROR("Read file to buffer failed: read file content failed.\n"); - wasm_free(buffer); - return NULL; - } - - *ret_size = file_size; - return buffer; -} - diff --git a/core/iwasm/runtime/platform/vxworks/wasm_platform.h b/core/iwasm/runtime/platform/vxworks/wasm_platform.h deleted file mode 100644 index 95d0daad42..0000000000 --- a/core/iwasm/runtime/platform/vxworks/wasm_platform.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include -#include -#include "wasm_config.h" -#include "wasm_types.h" - -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "VxWorks" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * 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 - -typedef pthread_t korp_tid; -typedef pthread_mutex_t korp_mutex; - -int wasm_platform_init(); - -extern bool is_little_endian; - -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* #include */ - -#ifndef __cplusplus -double sqrt(double x); -#endif - -#include - - -char* -wasm_read_file_to_buffer(const char *filename, int *ret_size); - -void* -wasm_dlsym(void *handle, const char *symbol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/iwasm/runtime/platform/zephyr/wasm_platform.c b/core/iwasm/runtime/platform/zephyr/wasm_platform.c deleted file mode 100644 index 08b1650ebd..0000000000 --- a/core/iwasm/runtime/platform/zephyr/wasm_platform.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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_platform.h" - -#ifndef CONFIG_AEE_ENABLE -static int -_stdout_hook_iwasm(int c) -{ - printk("%c", (char)c); - return 1; -} - -extern void __stdout_hook_install(int (*hook)(int)); -#endif - -bool is_little_endian = false; - -bool __is_little_endian() -{ - union w - { - int a; - char b; - }c; - - c.a = 1; - return (c.b == 1); -} - -int wasm_platform_init() -{ - if (__is_little_endian()) - is_little_endian = true; - -#ifndef CONFIG_AEE_ENABLE - /* Enable printf() in Zephyr */ - __stdout_hook_install(_stdout_hook_iwasm); -#endif - - return 0; -} - diff --git a/core/iwasm/runtime/platform/zephyr/wasm_platform.h b/core/iwasm/runtime/platform/zephyr/wasm_platform.h deleted file mode 100644 index e14d213d73..0000000000 --- a/core/iwasm/runtime/platform/zephyr/wasm_platform.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include "wasm_config.h" -#include "wasm_types.h" -#include -#include -#include -#include - -#include -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "Zephyr" - -#include -#include -#include -#include -#include -#include - -/** - * 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 - -typedef struct k_thread korp_thread; -typedef korp_thread *korp_tid; -typedef struct k_mutex korp_mutex; - -int wasm_platform_init(); - -extern bool is_little_endian; - -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* math functions */ -double sqrt(double x); -double floor(double x); -double ceil(double x); -double fmin(double x, double y); -double fmax(double x, double y); -double rint(double x); -double fabs(double x); -double trunc(double x); -int signbit(double x); -int isnan(double x); - -void* -wasm_dlsym(void *handle, const char *symbol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/iwasm/runtime/utils/wasm_dlfcn.c b/core/iwasm/runtime/utils/wasm_dlfcn.c index de71231251..56439c71f4 100644 --- a/core/iwasm/runtime/utils/wasm_dlfcn.c +++ b/core/iwasm/runtime/utils/wasm_dlfcn.c @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "wasm_platform.h" +#include "bh_platform.h" static bool sort_flag = false; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm.h b/core/iwasm/runtime/vmcore-wasm/wasm.h index e493da9901..06b655e291 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm.h @@ -17,7 +17,7 @@ #ifndef _WASM_H_ #define _WASM_H_ -#include "wasm_platform.h" +#include "bh_platform.h" #include "wasm_hashmap.h" #include "wasm_assert.h" diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_application.c b/core/iwasm/runtime/vmcore-wasm/wasm_application.c index df67b3a097..5073ef2e37 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_application.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_application.c @@ -160,6 +160,13 @@ union ieee754_double { } ieee; }; +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + bool wasm_application_execute_func(WASMModuleInstance *module_inst, char *name, int argc, char *argv[]) @@ -222,7 +229,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst, union ieee754_float u; sig = strtoul(endptr + 1, &endptr, 0); u.f = f32; - if (is_little_endian) + if (is_little_endian()) u.ieee.ieee_little_endian.mantissa = sig; else u.ieee.ieee_big_endian.mantissa = sig; @@ -245,7 +252,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst, union ieee754_double ud; sig = strtoull(endptr + 1, &endptr, 0); ud.d = u.val; - if (is_little_endian) { + if (is_little_endian()) { ud.ieee.ieee_little_endian.mantissa0 = sig >> 32; ud.ieee.ieee_little_endian.mantissa1 = sig; } diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index debdb256e0..7b4733eff1 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -21,6 +21,7 @@ #include "wasm_runtime.h" #include "wasm_log.h" #include "wasm_memory.h" +#include "wasm_dlfcn.h" /* Read a value of given type from the address pointed to by the given pointer and increase the pointer to the position just after the @@ -1347,6 +1348,13 @@ exchange32(uint8* p_data) *(p_data + 2) = value; } +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + static bool load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf, uint32 error_buf_size) @@ -1358,7 +1366,7 @@ load(const uint8 *buf, uint32 size, WASMModule *module, CHECK_BUF(p, p_end, sizeof(uint32)); magic_number = read_uint32(p); - if (!is_little_endian) + if (!is_little_endian()) exchange32((uint8*)&magic_number); if (magic_number != WASM_MAGIC_NUMBER) { @@ -1368,7 +1376,7 @@ load(const uint8 *buf, uint32 size, WASMModule *module, CHECK_BUF(p, p_end, sizeof(uint32)); version = read_uint32(p); - if (!is_little_endian) + if (!is_little_endian()) exchange32((uint8*)&version); if (version != WASM_CURRENT_VERSION) { diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index ebfe14b57d..8f8de1ca78 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -35,7 +35,7 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) bool wasm_runtime_init() { - if (wasm_platform_init() != 0) + if (bh_platform_init() != 0) return false; if (wasm_log_init() != 0) diff --git a/core/iwasm/runtime/platform/alios/COPYRIGHT b/core/shared-lib/platform/alios/COPYRIGHT similarity index 100% rename from core/iwasm/runtime/platform/alios/COPYRIGHT rename to core/shared-lib/platform/alios/COPYRIGHT diff --git a/core/iwasm/runtime/platform/alios/wasm_math.c b/core/shared-lib/platform/alios/bh_math.c similarity index 90% rename from core/iwasm/runtime/platform/alios/wasm_math.c rename to core/shared-lib/platform/alios/bh_math.c index bad81eac31..27e9531115 100644 --- a/core/iwasm/runtime/platform/alios/wasm_math.c +++ b/core/shared-lib/platform/alios/bh_math.c @@ -28,10 +28,7 @@ * $FreeBSD$ */ -#include "wasm_log.h" -#include "wasm_platform.h" -#include "wasm_platform_log.h" -#include "wasm_memory.h" +#include "bh_platform.h" #define __FDLIBM_STDC__ @@ -99,6 +96,13 @@ typedef union { } bits; } IEEEd2bits_B; +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + #define __HIL(x) *(1+pdouble2pint(&x)) #define __LOL(x) *(pdouble2pint(&x)) #define __HIB(x) *(int*)&x @@ -179,39 +183,39 @@ do { \ } while (0) /* Macro wrappers. */ -#define EXTRACT_WORDS(ix0,ix1,d) do { \ - if (is_little_endian) \ - EXTRACT_WORDS_L(ix0,ix1,d); \ - else \ - EXTRACT_WORDS_B(ix0,ix1,d); \ +#define EXTRACT_WORDS(ix0,ix1,d) do { \ + if (is_little_endian()) \ + EXTRACT_WORDS_L(ix0,ix1,d); \ + else \ + EXTRACT_WORDS_B(ix0,ix1,d); \ } while (0) -#define INSERT_WORDS(d,ix0,ix1) do { \ - if (is_little_endian) \ - INSERT_WORDS_L(d,ix0,ix1); \ - else \ - INSERT_WORDS_B(d,ix0,ix1); \ +#define INSERT_WORDS(d,ix0,ix1) do { \ + if (is_little_endian()) \ + INSERT_WORDS_L(d,ix0,ix1); \ + else \ + INSERT_WORDS_B(d,ix0,ix1); \ } while (0) -#define GET_HIGH_WORD(i,d) \ -do { \ - if (is_little_endian) \ - GET_HIGH_WORD_L(i,d); \ - else \ - GET_HIGH_WORD_B(i,d); \ -} while (0) +#define GET_HIGH_WORD(i,d) \ + do { \ + if (is_little_endian()) \ + GET_HIGH_WORD_L(i,d); \ + else \ + GET_HIGH_WORD_B(i,d); \ + } while (0) -#define SET_HIGH_WORD(d,v) \ -do { \ - if (is_little_endian) \ - SET_HIGH_WORD_L(d,v); \ - else \ - SET_HIGH_WORD_B(d,v); \ -} while (0) +#define SET_HIGH_WORD(d,v) \ + do { \ + if (is_little_endian()) \ + SET_HIGH_WORD_L(d,v); \ + else \ + SET_HIGH_WORD_B(d,v); \ + } while (0) -#define __HI(x) (is_little_endian ? __HIL(x) : __HIB(x)) +#define __HI(x) (is_little_endian() ? __HIL(x) : __HIB(x)) -#define __LO(x) (is_little_endian ? __LOL(x) : __LOB(x)) +#define __LO(x) (is_little_endian() ? __LOL(x) : __LOB(x)) /* * Attempt to get strict C99 semantics for assignment with non-C99 compilers. @@ -509,7 +513,7 @@ static double freebsd_rint(double x) static int freebsd_isnan(double d) { - if (is_little_endian) { + if (is_little_endian()) { IEEEd2bits_L u; u.d = d; return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0)); diff --git a/core/shared-lib/platform/alios/bh_platform.c b/core/shared-lib/platform/alios/bh_platform.c index fe05e8bd1b..f8ca5735f1 100644 --- a/core/shared-lib/platform/alios/bh_platform.c +++ b/core/shared-lib/platform/alios/bh_platform.c @@ -25,3 +25,9 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +int bh_platform_init() +{ + return 0; +} + diff --git a/core/shared-lib/platform/alios/bh_platform.h b/core/shared-lib/platform/alios/bh_platform.h index 15fd614fb3..e23958c95d 100644 --- a/core/shared-lib/platform/alios/bh_platform.h +++ b/core/shared-lib/platform/alios/bh_platform.h @@ -43,8 +43,6 @@ /* Invalid thread tid */ #define INVALID_THREAD_ID NULL -#define INVALID_SEM_ID NULL - #define BH_WAIT_FOREVER AOS_WAIT_FOREVER typedef uint64_t uint64; @@ -79,6 +77,18 @@ int snprintf(char *buffer, size_t count, const char *format, ...); #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 + extern void bh_assert_internal(int v, const char *file_name, int line_number, const char *expr_string); #define bh_assert(expr) bh_assert_internal((int)(expr), __FILE__, __LINE__, # expr) @@ -86,5 +96,19 @@ extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned i extern int b_strcat_s(char * s1, size_t s1max, const char * s2); extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); +/* math functions */ +double sqrt(double x); +double floor(double x); +double ceil(double x); +double fmin(double x, double y); +double fmax(double x, double y); +double rint(double x); +double fabs(double x); +double trunc(double x); +int signbit(double x); +int isnan(double x); + +int bh_platform_init(); + #endif /* end of _BH_PLATFORM_H */ diff --git a/core/shared-lib/platform/include/bh_types.h b/core/shared-lib/platform/include/bh_types.h index ff561b244d..da26c7dc54 100644 --- a/core/shared-lib/platform/include/bh_types.h +++ b/core/shared-lib/platform/include/bh_types.h @@ -25,6 +25,8 @@ typedef unsigned short uint16; typedef short int16; typedef unsigned int uint32; typedef int int32; +typedef float float32; +typedef double float64; #define BYTES_OF_UINT8 1 #define BYTES_OF_UINT16 2 diff --git a/core/shared-lib/platform/linux/bh_platform.c b/core/shared-lib/platform/linux/bh_platform.c index fe05e8bd1b..3ff600cfc9 100755 --- a/core/shared-lib/platform/linux/bh_platform.c +++ b/core/shared-lib/platform/linux/bh_platform.c @@ -15,8 +15,10 @@ */ #include "bh_platform.h" -#include -#include + +#include +#include +#include char *bh_strdup(const char *s) { @@ -25,3 +27,56 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +int bh_platform_init() +{ + return 0; +} + +char* +bh_read_file_to_buffer(const char *filename, int *ret_size) +{ + char *buffer; + int file; + int file_size, read_size; + struct stat stat_buf; + + if (!filename || !ret_size) { + printf("Read file to buffer failed: invalid filename or ret size.\n"); + return NULL; + } + + if ((file = open(filename, O_RDONLY, 0)) == -1) { + printf("Read file to buffer failed: open file %s failed.\n", + filename); + return NULL; + } + + if (fstat(file, &stat_buf) != 0) { + printf("Read file to buffer failed: fstat file %s failed.\n", + filename); + close(file); + return NULL; + } + + file_size = stat_buf.st_size; + + if (!(buffer = bh_malloc(file_size))) { + printf("Read file to buffer failed: alloc memory failed.\n"); + close(file); + return NULL; + } + + read_size = read(file, buffer, file_size); + close(file); + + if (read_size < file_size) { + printf("Read file to buffer failed: read file content failed.\n"); + bh_free(buffer); + return NULL; + } + + *ret_size = file_size; + return buffer; +} + diff --git a/core/shared-lib/platform/linux/bh_platform.h b/core/shared-lib/platform/linux/bh_platform.h index 00c25b4926..47172c1f68 100644 --- a/core/shared-lib/platform/linux/bh_platform.h +++ b/core/shared-lib/platform/linux/bh_platform.h @@ -26,11 +26,16 @@ #include #include #include -#include - -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -47,46 +52,19 @@ extern void DEBUGME(void); /* NEED qsort */ -#include -#include -#include -#include -#include -#include -#include -#include - #define _STACK_SIZE_ADJUSTMENT (32 * 1024) -/* Stack size of applet manager thread. */ -#define BH_APPLET_MANAGER_THREAD_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of HMC thread. */ -#define BH_HMC_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of watchdog thread. */ -#define BH_WATCHDOG_THREAD_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - /* Stack size of applet threads's native part. */ #define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) -/* Stack size of remote invoke listen thread. */ -#define BH_REMOTE_INVOKE_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of remote post listen thread. */ -#define BH_REMOTE_POST_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Maximal recursion depth of interpreter. */ -#define BH_MAX_INTERP_RECURSION_DEPTH 8 - /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 #define BH_ROUTINE_MODIFIER + #define BHT_TIMEDOUT ETIMEDOUT #define INVALID_THREAD_ID 0xFFffFFff -#define INVALID_SEM_ID SEM_FAILED typedef pthread_t korp_tid; typedef pthread_mutex_t korp_mutex; @@ -99,28 +77,43 @@ typedef void* (*thread_start_routine_t)(void*); #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); -/* Definitions for applet debugging */ -#define APPLET_DEBUG_LISTEN_PORT 8000 -#define BH_SOCKET_INVALID_SOCK -1 #define BH_WAIT_FOREVER 0xFFFFFFFF -typedef int bh_socket_t; #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 -extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, - unsigned int n); -extern int b_strcat_s(char * s1, size_t s1max, const char * s2); -extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); -extern int fopen_s(FILE ** pFile, const char *filename, const char *mode); +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, + unsigned int n); +int b_strcat_s(char * s1, size_t s1max, const char * s2); +int b_strcpy_s(char * s1, size_t s1max, const char * s2); + +int fopen_s(FILE ** pFile, const char *filename, const char *mode); + +char *bh_read_file_to_buffer(const char *filename, int *ret_size); + +char *bh_strdup(const char *s); -extern char *bh_strdup(const char *s); +int bh_platform_init(); #ifdef __cplusplus } diff --git a/core/shared-lib/platform/vxworks/bh_platform.c b/core/shared-lib/platform/vxworks/bh_platform.c index fe05e8bd1b..981124228b 100644 --- a/core/shared-lib/platform/vxworks/bh_platform.c +++ b/core/shared-lib/platform/vxworks/bh_platform.c @@ -17,6 +17,12 @@ #include "bh_platform.h" #include #include +#include +#include +#include +#include +#include + char *bh_strdup(const char *s) { @@ -25,3 +31,56 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +int bh_platform_init() +{ + return 0; +} + +char* +bh_read_file_to_buffer(const char *filename, int *ret_size) +{ + char *buffer; + int file; + int file_size, read_size; + struct stat stat_buf; + + if (!filename || !ret_size) { + printf("Read file to buffer failed: invalid filename or ret size.\n"); + return NULL; + } + + if ((file = open(filename, O_RDONLY, 0)) == -1) { + printf("Read file to buffer failed: open file %s failed.\n", + filename); + return NULL; + } + + if (fstat(file, &stat_buf) != 0) { + printf("Read file to buffer failed: fstat file %s failed.\n", + filename); + close(file); + return NULL; + } + + file_size = stat_buf.st_size; + + if (!(buffer = wasm_malloc(file_size))) { + printf("Read file to buffer failed: alloc memory failed.\n"); + close(file); + return NULL; + } + + read_size = read(file, buffer, file_size); + close(file); + + if (read_size < file_size) { + printf("Read file to buffer failed: read file content failed.\n"); + wasm_free(buffer); + return NULL; + } + + *ret_size = file_size; + return buffer; +} + diff --git a/core/shared-lib/platform/vxworks/bh_platform.h b/core/shared-lib/platform/vxworks/bh_platform.h index 57fea9a854..142583e5b5 100644 --- a/core/shared-lib/platform/vxworks/bh_platform.h +++ b/core/shared-lib/platform/vxworks/bh_platform.h @@ -27,10 +27,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif #ifdef __cplusplus extern "C" { @@ -43,48 +46,23 @@ extern void DEBUGME(void); #define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0) -#define BH_PLATFORM "Linux" +#define BH_PLATFORM "VxWorks" /* NEED qsort */ -#include -#include -#include -#include -#include -#include - #define _STACK_SIZE_ADJUSTMENT (32 * 1024) -/* Stack size of applet manager thread. */ -#define BH_APPLET_MANAGER_THREAD_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of HMC thread. */ -#define BH_HMC_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of watchdog thread. */ -#define BH_WATCHDOG_THREAD_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - /* Stack size of applet threads's native part. */ #define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) -/* Stack size of remote invoke listen thread. */ -#define BH_REMOTE_INVOKE_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of remote post listen thread. */ -#define BH_REMOTE_POST_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Maximal recursion depth of interpreter. */ -#define BH_MAX_INTERP_RECURSION_DEPTH 8 - /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 #define BH_ROUTINE_MODIFIER + #define BHT_TIMEDOUT ETIMEDOUT #define INVALID_THREAD_ID 0xFFffFFff -#define INVALID_SEM_ID SEM_FAILED typedef pthread_t korp_tid; typedef pthread_mutex_t korp_mutex; @@ -97,27 +75,41 @@ typedef void* (*thread_start_routine_t)(void*); #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); -/* Definitions for applet debugging */ -#define APPLET_DEBUG_LISTEN_PORT 8000 -#define BH_SOCKET_INVALID_SOCK -1 #define BH_WAIT_FOREVER 0xFFFFFFFF -typedef int bh_socket_t; #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 -extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, - unsigned int n); -extern int b_strcat_s(char * s1, size_t s1max, const char * s2); -extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); +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_read_file_to_buffer(const char *filename, int *ret_size); + +char *bh_strdup(const char *s); -extern char *bh_strdup(const char *s); +int bh_platform_init(); #ifdef __cplusplus } diff --git a/core/iwasm/runtime/platform/zephyr/COPYRIGHT b/core/shared-lib/platform/zephyr/COPYRIGHT similarity index 100% rename from core/iwasm/runtime/platform/zephyr/COPYRIGHT rename to core/shared-lib/platform/zephyr/COPYRIGHT diff --git a/core/iwasm/runtime/platform/zephyr/wasm_math.c b/core/shared-lib/platform/zephyr/bh_math.c similarity index 91% rename from core/iwasm/runtime/platform/zephyr/wasm_math.c rename to core/shared-lib/platform/zephyr/bh_math.c index ebea5c4903..a279470430 100644 --- a/core/iwasm/runtime/platform/zephyr/wasm_math.c +++ b/core/shared-lib/platform/zephyr/bh_math.c @@ -28,10 +28,7 @@ * $FreeBSD$ */ -#include "wasm_log.h" -#include "wasm_platform.h" -#include "wasm_platform_log.h" -#include "wasm_memory.h" +#include "bh_platform.h" #define __FDLIBM_STDC__ @@ -99,6 +96,13 @@ typedef union { } bits; } IEEEd2bits_B; +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + #define __HIL(x) *(1+pdouble2pint(&x)) #define __LOL(x) *(pdouble2pint(&x)) #define __HIB(x) *(int*)&x @@ -179,39 +183,39 @@ typedef union { } while (0) /* Macro wrappers. */ -#define EXTRACT_WORDS(ix0,ix1,d) do { \ - if (is_little_endian) \ - EXTRACT_WORDS_L(ix0,ix1,d); \ - else \ - EXTRACT_WORDS_B(ix0,ix1,d); \ +#define EXTRACT_WORDS(ix0,ix1,d) do { \ + if (is_little_endian()) \ + EXTRACT_WORDS_L(ix0,ix1,d); \ + else \ + EXTRACT_WORDS_B(ix0,ix1,d); \ } while (0) -#define INSERT_WORDS(d,ix0,ix1) do { \ - if (is_little_endian) \ - INSERT_WORDS_L(d,ix0,ix1); \ - else \ - INSERT_WORDS_B(d,ix0,ix1); \ +#define INSERT_WORDS(d,ix0,ix1) do { \ + if (is_little_endian()) \ + INSERT_WORDS_L(d,ix0,ix1); \ + else \ + INSERT_WORDS_B(d,ix0,ix1); \ } while (0) -#define GET_HIGH_WORD(i,d) \ - do { \ - if (is_little_endian) \ - GET_HIGH_WORD_L(i,d); \ - else \ - GET_HIGH_WORD_B(i,d); \ - } while (0) +#define GET_HIGH_WORD(i,d) \ + do { \ + if (is_little_endian()) \ + GET_HIGH_WORD_L(i,d); \ + else \ + GET_HIGH_WORD_B(i,d); \ + } while (0) -#define SET_HIGH_WORD(d,v) \ - do { \ - if (is_little_endian) \ - SET_HIGH_WORD_L(d,v); \ - else \ - SET_HIGH_WORD_B(d,v); \ - } while (0) +#define SET_HIGH_WORD(d,v) \ + do { \ + if (is_little_endian()) \ + SET_HIGH_WORD_L(d,v); \ + else \ + SET_HIGH_WORD_B(d,v); \ + } while (0) -#define __HI(x) (is_little_endian ? __HIL(x) : __HIB(x)) +#define __HI(x) (is_little_endian() ? __HIL(x) : __HIB(x)) -#define __LO(x) (is_little_endian ? __LOL(x) : __LOB(x)) +#define __LO(x) (is_little_endian() ? __LOL(x) : __LOB(x)) /* * Attempt to get strict C99 semantics for assignment with non-C99 compilers. @@ -509,7 +513,7 @@ static double freebsd_rint(double x) static int freebsd_isnan(double d) { - if (is_little_endian) { + if (is_little_endian()) { IEEEd2bits_L u; u.d = d; return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0)); diff --git a/core/shared-lib/platform/zephyr/bh_platform.c b/core/shared-lib/platform/zephyr/bh_platform.c index fe05e8bd1b..7c4263b317 100755 --- a/core/shared-lib/platform/zephyr/bh_platform.c +++ b/core/shared-lib/platform/zephyr/bh_platform.c @@ -25,3 +25,25 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +#ifndef CONFIG_AEE_ENABLE +static int +_stdout_hook_iwasm(int c) +{ + printk("%c", (char)c); + return 1; +} + +int bh_platform_init() +{ + extern void __stdout_hook_install(int (*hook)(int)); + /* Enable printf() in Zephyr */ + __stdout_hook_install(_stdout_hook_iwasm); + return 0; +} +#else +int bh_platform_init() +{ + return 0; +} +#endif diff --git a/core/shared-lib/platform/zephyr/bh_platform.h b/core/shared-lib/platform/zephyr/bh_platform.h index 4e22d90492..2602bee314 100644 --- a/core/shared-lib/platform/zephyr/bh_platform.h +++ b/core/shared-lib/platform/zephyr/bh_platform.h @@ -52,7 +52,6 @@ /* Invalid thread tid */ #define INVALID_THREAD_ID NULL -#define INVALID_SEM_ID SEM_FAILED #define BH_WAIT_FOREVER K_FOREVER typedef uint64_t uint64; @@ -89,6 +88,18 @@ int snprintf(char *buffer, size_t count, const char *format, ...); #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(x) \ do { \ if (!(x)) { \ @@ -96,9 +107,23 @@ int snprintf(char *buffer, size_t count, const char *format, ...); } \ } while (0) -extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, - unsigned int n); -extern int b_strcat_s(char * s1, size_t s1max, const char * s2); -extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); +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); + +/* math functions */ +double sqrt(double x); +double floor(double x); +double ceil(double x); +double fmin(double x, double y); +double fmax(double x, double y); +double rint(double x); +double fabs(double x); +double trunc(double x); +int signbit(double x); +int isnan(double x); + +int bh_platform_init(); #endif diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c index a4313df91f..2b91f0b4c5 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c @@ -16,9 +16,9 @@ #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" diff --git a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt index bd7c016989..a564c6aab9 100644 --- a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt +++ b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt @@ -53,9 +53,8 @@ target_include_directories(app PRIVATE ${IWASM_ROOT}/runtime/include ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr ) -set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c +set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c - ${IWASM_ROOT}/runtime/platform/zephyr/wasm_platform.c ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c ${IWASM_ROOT}/runtime/utils/wasm_log.c @@ -92,6 +91,7 @@ set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_platform_log.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_time.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_alloc.c From d518e64e5929772274801ba17f9f6bded482d718 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Thu, 8 Aug 2019 16:45:04 +0800 Subject: [PATCH 06/18] Enhance wasm loader to fix some security issues --- core/iwasm/lib/native/libc/libc_wrapper.c | 23 +++ core/iwasm/products/linux/main.c | 19 ++- core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 35 ++-- core/iwasm/runtime/vmcore-wasm/wasm_loader.c | 159 +++++++++++++----- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 5 +- 5 files changed, 178 insertions(+), 63 deletions(-) diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index fabc8b8924..74b2c0ccb8 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -846,6 +846,22 @@ nullFunc_X_wrapper(int32 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 } @@ -857,6 +873,10 @@ typedef struct WASMNativeFuncDef { } WASMNativeFuncDef; static WASMNativeFuncDef native_func_defs[] = { +#ifdef ENABLE_SPEC_TEST + REG_NATIVE_FUNC(spectest, print_i32), + REG_NATIVE_FUNC(spectest, print), +#endif REG_NATIVE_FUNC(env, _printf), REG_NATIVE_FUNC(env, _sprintf), REG_NATIVE_FUNC(env, _snprintf), @@ -927,6 +947,9 @@ typedef struct WASMNativeGlobalDef { } 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 }, diff --git a/core/iwasm/products/linux/main.c b/core/iwasm/products/linux/main.c index 9b0dc08ccc..e415de7d41 100644 --- a/core/iwasm/products/linux/main.c +++ b/core/iwasm/products/linux/main.c @@ -129,7 +129,11 @@ app_instance_repl(wasm_module_inst_t module_inst) return NULL; } -static char global_heap_buf[512 * 1024] = { 0 }; +#define USE_GLOBAL_HEAP_BUF 0 + +#if USE_GLOBAL_HEAP_BUF != 0 +static char global_heap_buf[10 * 1024 * 1024] = { 0 }; +#endif int main(int argc, char *argv[]) { @@ -175,11 +179,18 @@ int main(int argc, char *argv[]) app_argc = argc; app_argv = argv; +#if USE_GLOBAL_HEAP_BUF != 0 if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) != 0) { - wasm_printf("Init global heap failed.\n"); + wasm_printf("Init memory with global heap buffer failed.\n"); return -1; } +#else + if (bh_memory_init_with_allocator(malloc, free)) { + wasm_printf("Init memory with memory allocator failed.\n"); + return -1; + } +#endif /* initialize runtime environment */ if (!wasm_runtime_init()) @@ -201,8 +212,8 @@ int main(int argc, char *argv[]) /* instantiate the module */ if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, - 16 * 1024, /* stack size */ - 8 * 1024, /* heap size */ + 64 * 1024, /* stack size */ + 64 * 1024, /* heap size */ error_buf, sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index 73163f32ca..490306db99 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -588,7 +588,7 @@ ALLOC_FRAME(WASMThread *self, uint32 size, WASMInterpFrame *prev_frame) frame->prev_frame = prev_frame; else { wasm_runtime_set_exception(self->module_inst, - "WASM interp failed, alloc frame failed."); + "WASM interp failed: stack overflow."); } return frame; @@ -641,7 +641,7 @@ wasm_interp_call_func_native(WASMThread *self, else { if (!(argv = wasm_malloc(sizeof(uint32) * argc))) { wasm_runtime_set_exception(self->module_inst, - "WASM call native failed: alloc memory for argv failed."); + "WASM call native failed: allocate memory failed."); return; } } @@ -768,7 +768,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, BLOCK_TYPE_BLOCK, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "find block addr failed"); + wasm_runtime_set_exception(module, "find block address failed"); goto got_exception; } @@ -783,7 +783,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, BLOCK_TYPE_LOOP, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "find block addr failed"); + wasm_runtime_set_exception(module, "find block address failed"); goto got_exception; } @@ -798,7 +798,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, BLOCK_TYPE_IF, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "find block addr failed"); + wasm_runtime_set_exception(module, "find block address failed"); goto got_exception; } @@ -855,8 +855,9 @@ wasm_interp_call_func_bytecode(WASMThread *self, depths = depth_buf; else { if (!(depths = wasm_malloc(sizeof(uint32) * count))) { - wasm_runtime_set_exception(module, "WASM interp failed, " - "alloc block memory for br_table failed."); + wasm_runtime_set_exception(module, + "WASM interp failed: " + "allocate memory failed."); goto got_exception; } } @@ -931,7 +932,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_DROP): { wasm_runtime_set_exception(module, - "wasm interp failed: unsupported opcode"); + "WASM interp failed: unsupported opcode."); goto got_exception; } @@ -950,7 +951,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_SELECT): { wasm_runtime_set_exception(module, - "wasm interp failed: unsupported opcode"); + "WASM interp failed: unsupported opcode."); goto got_exception; } @@ -997,7 +998,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, break; default: wasm_runtime_set_exception(module, - "get local type is invalid"); + "invalid local type"); goto got_exception; } (void)local_count; @@ -1026,7 +1027,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, break; default: wasm_runtime_set_exception(module, - "set local type is invalid"); + "invalid local type"); goto got_exception; } (void)local_count; @@ -1054,7 +1055,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, SET_LOCAL_F64(local_idx, GET_F64_FROM_ADDR(frame_sp - 2)); break; default: - wasm_runtime_set_exception(module, "tee local type is invalid"); + wasm_runtime_set_exception(module, "invalid local type"); goto got_exception; } (void)local_count; @@ -1085,7 +1086,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, PUSH_F64(*(float64*)get_global_addr(memory, global)); break; default: - wasm_runtime_set_exception(module, "get global type is invalid"); + wasm_runtime_set_exception(module, "invalid global type"); goto got_exception; } HANDLE_OP_END (); @@ -1117,7 +1118,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, PUT_F64_TO_ADDR((uint32*)global_addr, POP_F64()); break; default: - wasm_runtime_set_exception(module, "set global index is overflow"); + wasm_runtime_set_exception(module, "invalid global type"); goto got_exception; } HANDLE_OP_END (); @@ -1977,7 +1978,8 @@ wasm_interp_call_func_bytecode(WASMThread *self, #if WASM_ENABLE_LABELS_AS_VALUES == 0 default: - wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode"); + wasm_runtime_set_exception(module, + "WASM interp failed: unsupported opcode."); goto got_exception; } #endif @@ -2005,7 +2007,8 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_UNUSED_0x26): HANDLE_OP (WASM_OP_UNUSED_0x27): { - wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode"); + wasm_runtime_set_exception(module, + "WASM interp failed: unsupported opcode."); goto got_exception; } #endif diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index 7b4733eff1..dbf8a4dcd1 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -141,7 +141,8 @@ const_str_set_insert(const uint8 *str, int32 len, WASMModule *module, if (!c_str) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: " + "allocate memory failed."); return NULL; } @@ -234,7 +235,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->type_count = type_count; if (!(module->types = wasm_malloc(sizeof(WASMType*) * type_count))) { set_error_buf(error_buf, error_buf_size, - "Load type section failed: alloc memory failed."); + "Load type section failed: allocate memory failed."); return false; } @@ -256,13 +257,20 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, CHECK_BUF(p, p_end, param_count); p += param_count; read_leb_uint32(p, p_end, result_count); - wasm_assert(result_count <= 1); + if (result_count > 1) { + set_error_buf(error_buf, error_buf_size, + "Load type section failed: invalid result count."); + return false; + } CHECK_BUF(p, p_end, result_count); p = p_org; if (!(type = module->types[i] = wasm_malloc(offsetof(WASMType, types) + - sizeof(uint8) * (param_count + result_count)))) + sizeof(uint8) * (param_count + result_count)))) { + set_error_buf(error_buf, error_buf_size, + "Load type section failed: allocate memory failed."); return false; + } /* Resolve param types and result types */ type->param_count = param_count; @@ -413,7 +421,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->import_count = import_count; if (!(module->imports = wasm_malloc(sizeof(WASMImport) * import_count))) { set_error_buf(error_buf, error_buf_size, - "Load import section failed: alloc memory failed."); + "Load import section failed: allocate memory failed."); return false; } @@ -635,7 +643,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, module->function_count = func_count; if (!(module->functions = wasm_malloc(sizeof(WASMFunction*) * func_count))) { set_error_buf(error_buf, error_buf_size, - "Load function section failed: alloc memory failed."); + "Load function section failed: allocate memory failed."); return false; } @@ -652,7 +660,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, } read_leb_uint32(p_code, buf_code_end, code_size); - if (code_size == 0) { + if (code_size == 0 + || p_code + code_size > buf_code_end) { set_error_buf(error_buf, error_buf_size, "Load function section failed: " "invalid function code size."); @@ -678,7 +687,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, if (!(func = module->functions[i] = wasm_malloc(total_size))) { set_error_buf(error_buf, error_buf_size, - "Load function section failed: alloc memory failed."); + "Load function section failed: " + "allocate memory failed."); return false; } @@ -696,7 +706,20 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, local_type_index = 0; for (j = 0; j < local_set_count; j++) { read_leb_uint32(p_code, buf_code_end, sub_local_count); + if (local_type_index + sub_local_count <= local_type_index + || local_type_index + sub_local_count > local_count) { + set_error_buf(error_buf, error_buf_size, + "Load function section failed: " + "invalid local count."); + return false; + } read_leb_uint8(p_code, buf_code_end, type); + if (type < VALUE_TYPE_F64 || type > VALUE_TYPE_I32) { + set_error_buf(error_buf, error_buf_size, + "Load function section failed: " + "invalid local type."); + return false; + } for (k = 0; k < sub_local_count; k++) { func->local_types[local_type_index++] = type; } @@ -707,8 +730,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, if (p != p_end) { set_error_buf(error_buf, error_buf_size, - "Load function section failed: " - "invalid section size."); + "Load function section failed: " + "invalid section size."); return false; } @@ -735,7 +758,8 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->table_count = table_count; if (!(module->tables = wasm_malloc(sizeof(WASMTable) * table_count))) { set_error_buf(error_buf, error_buf_size, - "Load table section failed: alloc memory failed."); + "Load table section failed: " + "allocate memory failed."); return false; } @@ -777,7 +801,8 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->memory_count = memory_count; if (!(module->memories = wasm_malloc(sizeof(WASMMemory) * memory_count))) { set_error_buf(error_buf, error_buf_size, - "Load memory section failed: alloc memory failed."); + "Load memory section failed: " + "allocate memory failed."); return false; } @@ -814,7 +839,8 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->global_count = global_count; if (!(module->globals = wasm_malloc(sizeof(WASMGlobal) * global_count))) { set_error_buf(error_buf, error_buf_size, - "Load global section failed: alloc memory failed."); + "Load global section failed: " + "allocate memory failed."); return false; } @@ -859,7 +885,8 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->export_count = export_count; if (!(module->exports = wasm_malloc(sizeof(WASMExport) * export_count))) { set_error_buf(error_buf, error_buf_size, - "Load export section failed: alloc memory failed."); + "Load export section failed: " + "allocate memory failed."); return false; } @@ -952,7 +979,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m (sizeof(WASMTableSeg) * table_segment_count))) { set_error_buf(error_buf, error_buf_size, "Load table segment section failed: " - "alloc memory failed."); + "allocate memory failed."); return false; } @@ -974,7 +1001,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m wasm_malloc(sizeof(uint32) * function_count))) { set_error_buf(error_buf, error_buf_size, "Load table segment section failed: " - "alloc memory failed."); + "allocate memory failed."); return false; } for (j = 0; j < function_count; j++) { @@ -1012,8 +1039,8 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end, if (!(module->data_segments = wasm_malloc(sizeof(WASMDataSeg*) * data_seg_count))) { set_error_buf(error_buf, error_buf_size, - "Load data segment section failed, " - "alloc memory failed."); + "Load data segment section failed: " + "allocate memory failed."); return false; } @@ -1031,7 +1058,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end, wasm_malloc(sizeof(WASMDataSeg)))) { set_error_buf(error_buf, error_buf_size, "Load data segment section failed: " - "alloc memory failed."); + "allocate memory failed."); return false; } @@ -1117,12 +1144,6 @@ load_from_sections(WASMModule *module, WASMSection *sections, section = section->next; } - if (!buf_code) { - set_error_buf(error_buf, error_buf_size, - "WASM module load failed: find code section failed."); - return false; - } - section = sections; while (section) { buf = section->section_body; @@ -1140,8 +1161,13 @@ load_from_sections(WASMModule *module, WASMSection *sections, return false; break; case SECTION_TYPE_FUNC: + if (!buf_code) { + set_error_buf(error_buf, error_buf_size, + "WASM module load failed: find code section failed."); + return false; + } if (!load_function_section(buf, buf_end, buf_code, buf_code_end, - module, error_buf, error_buf_size)) + module, error_buf, error_buf_size)) return false; break; case SECTION_TYPE_TABLE: @@ -1229,7 +1255,8 @@ create_module(char *error_buf, uint32 error_buf_size) if (!module) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: " + "allocate memory failed."); return NULL; } @@ -1309,7 +1336,8 @@ create_sections(const uint8 *buf, uint32 size, if (!(section = wasm_malloc(sizeof(WASMSection)))) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: " + "allocate memory failed."); return false; } @@ -1401,7 +1429,7 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu if (!module) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: allocate memory failed."); return NULL; } @@ -1855,9 +1883,11 @@ wasm_loader_find_block_addr(WASMModule *module, break; default: - LOG_ERROR("WASM loader find block addr failed: invalid opcode %02x.\n", - opcode); - break; + if (error_buf) + snprintf(error_buf, error_buf_size, + "WASM loader find block addr failed: " + "invalid opcode %02x.", opcode); + return false; } } @@ -1902,7 +1932,7 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new) if (!mem_new) { \ set_error_buf(error_buf, error_buf_size, \ "WASM loader prepare bytecode failed: " \ - "alloc memory failed"); \ + "allocate memory failed."); \ goto fail; \ } \ mem = mem_new; \ @@ -2201,6 +2231,24 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num, } \ } while (0) +static bool +check_memory(WASMModule *module, + char *error_buf, uint32 error_buf_size) +{ + if (module->memory_count == 0 + && module->import_memory_count == 0) { + set_error_buf(error_buf, error_buf_size, + "load or store in module without default memory"); + return false; + } + return true; +} + +#define CHECK_MEMORY() do { \ + if (!check_memory(module, error_buf, error_buf_size)) \ + goto fail; \ + } while (0) + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, char *error_buf, uint32 error_buf_size) @@ -2235,7 +2283,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, frame_ref_size = 32; if (!(frame_ref_bottom = frame_ref = wasm_malloc(frame_ref_size))) { set_error_buf(error_buf, error_buf_size, - "WASM loader prepare bytecode failed: alloc memory failed"); + "WASM loader prepare bytecode failed: " + "allocate memory failed"); goto fail; } memset(frame_ref_bottom, 0, frame_ref_size); @@ -2244,7 +2293,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, frame_csp_size = sizeof(BranchBlock) * 8; if (!(frame_csp_bottom = frame_csp = wasm_malloc(frame_csp_size))) { set_error_buf(error_buf, error_buf_size, - "WASM loader prepare bytecode failed: alloc memory failed"); + "WASM loader prepare bytecode failed: " + "allocate memory failed"); goto fail; } @@ -2337,7 +2387,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, if (!block) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " - "alloc memory failed"); + "allocate memory failed."); goto fail; } @@ -2350,7 +2400,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, block)) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " - "alloc memory failed"); + "allocate memory failed."); wasm_free(block); goto fail; } @@ -2482,12 +2532,20 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMType *func_type; uint32 type_idx; + if (module->table_count == 0 + && module->import_table_count == 0) { + set_error_buf(error_buf, error_buf_size, + "call indirect without default table"); + goto fail; + } + read_leb_uint32(p, p_end, type_idx); read_leb_uint8(p, p_end, u8); /* 0x00 */ POP_I32(); if (type_idx >= module->type_count) { - set_error_buf(error_buf, error_buf_size, "function index is overflow"); + set_error_buf(error_buf, error_buf_size, + "function index is overflow"); goto fail; } @@ -2618,6 +2676,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_I32_LOAD8_U: case WASM_OP_I32_LOAD16_S: case WASM_OP_I32_LOAD16_U: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2631,6 +2690,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_I64_LOAD16_U: case WASM_OP_I64_LOAD32_S: case WASM_OP_I64_LOAD32_U: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2638,6 +2698,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_F32_LOAD: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2645,6 +2706,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_F64_LOAD: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2654,6 +2716,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_I32_STORE: case WASM_OP_I32_STORE8: case WASM_OP_I32_STORE16: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2664,6 +2727,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_I64_STORE8: case WASM_OP_I64_STORE16: case WASM_OP_I64_STORE32: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I64(); @@ -2671,6 +2735,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_F32_STORE: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_F32(); @@ -2678,6 +2743,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_F64_STORE: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_F64(); @@ -2685,11 +2751,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_MEMORY_SIZE: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* 0x00 */ PUSH_I32(); break; case WASM_OP_MEMORY_GROW: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* 0x00 */ POP_I32(); PUSH_I32(); @@ -2971,15 +3039,24 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; default: - LOG_ERROR("WASM loader find block addr failed: invalid opcode %02x.\n", - opcode); - break; + if (error_buf != NULL) + snprintf(error_buf, error_buf_size, + "WASM module load failed: " + "invalid opcode %02x.", opcode); + goto fail; } if (opcode != WASM_OP_I32_CONST) is_i32_const = false; } + if (csp_num > 0) { + set_error_buf(error_buf, error_buf_size, + "WASM module load failed: " + "function body must end with END opcode."); + goto fail; + } + func->max_stack_cell_num = max_stack_cell_num; func->max_block_num = max_csp_num; return_value = true; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index 7b1c656174..a7a9a87453 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -877,8 +877,9 @@ wasm_runtime_instantiate(WASMModule *module, length = data_seg->data_length; memory_size = NumBytesPerPage * module_inst->default_memory->cur_page_count; - if (base_offset >= memory_size - || base_offset + length > memory_size) { + if (length > 0 + && (base_offset >= memory_size + || base_offset + length > memory_size)) { set_error_buf(error_buf, error_buf_size, "Instantiate module failed: data segment out of range."); wasm_runtime_deinstantiate(module_inst); From 6a318c4d33e6dcc5408cd97be74053f45cc28bcb Mon Sep 17 00:00:00 2001 From: wenyongh Date: Wed, 14 Aug 2019 16:12:04 +0800 Subject: [PATCH 07/18] Fix issue about illegal load of EXC_RETURN into PC on stm32 board --- .../gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c | 3 +++ samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf | 2 ++ .../vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c | 5 ++++- samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf | 2 ++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c index 6c42acc8e1..4868155042 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c @@ -69,6 +69,9 @@ static bool host_init() int host_send(void * ctx, const char *buf, int size) { + if (!uart_dev) + return 0; + for (int i = 0; i < size; i++) uart_poll_out(uart_dev, buf[i]); diff --git a/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf b/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf index 2375969e15..79d8920545 100644 --- a/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf +++ b/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf @@ -5,3 +5,5 @@ CONFIG_PRINTK=y CONFIG_LOG=y #CONFIG_UART_2=y CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_STACK_SENTINEL=y +CONFIG_MAIN_STACK_SIZE=2048 diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c index 1fc3eb941d..64e27d715e 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c @@ -55,7 +55,7 @@ static bool host_init() uart_dev = device_get_binding(HOST_DEVICE_COMM_UART_NAME); if (!uart_dev) { printf("UART: Device driver not found.\n"); - return; + return false; } uart_irq_rx_enable(uart_dev); uart_irq_callback_set(uart_dev, uart_irq_callback); @@ -64,6 +64,9 @@ static bool host_init() int host_send(void * ctx, const char *buf, int size) { + if (!uart_dev) + return 0; + for (int i = 0; i < size; i++) uart_poll_out(uart_dev, buf[i]); diff --git a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf index 2375969e15..79d8920545 100644 --- a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf +++ b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf @@ -5,3 +5,5 @@ CONFIG_PRINTK=y CONFIG_LOG=y #CONFIG_UART_2=y CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_STACK_SENTINEL=y +CONFIG_MAIN_STACK_SIZE=2048 From e119204367e1b66ef329c58c3253a51b4b27cecc Mon Sep 17 00:00:00 2001 From: wenyongh Date: Mon, 19 Aug 2019 15:53:02 +0800 Subject: [PATCH 08/18] Updates that let a restricted version of the interpreter run in SGX --- core/iwasm/lib/native/libc/libc_wrapper_sgx.c | 1026 +++++++++++++++++ core/iwasm/lib/native/libc/wasm_libc.cmake | 2 +- .../iwasm/lib/native/libc/wasm_libc_sgx.cmake | 23 + core/iwasm/products/linux-sgx/CMakeLists.txt | 89 ++ .../iwasm/products/linux-sgx/ext_lib_export.c | 21 + .../platform/include/wasm_platform_log.h | 4 +- .../runtime/platform/linux-sgx/platform.cmake | 25 + .../runtime/platform/linux-sgx/wasm_native.c | 332 ++++++ core/shared-lib/include/bh_common.h | 3 + core/shared-lib/include/config.h | 4 + core/shared-lib/mem-alloc/bh_memory.c | 15 +- core/shared-lib/mem-alloc/ems/ems_alloc.c | 14 +- .../mem-alloc/ems/ems_gc_internal.h | 2 +- core/shared-lib/mem-alloc/ems/ems_kfc.c | 12 +- core/shared-lib/platform/alios/bh_platform.h | 2 + .../shared-lib/platform/linux-sgx/bh_assert.c | 69 ++ .../platform/linux-sgx/bh_definition.c | 81 ++ .../platform/linux-sgx/bh_platform.c | 67 ++ .../platform/linux-sgx/bh_platform.h | 115 ++ .../platform/linux-sgx/bh_platform_log.c | 41 + .../shared-lib/platform/linux-sgx/bh_thread.c | 190 +++ core/shared-lib/platform/linux-sgx/bh_time.c | 80 ++ .../platform/linux-sgx/shared_platform.cmake | 24 + core/shared-lib/platform/linux/bh_platform.h | 2 + .../shared-lib/platform/vxworks/bh_platform.h | 2 + core/shared-lib/platform/zephyr/bh_platform.h | 2 + 26 files changed, 2223 insertions(+), 24 deletions(-) create mode 100644 core/iwasm/lib/native/libc/libc_wrapper_sgx.c create mode 100644 core/iwasm/lib/native/libc/wasm_libc_sgx.cmake create mode 100644 core/iwasm/products/linux-sgx/CMakeLists.txt create mode 100644 core/iwasm/products/linux-sgx/ext_lib_export.c create mode 100644 core/iwasm/runtime/platform/linux-sgx/platform.cmake create mode 100644 core/iwasm/runtime/platform/linux-sgx/wasm_native.c create mode 100644 core/shared-lib/platform/linux-sgx/bh_assert.c create mode 100644 core/shared-lib/platform/linux-sgx/bh_definition.c create mode 100644 core/shared-lib/platform/linux-sgx/bh_platform.c create mode 100644 core/shared-lib/platform/linux-sgx/bh_platform.h create mode 100644 core/shared-lib/platform/linux-sgx/bh_platform_log.c create mode 100644 core/shared-lib/platform/linux-sgx/bh_thread.c create mode 100644 core/shared-lib/platform/linux-sgx/bh_time.c create mode 100644 core/shared-lib/platform/linux-sgx/shared_platform.cmake 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 From 7993bc1f7c92314cff9f449d645f3df7f8d6ea77 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Wed, 21 Aug 2019 16:17:26 +0800 Subject: [PATCH 09/18] Enable native/app address validation and conversion for wasm app --- core/iwasm/lib/native-interface/wasm_export.h | 102 ++ core/iwasm/lib/native/base/base_lib_export.c | 110 ++ core/iwasm/lib/native/libc/libc_wrapper_sgx.c | 1026 ----------------- core/iwasm/lib/native/libc/wasm_libc.cmake | 2 +- .../iwasm/lib/native/libc/wasm_libc_sgx.cmake | 23 - core/iwasm/products/linux-sgx/CMakeLists.txt | 89 -- .../iwasm/products/linux-sgx/ext_lib_export.c | 21 - core/iwasm/runtime/include/wasm_export.h | 7 + .../platform/include/wasm_platform_log.h | 4 +- .../runtime/platform/linux-sgx/platform.cmake | 25 - .../runtime/platform/linux-sgx/wasm_native.c | 332 ------ core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 24 +- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 91 +- core/iwasm/runtime/vmcore-wasm/wasm_runtime.h | 7 + core/shared-lib/include/bh_common.h | 3 - core/shared-lib/include/config.h | 14 +- core/shared-lib/mem-alloc/bh_memory.c | 15 +- core/shared-lib/mem-alloc/ems/ems_alloc.c | 14 +- .../mem-alloc/ems/ems_gc_internal.h | 2 +- core/shared-lib/mem-alloc/ems/ems_kfc.c | 12 +- core/shared-lib/platform/alios/bh_platform.h | 2 - .../shared-lib/platform/linux-sgx/bh_assert.c | 69 -- .../platform/linux-sgx/bh_definition.c | 81 -- .../platform/linux-sgx/bh_platform.c | 67 -- .../platform/linux-sgx/bh_platform.h | 115 -- .../platform/linux-sgx/bh_platform_log.c | 41 - .../shared-lib/platform/linux-sgx/bh_thread.c | 190 --- core/shared-lib/platform/linux-sgx/bh_time.c | 80 -- .../platform/linux-sgx/shared_platform.cmake | 24 - core/shared-lib/platform/linux/bh_platform.h | 2 - .../shared-lib/platform/vxworks/bh_platform.h | 2 - core/shared-lib/platform/zephyr/bh_platform.h | 2 - 32 files changed, 366 insertions(+), 2232 deletions(-) create mode 100644 core/iwasm/lib/native-interface/wasm_export.h delete mode 100644 core/iwasm/lib/native/libc/libc_wrapper_sgx.c delete mode 100644 core/iwasm/lib/native/libc/wasm_libc_sgx.cmake delete mode 100644 core/iwasm/products/linux-sgx/CMakeLists.txt delete mode 100644 core/iwasm/products/linux-sgx/ext_lib_export.c delete mode 100644 core/iwasm/runtime/platform/linux-sgx/platform.cmake delete mode 100644 core/iwasm/runtime/platform/linux-sgx/wasm_native.c delete mode 100644 core/shared-lib/platform/linux-sgx/bh_assert.c delete mode 100644 core/shared-lib/platform/linux-sgx/bh_definition.c delete mode 100644 core/shared-lib/platform/linux-sgx/bh_platform.c delete mode 100644 core/shared-lib/platform/linux-sgx/bh_platform.h delete mode 100644 core/shared-lib/platform/linux-sgx/bh_platform_log.c delete mode 100644 core/shared-lib/platform/linux-sgx/bh_thread.c delete mode 100644 core/shared-lib/platform/linux-sgx/bh_time.c delete mode 100644 core/shared-lib/platform/linux-sgx/shared_platform.cmake diff --git a/core/iwasm/lib/native-interface/wasm_export.h b/core/iwasm/lib/native-interface/wasm_export.h new file mode 100644 index 0000000000..ed9d570f81 --- /dev/null +++ b/core/iwasm/lib/native-interface/wasm_export.h @@ -0,0 +1,102 @@ +/* + * 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 _WASM_EXPORT_H +#define _WASM_EXPORT_H + +#include +#include + +/** + * API exported to WASM application + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get current WASM module instance of the current native thread + * + * @return current WASM module instance of the current native thread, 0 + * if not found + * Note: the return type is uint64_t but not pointer type, because that + * the we only supports WASM-32, in which the pointer type is + * compiled to WASM i32 type, but the pointer type in native can be + * 32-bit and 64-bit. And if the native pointer is 64-bit, data loss + * occurs after converting it to WASM i32 type. + */ +uint64_t +wasm_runtime_get_current_module_inst(); + +/** + * Validate the app address, check whether it belongs to WASM module + * instance's address space, or in its heap space or memory space. + * + * @param module_inst the WASM module instance + * @param app_offset the app address to validate, which is a relative address + * @param size the size bytes of the app address + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_validate_app_addr(uint64_t module_inst, + int32_t app_offset, uint32_t size); + +/** + * Validate the native address, check whether it belongs to WASM module + * instance's address space, or in its heap space or memory space. + * + * @param module_inst the WASM module instance + * @param native_ptr the native address to validate, which is an absolute + * address + * @param size the size bytes of the app address + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_validate_native_addr(uint64_t module_inst, + uint64_t native_ptr, uint32_t size); + +/** + * Convert app address(relative address) to native address(absolute address) + * + * @param module_inst the WASM module instance + * @param app_offset the app adress + * + * @return the native address converted + */ +uint64_t +wasm_runtime_addr_app_to_native(uint64_t module_inst, + int32_t app_offset); + +/** + * Convert native address(absolute address) to app address(relative address) + * + * @param module_inst the WASM module instance + * @param native_ptr the native address + * + * @return the app address converted + */ +int32_t +wasm_runtime_addr_native_to_app(uint64_t module_inst, + uint64_t native_ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of _WASM_EXPORT_H */ diff --git a/core/iwasm/lib/native/base/base_lib_export.c b/core/iwasm/lib/native/base/base_lib_export.c index 4392a7ba4a..353871b6d7 100644 --- a/core/iwasm/lib/native/base/base_lib_export.c +++ b/core/iwasm/lib/native/base/base_lib_export.c @@ -18,11 +18,116 @@ #include #include #include "lib_export.h" +#include "bh_platform.h" +#include "wasm_export.h" #ifdef WASM_ENABLE_BASE_LIB #include "base_lib_export.h" #endif +static uint64 +wasm_runtime_get_current_module_inst_wrapper() +{ + return (uint64)(uintptr_t) + wasm_runtime_get_current_module_inst(); +} + +static bool +wasm_runtime_validate_app_addr_wrapper(uint32 inst_part0, uint32 inst_part1, + int32 app_offset, uint32 size) +{ + bool ret; + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return false; + } + + ret = wasm_runtime_validate_app_addr(module_inst, app_offset, size); + if (!ret) + wasm_runtime_clear_exception(module_inst); + return ret; +} + +static bool +wasm_runtime_validate_native_addr_wrapper(uint32 inst_part0, uint32 inst_part1, + uint32 native_ptr_part0, + uint32 native_ptr_part1, + uint32 size) +{ + bool ret; + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + union { uint64 u64; uint32 parts[2]; } native_ptr; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return false; + } + + native_ptr.parts[0] = native_ptr_part0; + native_ptr.parts[1] = native_ptr_part1; + ret = wasm_runtime_validate_native_addr(module_inst, + (void*)(uintptr_t)native_ptr.u64, + size); + if (!ret) + wasm_runtime_clear_exception(module_inst); + return ret; +} + +static uint64 +wasm_runtime_addr_app_to_native_wrapper(uint32 inst_part0, uint32 inst_part1, + int32 app_offset) +{ + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return 0; + } + return (uint64)(uintptr_t) + wasm_runtime_addr_app_to_native(module_inst, app_offset); +} + +static int32 +wasm_runtime_addr_native_to_app_wrapper(uint32 inst_part0, uint32 inst_part1, + uint32 native_ptr_part0, + uint32 native_ptr_part1) +{ + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + union { uint64 u64; uint32 parts[2]; } native_ptr; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return 0; + } + + native_ptr.parts[0] = native_ptr_part0; + native_ptr.parts[1] = native_ptr_part1; + return wasm_runtime_addr_native_to_app(module_inst, + (void*)(uintptr_t)native_ptr.u64); +} + static NativeSymbol extended_native_symbol_defs[] = { /* TODO: use macro EXPORT_WASM_API() or EXPORT_WASM_API2() to add functions to register. */ @@ -38,6 +143,11 @@ static NativeSymbol extended_native_symbol_defs[] = { EXPORT_WASM_API(wasm_timer_restart), EXPORT_WASM_API(wasm_get_sys_tick_ms), #endif + EXPORT_WASM_API2(wasm_runtime_get_current_module_inst), + EXPORT_WASM_API2(wasm_runtime_validate_app_addr), + EXPORT_WASM_API2(wasm_runtime_validate_native_addr), + EXPORT_WASM_API2(wasm_runtime_addr_app_to_native), + EXPORT_WASM_API2(wasm_runtime_addr_native_to_app), }; int get_base_lib_export_apis(NativeSymbol **p_base_lib_apis) diff --git a/core/iwasm/lib/native/libc/libc_wrapper_sgx.c b/core/iwasm/lib/native/libc/libc_wrapper_sgx.c deleted file mode 100644 index 0b2a21bbf0..0000000000 --- a/core/iwasm/lib/native/libc/libc_wrapper_sgx.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * 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 f70b3b81a7..52e55123f6 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}/libc_wrapper.c) +file (GLOB_RECURSE source_all ${WASM_LIBC_DIR}/*.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 deleted file mode 100644 index c2f8770974..0000000000 --- a/core/iwasm/lib/native/libc/wasm_libc_sgx.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index 4a53f95750..0000000000 --- a/core/iwasm/products/linux-sgx/CMakeLists.txt +++ /dev/null @@ -1,89 +0,0 @@ -# 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 deleted file mode 100644 index 8d78f3ae14..0000000000 --- a/core/iwasm/products/linux-sgx/ext_lib_export.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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/include/wasm_export.h b/core/iwasm/runtime/include/wasm_export.h index 0492fcb441..c62bc8cb61 100644 --- a/core/iwasm/runtime/include/wasm_export.h +++ b/core/iwasm/runtime/include/wasm_export.h @@ -152,6 +152,13 @@ wasm_runtime_instantiate(const wasm_module_t module, void wasm_runtime_deinstantiate(wasm_module_inst_t module_inst); +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 +bool +wasm_runtime_set_ext_memory(wasm_module_inst_t module_inst, + uint8_t *ext_mem_data, uint32_t ext_mem_size, + char *error_buf, uint32_t error_buf_size); +#endif + /** * Load WASM module instance from AOT file. * diff --git a/core/iwasm/runtime/platform/include/wasm_platform_log.h b/core/iwasm/runtime/platform/include/wasm_platform_log.h index e74de3ff24..3fe55bf59c 100644 --- a/core/iwasm/runtime/platform/include/wasm_platform_log.h +++ b/core/iwasm/runtime/platform/include/wasm_platform_log.h @@ -17,9 +17,7 @@ #ifndef _WASM_PLATFORM_LOG #define _WASM_PLATFORM_LOG -#include "bh_platform.h" - -#define wasm_printf bh_printf +#define wasm_printf 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 deleted file mode 100644 index c01fd0e576..0000000000 --- a/core/iwasm/runtime/platform/linux-sgx/platform.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# 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 deleted file mode 100644 index 59b081b7b2..0000000000 --- a/core/iwasm/runtime/platform/linux-sgx/wasm_native.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * 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/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index 490306db99..f0b0beba4f 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -74,6 +74,24 @@ GET_F64_FROM_ADDR (uint32 *addr) } #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 +#define CHECK_EXT_MEMORY_SPACE() \ + else if (module->ext_mem_data \ + && module->ext_mem_base_offset <= offset1 \ + && offset1 < module->ext_mem_base_offset \ + + module->ext_mem_size) { \ + maddr = module->ext_mem_data \ + + (offset1 - module->ext_mem_base_offset); \ + if (maddr < module->ext_mem_data) \ + goto out_of_bounds; \ + maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ + if (maddr1 > module->ext_mem_data_end) \ + goto out_of_bounds; \ + } +#else +#define CHECK_EXT_MEMORY_SPACE() +#endif + #define CHECK_MEMORY_OVERFLOW() do { \ uint32 offset1 = offset + addr; \ uint8 *maddr1; \ @@ -89,7 +107,8 @@ GET_F64_FROM_ADDR (uint32 *addr) if (maddr1 > memory->end_addr) \ goto out_of_bounds; \ } \ - else { \ + else if (offset1 < memory->heap_base_offset \ + + (memory->heap_data_end - memory->heap_data)) { \ maddr = memory->heap_data + offset1 - memory->heap_base_offset; \ if (maddr < memory->heap_data) \ goto out_of_bounds; \ @@ -97,6 +116,9 @@ GET_F64_FROM_ADDR (uint32 *addr) if (maddr1 > memory->heap_data_end) \ goto out_of_bounds; \ } \ + CHECK_EXT_MEMORY_SPACE() \ + else \ + goto out_of_bounds; \ } while (0) static inline uint32 diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index a7a9a87453..35efd7a998 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -992,6 +992,37 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst) wasm_free(module_inst); } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 +bool +wasm_runtime_set_ext_memory(WASMModuleInstance *module_inst, + uint8 *ext_mem_data, uint32 ext_mem_size, + char *error_buf, uint32 error_buf_size) +{ + if (module_inst->ext_mem_data) { + set_error_buf(error_buf, error_buf_size, + "Set external memory failed: " + "an external memory has been set."); + return false; + } + + if (!ext_mem_data + || ext_mem_size > 1 * BH_GB + || ext_mem_data + ext_mem_size < ext_mem_data) { + set_error_buf(error_buf, error_buf_size, + "Set external memory failed: " + "invalid input."); + return false; + } + + module_inst->ext_mem_data = ext_mem_data; + module_inst->ext_mem_data_end = ext_mem_data + ext_mem_size; + module_inst->ext_mem_size = ext_mem_size; + module_inst->ext_mem_base_offset = DEFAULT_EXT_MEM_BASE_OFFSET; + + return true; +} +#endif + bool wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count) { @@ -1166,24 +1197,40 @@ wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst, uint8 *addr; /* integer overflow check */ - if(app_offset < 0 || - app_offset + size < app_offset) { + if(app_offset + size < app_offset) { goto fail; } memory = module_inst->default_memory; - if (app_offset < memory->heap_base_offset) { + if (0 <= app_offset + && app_offset < memory->heap_base_offset) { addr = memory->memory_data + app_offset; if (!(memory->base_addr <= addr && addr + size <= memory->end_addr)) goto fail; return true; } - else { + else if (memory->heap_base_offset < app_offset + && app_offset < memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data)) { addr = memory->heap_data + (app_offset - memory->heap_base_offset); if (!(memory->heap_data <= addr && addr + size <= memory->heap_data_end)) goto fail; return true; } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_base_offset <= app_offset + && app_offset < module_inst->ext_mem_base_offset + + module_inst->ext_mem_size) { + addr = module_inst->ext_mem_data + + (app_offset - module_inst->ext_mem_base_offset); + if (!(module_inst->ext_mem_data <= addr + && addr + size <= module_inst->ext_mem_data_end)) + goto fail; + + return true; + } +#endif fail: wasm_runtime_set_exception(module_inst, "out of bounds memory access"); @@ -1202,7 +1249,13 @@ wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst, } if ((memory->base_addr <= addr && addr + size <= memory->end_addr) - || (memory->heap_data <= addr && addr + size <= memory->heap_data_end)) + || (memory->heap_data <= addr && addr + size <= memory->heap_data_end) +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + || (module_inst->ext_mem_data + && module_inst->ext_mem_data <= addr + && addr + size <= module_inst->ext_mem_data_end) +#endif + ) return true; fail: @@ -1215,10 +1268,22 @@ wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst, int32 app_offset) { WASMMemoryInstance *memory = module_inst->default_memory; - if (app_offset < memory->heap_base_offset) + if (0 <= app_offset && app_offset < memory->heap_base_offset) return memory->memory_data + app_offset; - else + else if (memory->heap_base_offset < app_offset + && app_offset < memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data)) return memory->heap_data + (app_offset - memory->heap_base_offset); +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_base_offset <= app_offset + && app_offset < module_inst->ext_mem_base_offset + + module_inst->ext_mem_size) + return module_inst->ext_mem_data + + (app_offset - module_inst->ext_mem_base_offset); +#endif + else + return NULL; } int32 @@ -1229,9 +1294,19 @@ wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst, if (memory->base_addr <= (uint8*)native_ptr && (uint8*)native_ptr < memory->end_addr) return (uint8*)native_ptr - memory->memory_data; - else + else if (memory->heap_data <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->heap_data_end) return memory->heap_base_offset + ((uint8*)native_ptr - memory->heap_data); +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_data <= (uint8*)native_ptr + && (uint8*)native_ptr < module_inst->ext_mem_data_end) + return module_inst->ext_mem_base_offset + + ((uint8*)native_ptr - module_inst->ext_mem_data); +#endif + else + return 0; } uint32 diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h index 56e806b94c..30ef58c335 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h @@ -148,6 +148,13 @@ typedef struct WASMModuleInstance { uint32 temp_ret; uint32 llvm_stack; +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + int32 ext_mem_base_offset; + uint8 *ext_mem_data; + uint8 *ext_mem_data_end; + uint32 ext_mem_size; +#endif + /* Default WASM stack size of threads of this Module instance. */ uint32 wasm_stack_size; diff --git a/core/shared-lib/include/bh_common.h b/core/shared-lib/include/bh_common.h index a8176dc7f9..9a3366ce16 100755 --- a/core/shared-lib/include/bh_common.h +++ b/core/shared-lib/include/bh_common.h @@ -23,9 +23,6 @@ #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 4ece2251df..b36753c102 100644 --- a/core/shared-lib/include/config.h +++ b/core/shared-lib/include/config.h @@ -26,9 +26,7 @@ #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 @@ -45,9 +43,7 @@ #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 @@ -119,3 +115,13 @@ #define APP_THREAD_STACK_SIZE_MAX (256 * 1024) #endif #endif + +/* External memory space provided by user, + but not wasm memory space and app heap space */ +#ifndef WASM_ENABLE_EXT_MEMORY_SPACE +#define WASM_ENABLE_EXT_MEMORY_SPACE 0 +#endif + +/* Default base offset of external memory space */ +#define DEFAULT_EXT_MEM_BASE_OFFSET (-2 * BH_GB) + diff --git a/core/shared-lib/mem-alloc/bh_memory.c b/core/shared-lib/mem-alloc/bh_memory.c index f0a6641e5e..bca6970518 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; } - bh_printf("Init memory with pool (%p, %u) failed.\n", mem, bytes); + 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; } - bh_printf("Init memory with allocator (%p, %p) failed.\n", _malloc_func, + 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) { - bh_printf("bh_malloc failed: memory hasn't been initialize.\n"); + 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) { - bh_printf("bh_free failed: memory hasn't been initialize.\n"); + 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) { - bh_printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n", + 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) { - bh_printf("location:%s@%d:used:%d:contribution:%d\n", + printf("location:%s@%d:used:%d:contribution:%d\n", func, line, memory_in_use, alloc); } @@ -328,3 +328,4 @@ 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 2c27b71cf6..d8682b6c7b 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) { - bh_printf("[GC_ERROR]couldn't find the node in the normal list"); + 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 - bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size); + 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 - bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size); + 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 - bh_printf("HEAP.FREE, heap: %p, size: %u\n",heap, size); + 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) { - bh_printf("heap: %p, heap start: %p\n", heap, heap->base_addr); - bh_printf( + printf("heap: %p, heap start: %p\n", heap, heap->base_addr); + 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); - bh_printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n", + 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 51308d2a9b..b717971aee 100644 --- a/core/shared-lib/mem-alloc/ems/ems_gc_internal.h +++ b/core/shared-lib/mem-alloc/ems/ems_gc_internal.h @@ -21,7 +21,6 @@ extern "C" { #endif -#include "bh_platform.h" #include "bh_thread.h" #include "bh_memory.h" #include "bh_assert.h" @@ -280,3 +279,4 @@ 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 0090c317bf..791a298a50 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)) { \ - bh_printf("Platform checking failed on LINE %d at FILE %s.", \ + 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) { - bh_printf("Check platform compatibility failed"); + printf("Check platform compatibility failed"); return NULL; } if (buf_size < 1024) { - bh_printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size); + 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) { - bh_printf("[GC_ERROR]failed to init lock "); + printf("[GC_ERROR]failed to init lock "); return NULL; } #ifdef BH_FOOTPRINT - bh_printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size); + 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 - bh_printf("heap is successfully initialized with max_size=%u.", + 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 468d0b4e96..e23958c95d 100644 --- a/core/shared-lib/platform/alios/bh_platform.h +++ b/core/shared-lib/platform/alios/bh_platform.h @@ -52,8 +52,6 @@ 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 deleted file mode 100644 index b52a9aa5ba..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_assert.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 deleted file mode 100644 index 5105d0ff83..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_definition.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2166d53abf..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_platform.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 deleted file mode 100644 index 59cbb6d598..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_platform.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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 deleted file mode 100644 index 4ff03192a7..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_platform_log.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8730e13cd6..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_thread.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0627b08d0c..0000000000 --- a/core/shared-lib/platform/linux-sgx/bh_time.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 deleted file mode 100644 index 5b403a09cc..0000000000 --- a/core/shared-lib/platform/linux-sgx/shared_platform.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# 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 2ee9e24f3c..47172c1f68 100644 --- a/core/shared-lib/platform/linux/bh_platform.h +++ b/core/shared-lib/platform/linux/bh_platform.h @@ -77,8 +77,6 @@ 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 c023549da3..142583e5b5 100644 --- a/core/shared-lib/platform/vxworks/bh_platform.h +++ b/core/shared-lib/platform/vxworks/bh_platform.h @@ -75,8 +75,6 @@ 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 45f8e14eee..2602bee314 100644 --- a/core/shared-lib/platform/zephyr/bh_platform.h +++ b/core/shared-lib/platform/zephyr/bh_platform.h @@ -78,8 +78,6 @@ 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 From 6dc3e9893625243a4fb2d639d51ede149e33df58 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Wed, 21 Aug 2019 16:33:58 +0800 Subject: [PATCH 10/18] Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused --- core/iwasm/products/alios-things/src/main.c | 14 +++++++++ core/iwasm/products/linux/main.c | 29 +++++++++++++++++++ core/iwasm/products/vxworks/main.c | 29 +++++++++++++++++++ core/iwasm/products/zephyr/simple/src/main.c | 14 +++++++++ core/iwasm/runtime/include/wasm_export.h | 30 -------------------- 5 files changed, 86 insertions(+), 30 deletions(-) diff --git a/core/iwasm/products/alios-things/src/main.c b/core/iwasm/products/alios-things/src/main.c index 395c9b852b..336247856a 100644 --- a/core/iwasm/products/alios-things/src/main.c +++ b/core/iwasm/products/alios-things/src/main.c @@ -29,6 +29,20 @@ static int app_argc; static char **app_argv; +/** + * Find the unique main function from a WASM module instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the main function is called, false otherwise. + */ +bool +wasm_application_execute_main(wasm_module_inst_t module_inst, + int argc, char *argv[]); + static void* app_instance_main(wasm_module_inst_t module_inst) { diff --git a/core/iwasm/products/linux/main.c b/core/iwasm/products/linux/main.c index e415de7d41..86c6e5e753 100644 --- a/core/iwasm/products/linux/main.c +++ b/core/iwasm/products/linux/main.c @@ -46,6 +46,35 @@ static int print_help() return 1; } +/** + * Find the unique main function from a WASM module instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the main function is called, false otherwise. + */ +bool +wasm_application_execute_main(wasm_module_inst_t module_inst, + int argc, char *argv[]); + +/** + * Find the specified function in argv[0] from WASM module of current instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param name the name of the function to execute + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the specified function is called, false otherwise. + */ +bool +wasm_application_execute_func(wasm_module_inst_t module_inst, + const char *name, int argc, char *argv[]); + static void* app_instance_main(wasm_module_inst_t module_inst) { diff --git a/core/iwasm/products/vxworks/main.c b/core/iwasm/products/vxworks/main.c index dc26304288..a1a503f319 100644 --- a/core/iwasm/products/vxworks/main.c +++ b/core/iwasm/products/vxworks/main.c @@ -46,6 +46,35 @@ static int print_help() return 1; } +/** + * Find the unique main function from a WASM module instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the main function is called, false otherwise. + */ +bool +wasm_application_execute_main(wasm_module_inst_t module_inst, + int argc, char *argv[]); + +/** + * Find the specified function in argv[0] from WASM module of current instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param name the name of the function to execute + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the specified function is called, false otherwise. + */ +bool +wasm_application_execute_func(wasm_module_inst_t module_inst, + const char *name, int argc, char *argv[]); + static void* app_instance_main(wasm_module_inst_t module_inst) { diff --git a/core/iwasm/products/zephyr/simple/src/main.c b/core/iwasm/products/zephyr/simple/src/main.c index a6a9260a79..fee58f9def 100644 --- a/core/iwasm/products/zephyr/simple/src/main.c +++ b/core/iwasm/products/zephyr/simple/src/main.c @@ -29,6 +29,20 @@ static int app_argc; static char **app_argv; +/** + * Find the unique main function from a WASM module instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the main function is called, false otherwise. + */ +bool +wasm_application_execute_main(wasm_module_inst_t module_inst, + int argc, char *argv[]); + static void* app_instance_main(wasm_module_inst_t module_inst) { diff --git a/core/iwasm/runtime/include/wasm_export.h b/core/iwasm/runtime/include/wasm_export.h index c62bc8cb61..61de096787 100644 --- a/core/iwasm/runtime/include/wasm_export.h +++ b/core/iwasm/runtime/include/wasm_export.h @@ -391,36 +391,6 @@ int32_t wasm_runtime_addr_native_to_app(wasm_module_inst_t module_inst, void *native_ptr); -/** - * Find the unique main function from a WASM module instance - * and execute that function. - * - * @param module_inst the WASM module instance - * @param argc the number of arguments - * @param argv the arguments array - * - * @return true if the main function is called, false otherwise. - */ -bool -wasm_application_execute_main(wasm_module_inst_t module_inst, - int argc, char *argv[]); - -/** - * Find the specified function in argv[0] from WASM module of current instance - * and execute that function. - * - * @param module_inst the WASM module instance - * @param name the name of the function to execute - * @param argc the number of arguments - * @param argv the arguments array - * - * @return true if the specified function is called, false otherwise. - */ -bool -wasm_application_execute_func(wasm_module_inst_t module_inst, - const char *name, int argc, char *argv[]); - - #ifdef __cplusplus } #endif From 49429b11d935ee40e0dca108fc0e99a2b73c0c28 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Tue, 27 Aug 2019 13:51:35 +0800 Subject: [PATCH 11/18] Refine binary size and fix several minor issues Optimize interpreter LOAD/STORE opcodes to decrease the binary size Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper Add macros of global heap size, stack size, heap size for Zephyr main.c Clear compile warning of wasm_application.c --- core/iwasm/lib/native/libc/libc_wrapper.c | 17 -- core/iwasm/products/linux/CMakeLists.txt | 7 +- core/iwasm/products/zephyr/simple/src/main.c | 31 +-- core/iwasm/runtime/include/bh_memory.h | 110 ++++++++++ .../runtime/vmcore-wasm/wasm_application.c | 7 +- core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 192 ++++++++++++------ core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 17 +- 7 files changed, 274 insertions(+), 107 deletions(-) create mode 100644 core/iwasm/runtime/include/bh_memory.h diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index 74b2c0ccb8..d443888cf6 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -984,23 +984,6 @@ wasm_native_global_lookup(const char *module_name, const char *global_name, global_def++; } - /* Lookup non-constant globals which cannot be defined by table */ - if (!strcmp(module_name, "env")) { - 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; - } - } - return false; } diff --git a/core/iwasm/products/linux/CMakeLists.txt b/core/iwasm/products/linux/CMakeLists.txt index a2510790e4..6e89367075 100644 --- a/core/iwasm/products/linux/CMakeLists.txt +++ b/core/iwasm/products/linux/CMakeLists.txt @@ -68,6 +68,7 @@ include (../../lib/native/base/wasm_lib_base.cmake) include (../../lib/native/libc/wasm_libc.cmake) include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake) +include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) add_library (vmlib ${WASM_PLATFORM_LIB_SOURCE} @@ -76,7 +77,8 @@ add_library (vmlib ${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIBC_SOURCE} ${PLATFORM_SHARED_SOURCE} - ${MEM_ALLOC_SHARED_SOURCE}) + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) add_executable (iwasm main.c ext_lib_export.c) @@ -91,7 +93,8 @@ add_library (libiwasm SHARED ${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIBC_SOURCE} ${PLATFORM_SHARED_SOURCE} - ${MEM_ALLOC_SHARED_SOURCE}) + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) install (TARGETS libiwasm DESTINATION lib) diff --git a/core/iwasm/products/zephyr/simple/src/main.c b/core/iwasm/products/zephyr/simple/src/main.c index fee58f9def..da85a3bba4 100644 --- a/core/iwasm/products/zephyr/simple/src/main.c +++ b/core/iwasm/products/zephyr/simple/src/main.c @@ -26,6 +26,11 @@ #include "bh_memory.h" #include "test_wasm.h" +#define CONFIG_GLOBAL_HEAP_BUF_SIZE 131072 +#define CONFIG_APP_STACK_SIZE 8192 +#define CONFIG_APP_HEAP_SIZE 8192 +#define CONFIG_MAIN_THREAD_STACK_SIZE 4096 + static int app_argc; static char **app_argv; @@ -54,7 +59,7 @@ app_instance_main(wasm_module_inst_t module_inst) return NULL; } -static char global_heap_buf[512 * 1024] = { 0 }; +static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 }; void iwasm_main(void *arg1, void *arg2, void *arg3) { @@ -72,7 +77,7 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) (void) arg3; if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) - != 0) { + != 0) { wasm_printf("Init global heap failed.\n"); return; } @@ -91,14 +96,17 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) /* load WASM module */ if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, - error_buf, sizeof(error_buf)))) { + error_buf, sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); goto fail2; } /* instantiate the module */ - if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024, - 8 * 1024, error_buf, sizeof(error_buf)))) { + if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, + CONFIG_APP_STACK_SIZE, + CONFIG_APP_HEAP_SIZE, + error_buf, + sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); goto fail3; } @@ -119,24 +127,23 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) fail1: bh_memory_destroy(); } -#define DEFAULT_THREAD_STACKSIZE (6 * 1024) -#define DEFAULT_THREAD_PRIORITY 5 +#define MAIN_THREAD_STACK_SIZE (CONFIG_MAIN_THREAD_STACK_SIZE) +#define MAIN_THREAD_PRIORITY 5 -K_THREAD_STACK_DEFINE(iwasm_main_thread_stack, DEFAULT_THREAD_STACKSIZE); +K_THREAD_STACK_DEFINE(iwasm_main_thread_stack, MAIN_THREAD_STACK_SIZE); static struct k_thread iwasm_main_thread; bool iwasm_init(void) { k_tid_t tid = k_thread_create(&iwasm_main_thread, iwasm_main_thread_stack, - DEFAULT_THREAD_STACKSIZE, iwasm_main, NULL, NULL, NULL, - DEFAULT_THREAD_PRIORITY, 0, K_NO_WAIT); + MAIN_THREAD_STACK_SIZE, + iwasm_main, NULL, NULL, NULL, + MAIN_THREAD_PRIORITY, 0, K_NO_WAIT); return tid ? true : false; } -#ifndef CONFIG_AEE_ENABLE void main(void) { iwasm_init(); } -#endif diff --git a/core/iwasm/runtime/include/bh_memory.h b/core/iwasm/runtime/include/bh_memory.h new file mode 100644 index 0000000000..352137a347 --- /dev/null +++ b/core/iwasm/runtime/include/bh_memory.h @@ -0,0 +1,110 @@ +/* + * 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_MEMORY_H +#define _BH_MEMORY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BH_KB (1024) +#define BH_MB ((BH_KB)*1024) +#define BH_GB ((BH_MB)*1024) + +/** + * Initialize memory allocator with a pool, the bh_malloc/bh_free function + * will malloc/free memory from the pool + * + * @param mem the pool buffer + * @param bytes the size bytes of the buffer + * + * @return 0 if success, -1 otherwise + */ +int bh_memory_init_with_pool(void *mem, unsigned int bytes); + +/** + * Initialize memory allocator with memory allocator, the bh_malloc/bh_free + * function will malloc/free memory with the allocator passed + * + * @param malloc_func the malloc function + * @param free_func the free function + * + * @return 0 if success, -1 otherwise + */ +int bh_memory_init_with_allocator(void *malloc_func, void *free_func); + +/** + * Destroy memory + */ +void bh_memory_destroy(); + +/** + * Get the pool size of memory, if memory is initialized with allocator, + * return 1GB by default. + */ +int bh_memory_pool_size(); + +#if BEIHAI_ENABLE_MEMORY_PROFILING == 0 + +/** + * This function allocates a memory chunk from system + * + * @param size bytes need allocate + * + * @return the pointer to memory allocated + */ +void* bh_malloc(unsigned int size); + +/** + * This function frees memory chunk + * + * @param ptr the pointer to memory need free + */ +void bh_free(void *ptr); + +#else + +void* bh_malloc_profile(const char *file, int line, const char *func, unsigned int size); +void bh_free_profile(const char *file, int line, const char *func, void *ptr); + +#define bh_malloc(size) bh_malloc_profile(__FILE__, __LINE__, __func__, size) +#define bh_free(ptr) bh_free_profile(__FILE__, __LINE__, __func__, ptr) + +/** + * Print current memory profiling data + * + * @param file file name of the caller + * @param line line of the file of the caller + * @param func function name of the caller + */ +void memory_profile_print(const char *file, int line, const char *func, int alloc); + +/** + * Summarize memory usage and print it out + * Can use awk to analyze the output like below: + * awk -F: '{print $2,$4,$6,$8,$9}' OFS="\t" ./out.txt | sort -n -r -k 1 + */ +void memory_usage_summarize(); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _BH_MEMORY_H */ + diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_application.c b/core/iwasm/runtime/vmcore-wasm/wasm_application.c index 5073ef2e37..cdcb568093 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_application.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_application.c @@ -293,10 +293,15 @@ wasm_application_execute_func(WASMModuleInstance *module_inst, break; case VALUE_TYPE_I64: { + char buf[16]; union { uint64 val; uint32 parts[2]; } u; u.parts[0] = argv1[0]; u.parts[1] = argv1[1]; - wasm_printf("0x%llx:i64", u.val); + if (sizeof(long) == 4) + snprintf(buf, sizeof(buf), "%s", "0x%llx:i64"); + else + snprintf(buf, sizeof(buf), "%s", "0x%lx:i64"); + wasm_printf(buf, u.val); break; } case VALUE_TYPE_F32: diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index f0b0beba4f..04cf744008 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -753,7 +753,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0; int32 didx, val; uint8 *else_addr, *end_addr; - uint8 *maddr; + uint8 *maddr = NULL; #if WASM_ENABLE_LABELS_AS_VALUES != 0 #define HANDLE_OPCODE(op) &&HANDLE_##op @@ -1148,70 +1148,98 @@ wasm_interp_call_func_bytecode(WASMThread *self, /* memory load instructions */ HANDLE_OP (WASM_OP_I32_LOAD): - DEF_OP_LOAD(PUSH_I32(*(int32*)maddr)); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD): - DEF_OP_LOAD(PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_F32_LOAD): - DEF_OP_LOAD(PUSH_F32(*(float32*)maddr)); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_F64_LOAD): - DEF_OP_LOAD(PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD8_S): - DEF_OP_LOAD(PUSH_I32(sign_ext_8_32(*(int8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD8_U): - DEF_OP_LOAD(PUSH_I32((uint32)(*(uint8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD16_S): - DEF_OP_LOAD(PUSH_I32(sign_ext_16_32(*(int16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD16_U): - DEF_OP_LOAD(PUSH_I32((uint32)(*(uint16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD8_S): - DEF_OP_LOAD(PUSH_I64(sign_ext_8_64(*(int8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD8_U): - DEF_OP_LOAD(PUSH_I64((uint64)(*(uint8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD16_S): - DEF_OP_LOAD(PUSH_I64(sign_ext_16_64(*(int16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD16_U): - DEF_OP_LOAD(PUSH_I64((uint64)(*(uint16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD32_S): - DEF_OP_LOAD(PUSH_I64(sign_ext_32_64(*(int32*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD32_U): - DEF_OP_LOAD(PUSH_I64((uint64)(*(uint32*)maddr))); - HANDLE_OP_END (); + { + uint32 offset, flags, addr; + GET_OPCODE(); + read_leb_uint32(frame_ip, frame_ip_end, flags); + read_leb_uint32(frame_ip, frame_ip_end, offset); + addr = POP_I32(); + CHECK_MEMORY_OVERFLOW(); +#if WASM_ENABLE_LABELS_AS_VALUES != 0 + static const void *handle_load_table[] = { + &&HANDLE_LOAD_WASM_OP_I32_LOAD, + &&HANDLE_LOAD_WASM_OP_I64_LOAD, + &&HANDLE_LOAD_WASM_OP_F32_LOAD, + &&HANDLE_LOAD_WASM_OP_F64_LOAD, + &&HANDLE_LOAD_WASM_OP_I32_LOAD8_S, + &&HANDLE_LOAD_WASM_OP_I32_LOAD8_U, + &&HANDLE_LOAD_WASM_OP_I32_LOAD16_S, + &&HANDLE_LOAD_WASM_OP_I32_LOAD16_U, + &&HANDLE_LOAD_WASM_OP_I64_LOAD8_S, + &&HANDLE_LOAD_WASM_OP_I64_LOAD8_U, + &&HANDLE_LOAD_WASM_OP_I64_LOAD16_S, + &&HANDLE_LOAD_WASM_OP_I64_LOAD16_U, + &&HANDLE_LOAD_WASM_OP_I64_LOAD32_S, + &&HANDLE_LOAD_WASM_OP_I64_LOAD32_U + }; + #define HANDLE_OP_LOAD(opcode) HANDLE_LOAD_##opcode + goto *handle_load_table[opcode - WASM_OP_I32_LOAD]; +#else + #define HANDLE_OP_LOAD(opcode) case opcode + switch (opcode) +#endif + { + HANDLE_OP_LOAD(WASM_OP_I32_LOAD): + PUSH_I32(*(int32*)maddr); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD): + PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_F32_LOAD): + PUSH_F32(*(float32*)maddr); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_F64_LOAD): + PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_S): + PUSH_I32(sign_ext_8_32(*(int8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_U): + PUSH_I32((uint32)(*(uint8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_S): + PUSH_I32(sign_ext_16_32(*(int16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_U): + PUSH_I32((uint32)(*(uint16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_S): + PUSH_I64(sign_ext_8_64(*(int8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_U): + PUSH_I64((uint64)(*(uint8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_S): + PUSH_I64(sign_ext_16_64(*(int16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_U): + PUSH_I64((uint64)(*(uint16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_S): + PUSH_I64(sign_ext_32_64(*(int32*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_U): + PUSH_I64((uint64)(*(uint32*)maddr)); + HANDLE_OP_END(); + } + (void)flags; + HANDLE_OP_END (); + } /* memory store instructions */ - HANDLE_OP (WASM_OP_I32_STORE): - DEF_OP_STORE(uint32, I32, *(int32*)maddr = sval); - HANDLE_OP_END (); - - HANDLE_OP (WASM_OP_I64_STORE): - DEF_OP_STORE(uint64, I64, PUT_I64_TO_ADDR((uint32*)maddr, sval)); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_F32_STORE): { uint32 offset, flags, addr; @@ -1241,25 +1269,63 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP_END (); } + HANDLE_OP (WASM_OP_I32_STORE): HANDLE_OP (WASM_OP_I32_STORE8): - DEF_OP_STORE(uint32, I32, *(uint8*)maddr = (uint8)sval); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_STORE16): - DEF_OP_STORE(uint32, I32, *(uint16*)maddr = (uint16)sval); - HANDLE_OP_END (); + { + uint32 offset, flags, addr; + uint32 sval; + GET_OPCODE(); + read_leb_uint32(frame_ip, frame_ip_end, flags); + read_leb_uint32(frame_ip, frame_ip_end, offset); + sval = POP_I32(); + addr = POP_I32(); + CHECK_MEMORY_OVERFLOW(); + switch (opcode) { + case WASM_OP_I32_STORE: + *(int32*)maddr = sval; + break; + case WASM_OP_I32_STORE8: + *(uint8*)maddr = (uint8)sval; + break; + case WASM_OP_I32_STORE16: + *(uint16*)maddr = (uint16)sval; + break; + } + (void)flags; + HANDLE_OP_END (); + } + HANDLE_OP (WASM_OP_I64_STORE): HANDLE_OP (WASM_OP_I64_STORE8): - DEF_OP_STORE(uint64, I64, *(uint8*)maddr = (uint8)sval); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_STORE16): - DEF_OP_STORE(uint64, I64, *(uint16*)maddr = (uint16)sval); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_STORE32): - DEF_OP_STORE(uint64, I64, *(uint32*)maddr = (uint32)sval); - HANDLE_OP_END (); + { + uint32 offset, flags, addr; + uint64 sval; + GET_OPCODE(); + read_leb_uint32(frame_ip, frame_ip_end, flags); + read_leb_uint32(frame_ip, frame_ip_end, offset); + sval = POP_I64(); + addr = POP_I32(); + CHECK_MEMORY_OVERFLOW(); + switch (opcode) { + case WASM_OP_I64_STORE: + PUT_I64_TO_ADDR((uint32*)maddr, sval); + break; + case WASM_OP_I64_STORE8: + *(uint8*)maddr = (uint8)sval; + break; + case WASM_OP_I64_STORE16: + *(uint16*)maddr = (uint16)sval; + break; + case WASM_OP_I64_STORE32: + *(uint32*)maddr = (uint32)sval; + break; + } + (void)flags; + HANDLE_OP_END (); + } /* memory size and memory grow instructions */ HANDLE_OP (WASM_OP_MEMORY_SIZE): diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index 35efd7a998..ec37222bd0 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -947,18 +947,11 @@ wasm_runtime_instantiate(WASMModule *module, wasm_runtime_set_tlr(&module_inst->main_tlr); module_inst->main_tlr.handle = ws_self_thread(); - /* Execute __post_instantiate function */ - if (!execute_post_inst_function(module_inst)) { - const char *exception = wasm_runtime_get_exception(module_inst); - wasm_printf("%s\n", exception); - wasm_runtime_deinstantiate(module_inst); - return NULL; - } - - /* Execute start function */ - if (!execute_start_function(module_inst)) { - const char *exception = wasm_runtime_get_exception(module_inst); - wasm_printf("%s\n", exception); + /* Execute __post_instantiate and start function */ + if (!execute_post_inst_function(module_inst) + || !execute_start_function(module_inst)) { + set_error_buf(error_buf, error_buf_size, + module_inst->cur_exception); wasm_runtime_deinstantiate(module_inst); return NULL; } From ad5f4fc0718a7da0d8c82c7eaa04f20819992a0b Mon Sep 17 00:00:00 2001 From: wenyongh Date: Wed, 28 Aug 2019 13:52:26 +0800 Subject: [PATCH 12/18] Add more strict security checks for libc wrapper API's --- core/iwasm/lib/native/libc/libc_wrapper.c | 101 +++++++++++++----- core/iwasm/runtime/include/wasm_export.h | 32 ++++++ core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 78 ++++++++++++++ 3 files changed, 187 insertions(+), 24 deletions(-) diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index d443888cf6..6d3ac0c9f5 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -52,6 +52,29 @@ wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack); #define module_free(offset) \ wasm_runtime_module_free(module_inst, offset) +static bool +validate_str_addr(wasm_module_inst_t module_inst, int32 str_offset) +{ + int32 app_end_offset; + char *str, *str_end; + + if (!wasm_runtime_get_app_addr_range(module_inst, str_offset, + NULL, &app_end_offset)) + goto fail; + + str = addr_app_to_native(str_offset); + str_end = str + (app_end_offset - str_offset); + while (str < str_end && *str != '\0') + str++; + if (str == str_end) + goto fail; + return true; + +fail: + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; +} + typedef int (*out_func_t)(int c, void *ctx); enum pad_type { @@ -64,9 +87,14 @@ enum pad_type { typedef char *_va_list; #define _INTSIZEOF(n) \ ((sizeof(n) + 3) & ~3) -#define _va_arg(ap,t) \ +#define _va_arg(ap, t) \ (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) +#define CHECK_VA_ARG(ap, t) do { \ + if ((uint8*)ap + _INTSIZEOF(t) > native_end_addr) \ + goto fail; \ +} while (0) + /** * @brief Output an unsigned int in hex format * @@ -172,14 +200,19 @@ print_err(out_func_t out, void *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) +static bool +_vprintf_wa(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; + uint8 *native_end_addr; + + if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)ap, + NULL, &native_end_addr)) + goto fail; /* fmt has already been adjusted if needed */ @@ -232,10 +265,13 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, int32 d; if (long_ctr < 2) { + CHECK_VA_ARG(ap, int32); d = _va_arg(ap, int32); } else { - int64 lld = _va_arg(ap, int64); + int64 lld; + CHECK_VA_ARG(ap, int64); + lld = _va_arg(ap, int64); if (lld > INT32_MAX || lld < INT32_MIN) { print_err(out, ctx); break; @@ -255,10 +291,13 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, uint32 u; if (long_ctr < 2) { + CHECK_VA_ARG(ap, uint32); u = _va_arg(ap, uint32); } else { - uint64 llu = _va_arg(ap, uint64); + uint64 llu; + CHECK_VA_ARG(ap, uint64); + llu = _va_arg(ap, uint64); if (llu > INT32_MAX) { print_err(out, ctx); break; @@ -281,8 +320,10 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, bool is_ptr = (*fmt == 'p') ? true : false; if (long_ctr < 2) { + CHECK_VA_ARG(ap, uint32); x = _va_arg(ap, uint32); } else { + CHECK_VA_ARG(ap, uint64); x = _va_arg(ap, uint64); } _printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width); @@ -292,11 +333,13 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, case 's': { char *s; char *start; - int32 s_offset = _va_arg(ap, uint32); + int32 s_offset; - if (!validate_app_addr(s_offset, 1)) { - wasm_runtime_set_exception(module_inst, "out of bounds memory access"); - return; + CHECK_VA_ARG(ap, uint32); + s_offset = _va_arg(ap, uint32); + + if (!validate_str_addr(module_inst, s_offset)) { + return false; } s = start = addr_app_to_native(s_offset); @@ -314,7 +357,9 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, } case 'c': { - int c = _va_arg(ap, int); + int c; + CHECK_VA_ARG(ap, int); + c = _va_arg(ap, int); out(c, ctx); break; } @@ -336,6 +381,11 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, still_might_format: ++fmt; } + return true; + +fail: + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; } struct str_context { @@ -391,7 +441,7 @@ parse_printf_args(wasm_module_inst_t module_inst, int32 fmt_offset, _va_list v; } u; - if (!validate_app_addr(fmt_offset, 1) + if (!validate_str_addr(module_inst, fmt_offset) || !validate_app_addr(va_list_offset, sizeof(int32))) return false; @@ -414,7 +464,8 @@ _printf_wrapper(int32 fmt_offset, int32 va_list_offset) 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); + if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst)) + return 0; return ctx.count; } @@ -427,7 +478,7 @@ _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) const char *fmt; _va_list va_args; - if (!validate_app_addr(str_offset, 1)) + if (!validate_str_addr(module_inst, str_offset)) return 0; str = addr_app_to_native(str_offset); @@ -439,7 +490,8 @@ _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) ctx.max = INT_MAX; ctx.count = 0; - _vprintf((out_func_t) sprintf_out, &ctx, fmt, va_args, module_inst); + if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst)) + return 0; if (ctx.count < ctx.max) { str[ctx.count] = '\0'; @@ -470,7 +522,8 @@ _snprintf_wrapper(int32 str_offset, int32 size, int32 fmt_offset, ctx.max = size; ctx.count = 0; - _vprintf((out_func_t) sprintf_out, &ctx, fmt, va_args, module_inst); + if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst)) + return 0; if (ctx.count < ctx.max) { str[ctx.count] = '\0'; @@ -485,7 +538,7 @@ _puts_wrapper(int32 str_offset) wasm_module_inst_t module_inst = get_module_inst(); const char *str; - if (!validate_app_addr(str_offset, 1)) + if (!validate_str_addr(module_inst, str_offset)) return 0; str = addr_app_to_native(str_offset); @@ -507,7 +560,7 @@ _strdup_wrapper(int32 str_offset) uint32 len; int32 str_ret_offset = 0; - if (!validate_app_addr(str_offset, 1)) + if (!validate_str_addr(module_inst, str_offset)) return 0; str = addr_app_to_native(str_offset); @@ -596,7 +649,7 @@ _strchr_wrapper(int32 s_offset, int32 c) const char *s; char *ret; - if (!validate_app_addr(s_offset, 1)) + if (!validate_str_addr(module_inst, s_offset)) return s_offset; s = addr_app_to_native(s_offset); @@ -610,8 +663,8 @@ _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)) + if (!validate_str_addr(module_inst, s1_offset) + || !validate_str_addr(module_inst, s2_offset)) return 0; s1 = addr_app_to_native(s1_offset); @@ -640,8 +693,8 @@ _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)) + if (!validate_str_addr(module_inst, dst_offset) + || !validate_str_addr(module_inst, src_offset)) return 0; dst = addr_app_to_native(dst_offset); @@ -672,7 +725,7 @@ _strlen_wrapper(int32 s_offset) wasm_module_inst_t module_inst = get_module_inst(); char *s; - if (!validate_app_addr(s_offset, 1)) + if (!validate_str_addr(module_inst, s_offset)) return 0; s = addr_app_to_native(s_offset); diff --git a/core/iwasm/runtime/include/wasm_export.h b/core/iwasm/runtime/include/wasm_export.h index 61de096787..e6c9df5d7f 100644 --- a/core/iwasm/runtime/include/wasm_export.h +++ b/core/iwasm/runtime/include/wasm_export.h @@ -391,6 +391,38 @@ int32_t wasm_runtime_addr_native_to_app(wasm_module_inst_t module_inst, void *native_ptr); +/** + * Get the app address range (relative address) that a app address belongs to + * + * @param module_inst the WASM module instance + * @param app_offset the app address to retrieve + * @param p_app_start_offset buffer to output the app start offset if not NULL + * @param p_app_end_offset buffer to output the app end offset if not NULL + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_get_app_addr_range(wasm_module_inst_t module_inst, + int32_t app_offset, + int32_t *p_app_start_offset, + int32_t *p_app_end_offset); + +/** + * Get the native address range (absolute address) that a native address belongs to + * + * @param module_inst the WASM module instance + * @param native_ptr the native address to retrieve + * @param p_native_start_addr buffer to output the native start address if not NULL + * @param p_native_end_addr buffer to output the native end address if not NULL + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_get_native_addr_range(wasm_module_inst_t module_inst, + uint8_t *native_ptr, + uint8_t **p_native_start_addr, + uint8_t **p_native_end_addr); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index ec37222bd0..eec38bcc98 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -1302,6 +1302,84 @@ wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst, return 0; } +bool +wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst, + int32 app_offset, + int32 *p_app_start_offset, + int32 *p_app_end_offset) +{ + int32 app_start_offset, app_end_offset; + WASMMemoryInstance *memory = module_inst->default_memory; + + if (0 <= app_offset && app_offset < memory->heap_base_offset) { + app_start_offset = 0; + app_end_offset = NumBytesPerPage * memory->cur_page_count; + } + else if (memory->heap_base_offset < app_offset + && app_offset < memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data)) { + app_start_offset = memory->heap_base_offset; + app_end_offset = memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data); + } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_base_offset <= app_offset + && app_offset < module_inst->ext_mem_base_offset + + module_inst->ext_mem_size) { + app_start_offset = module_inst->ext_mem_base_offset; + app_end_offset = app_start_offset + module_inst->ext_mem_size; + } +#endif + else + return false; + + if (p_app_start_offset) + *p_app_start_offset = app_start_offset; + if (p_app_end_offset) + *p_app_end_offset = app_end_offset; + return true; +} + +bool +wasm_runtime_get_native_addr_range(WASMModuleInstance *module_inst, + uint8 *native_ptr, + uint8 **p_native_start_addr, + uint8 **p_native_end_addr) +{ + uint8 *native_start_addr, *native_end_addr; + WASMMemoryInstance *memory = module_inst->default_memory; + + if (memory->base_addr <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->end_addr) { + native_start_addr = memory->memory_data; + native_end_addr = memory->memory_data + + NumBytesPerPage * memory->cur_page_count; + } + else if (memory->heap_data <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->heap_data_end) { + native_start_addr = memory->heap_data; + native_end_addr = memory->heap_data_end; + } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_data <= (uint8*)native_ptr + && (uint8*)native_ptr < module_inst->ext_mem_data_end) { + native_start_addr = module_inst->ext_mem_data; + native_end_addr = module_inst->ext_mem_data_end; + } +#endif + else + return false; + + if (p_native_start_addr) + *p_native_start_addr = native_start_addr; + if (p_native_end_addr) + *p_native_end_addr = native_end_addr; + return true; +} + + uint32 wasm_runtime_get_temp_ret(WASMModuleInstance *module_inst) { From cdaa0deed8ea81e1acdf2cc04c17bf3e5b2b0f56 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Wed, 28 Aug 2019 15:16:59 +0800 Subject: [PATCH 13/18] Use one libc wrapper copy for sgx and other platforms; remove bh_printf macro for other platform header files --- core/iwasm/lib/native/libc/libc_wrapper.c | 19 +- core/iwasm/lib/native/libc/libc_wrapper_sgx.c | 1026 ----------------- core/iwasm/lib/native/libc/wasm_libc.cmake | 2 +- .../iwasm/lib/native/libc/wasm_libc_sgx.cmake | 23 - core/iwasm/products/linux-sgx/CMakeLists.txt | 13 +- core/shared-lib/include/config.h | 6 +- core/shared-lib/mem-alloc/ems/ems_kfc.c | 2 +- core/shared-lib/platform/alios/bh_platform.h | 2 - .../platform/linux-sgx/bh_platform.c | 2 +- .../platform/linux-sgx/bh_platform.h | 2 +- core/shared-lib/platform/linux/bh_platform.h | 2 - .../shared-lib/platform/vxworks/bh_platform.h | 2 - core/shared-lib/platform/zephyr/bh_platform.h | 2 - 13 files changed, 26 insertions(+), 1077 deletions(-) delete mode 100644 core/iwasm/lib/native/libc/libc_wrapper_sgx.c delete mode 100644 core/iwasm/lib/native/libc/wasm_libc_sgx.cmake diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index 6d3ac0c9f5..cf31a2b97c 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -414,7 +414,7 @@ sprintf_out(int c, struct str_context *ctx) static int printf_out(int c, struct str_context *ctx) { - printf("%c", c); + bh_printf("%c", c); ctx->count++; return c; } @@ -542,13 +542,13 @@ _puts_wrapper(int32 str_offset) return 0; str = addr_app_to_native(str_offset); - return printf("%s\n", str); + return bh_printf("%s\n", str); } static int _putchar_wrapper(int c) { - printf("%c", c); + bh_printf("%c", c); return 1; } @@ -699,7 +699,10 @@ _strcpy_wrapper(int32 dst_offset, int32 src_offset) dst = addr_app_to_native(dst_offset); src = addr_app_to_native(src_offset); - strcpy(dst, src); + while (*src != '\0') + *dst++ = *src++; + *dst = '\0'; + return dst_offset; } @@ -842,7 +845,7 @@ static void _llvm_stackrestore_wrapper(uint32 llvm_stack) { wasm_module_inst_t module_inst = get_module_inst(); - printf("_llvm_stackrestore called!\n"); + bh_printf("_llvm_stackrestore called!\n"); wasm_runtime_set_llvm_stack(module_inst, llvm_stack); } @@ -850,7 +853,7 @@ static uint32 _llvm_stacksave_wrapper() { wasm_module_inst_t module_inst = get_module_inst(); - printf("_llvm_stacksave called!\n"); + bh_printf("_llvm_stacksave called!\n"); return wasm_runtime_get_llvm_stack(module_inst); } @@ -905,13 +908,13 @@ nullFunc_X_wrapper(int32 code) static void print_i32_wrapper(int i32) { - printf("%d\n", i32); + bh_printf("%d\n", i32); } static void print_wrapper(int i32) { - printf("%d\n", i32); + bh_printf("%d\n", i32); } #endif diff --git a/core/iwasm/lib/native/libc/libc_wrapper_sgx.c b/core/iwasm/lib/native/libc/libc_wrapper_sgx.c deleted file mode 100644 index 0b2a21bbf0..0000000000 --- a/core/iwasm/lib/native/libc/libc_wrapper_sgx.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * 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 f70b3b81a7..52e55123f6 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}/libc_wrapper.c) +file (GLOB_RECURSE source_all ${WASM_LIBC_DIR}/*.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 deleted file mode 100644 index c2f8770974..0000000000 --- a/core/iwasm/lib/native/libc/wasm_libc_sgx.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# 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 index 4a53f95750..4d590a8ef8 100644 --- a/core/iwasm/products/linux-sgx/CMakeLists.txt +++ b/core/iwasm/products/linux-sgx/CMakeLists.txt @@ -26,6 +26,7 @@ add_definitions(-DUSE_SGX=1) add_definitions(-DOPS_INPUT_OUTPUT=1) add_definitions(-DOPS_UNSAFE_BUFFERS=0) add_definitions(-DWASM_ENABLE_LOG=0) +add_definitions(-Dbh_printf=bh_printf_sgx) # Enable repl mode if want to test spec cases # add_definitions(-DWASM_ENABLE_REPL) @@ -71,19 +72,19 @@ 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 (../../lib/native/libc/wasm_libc.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) - +include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) 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}) + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) + +add_library (extlib ext_lib_export.c) diff --git a/core/shared-lib/include/config.h b/core/shared-lib/include/config.h index 63ad5efb3f..a7c2a8b2d8 100644 --- a/core/shared-lib/include/config.h +++ b/core/shared-lib/include/config.h @@ -26,9 +26,7 @@ #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 @@ -129,3 +127,7 @@ /* Default base offset of external memory space */ #define DEFAULT_EXT_MEM_BASE_OFFSET (-2 * BH_GB) +#ifndef bh_printf +#define bh_printf printf +#endif + diff --git a/core/shared-lib/mem-alloc/ems/ems_kfc.c b/core/shared-lib/mem-alloc/ems/ems_kfc.c index 0090c317bf..4409d65dba 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)) { \ - bh_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; \ } \ diff --git a/core/shared-lib/platform/alios/bh_platform.h b/core/shared-lib/platform/alios/bh_platform.h index 468d0b4e96..e23958c95d 100644 --- a/core/shared-lib/platform/alios/bh_platform.h +++ b/core/shared-lib/platform/alios/bh_platform.h @@ -52,8 +52,6 @@ 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_platform.c b/core/shared-lib/platform/linux-sgx/bh_platform.c index 2166d53abf..d6f4c29ce0 100644 --- a/core/shared-lib/platform/linux-sgx/bh_platform.c +++ b/core/shared-lib/platform/linux-sgx/bh_platform.c @@ -52,7 +52,7 @@ void bh_set_print_function(bh_print_function_t pf) print_function = pf; } -int bh_printf(const char *message, ...) +int bh_printf_sgx(const char *message, ...) { if (print_function != NULL) { char msg[FIXED_BUFFER_SIZE] = { '\0' }; diff --git a/core/shared-lib/platform/linux-sgx/bh_platform.h b/core/shared-lib/platform/linux-sgx/bh_platform.h index 59cbb6d598..7a835ef845 100644 --- a/core/shared-lib/platform/linux-sgx/bh_platform.h +++ b/core/shared-lib/platform/linux-sgx/bh_platform.h @@ -38,7 +38,7 @@ extern "C" { #endif -extern int bh_printf(const char *message, ...); +extern int bh_printf_sgx(const char *message, ...); typedef uint64_t uint64; typedef int64_t int64; diff --git a/core/shared-lib/platform/linux/bh_platform.h b/core/shared-lib/platform/linux/bh_platform.h index 2ee9e24f3c..47172c1f68 100644 --- a/core/shared-lib/platform/linux/bh_platform.h +++ b/core/shared-lib/platform/linux/bh_platform.h @@ -77,8 +77,6 @@ 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 c023549da3..142583e5b5 100644 --- a/core/shared-lib/platform/vxworks/bh_platform.h +++ b/core/shared-lib/platform/vxworks/bh_platform.h @@ -75,8 +75,6 @@ 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 45f8e14eee..2602bee314 100644 --- a/core/shared-lib/platform/zephyr/bh_platform.h +++ b/core/shared-lib/platform/zephyr/bh_platform.h @@ -78,8 +78,6 @@ 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 From cfd2c2d7a17154123b0911d23918ea2812215d93 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Thu, 29 Aug 2019 14:28:45 +0800 Subject: [PATCH 14/18] Enhance security of libc strcpy/sprintf wrapper function --- core/iwasm/lib/native/libc/libc_wrapper.c | 24 ++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index cf31a2b97c..8972356ecd 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -473,13 +473,17 @@ static int _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) { wasm_module_inst_t module_inst = get_module_inst(); + int32 app_end_offset; struct str_context ctx; char *str; const char *fmt; _va_list va_args; - if (!validate_str_addr(module_inst, str_offset)) - return 0; + if (!wasm_runtime_get_app_addr_range(module_inst, str_offset, + NULL, &app_end_offset)) { + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; + } str = addr_app_to_native(str_offset); @@ -487,7 +491,7 @@ _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) return 0; ctx.str = str; - ctx.max = INT_MAX; + ctx.max = app_end_offset - str_offset; ctx.count = 0; if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst)) @@ -692,17 +696,19 @@ _strcpy_wrapper(int32 dst_offset, int32 src_offset) { wasm_module_inst_t module_inst = get_module_inst(); char *dst, *src; + uint32 len; - if (!validate_str_addr(module_inst, dst_offset) - || !validate_str_addr(module_inst, src_offset)) + if (!validate_str_addr(module_inst, src_offset)) return 0; - dst = addr_app_to_native(dst_offset); src = addr_app_to_native(src_offset); - while (*src != '\0') - *dst++ = *src++; - *dst = '\0'; + len = strlen(src); + if (!validate_app_addr(dst_offset, len + 1)) + return 0; + + dst = addr_app_to_native(dst_offset); + strncpy(dst, src, len + 1); return dst_offset; } From 64d75fa1b0737cfb9360133b21f25c769e551a6b Mon Sep 17 00:00:00 2001 From: wenyongh Date: Tue, 10 Sep 2019 09:44:28 +0800 Subject: [PATCH 15/18] Fix issue of call native for x86_64/arm/mips, add module inst parameter for native wrapper functions --- core/app-mgr/app-manager/event.c | 3 +- core/app-mgr/app-manager/module_wasm_app.c | 7 +- core/app-mgr/app-manager/resource_reg.c | 6 +- core/iwasm/lib/app-libs/base/request.c | 14 +- core/iwasm/lib/app-libs/base/request.h | 1 - core/iwasm/lib/app-libs/base/timer.c | 6 +- core/iwasm/lib/app-libs/base/wasm_app.h | 1 - .../extension/connection/connection.c | 8 +- .../lib/app-libs/extension/gui/src/wgl_btn.c | 6 +- .../lib/app-libs/extension/gui/src/wgl_cb.c | 4 +- .../app-libs/extension/gui/src/wgl_label.c | 4 +- .../lib/app-libs/extension/gui/src/wgl_list.c | 4 +- .../lib/app-libs/extension/gui/src/wgl_obj.c | 4 +- .../lib/app-libs/extension/sensor/sensor.c | 6 +- .../lib/native-interface/connection_api.h | 15 +- core/iwasm/lib/native-interface/gui_api.h | 26 +- .../lib/native-interface/native_interface.h | 117 +++++-- core/iwasm/lib/native-interface/readme.txt | 2 +- .../iwasm/lib/native-interface/req_resp_api.h | 43 +++ .../lib/native-interface/restful_utils.c | 1 - core/iwasm/lib/native-interface/sensor_api.h | 10 +- .../iwasm/lib/native-interface/shared_utils.h | 68 ++-- core/iwasm/lib/native-interface/timer_api.h | 48 +++ .../lib/native-interface/wasm_export_api.h | 102 ++++++ core/iwasm/lib/native/base/base_lib_export.c | 25 +- core/iwasm/lib/native/base/request_response.c | 19 +- core/iwasm/lib/native/base/runtime_lib.h | 1 - core/iwasm/lib/native/base/timer_wrapper.c | 19 +- .../extension/connection/connection_wrapper.c | 19 +- .../native/extension/gui/wgl_btn_wrapper.c | 4 +- .../lib/native/extension/gui/wgl_cb_wrapper.c | 4 +- .../native/extension/gui/wgl_label_wrapper.c | 4 +- .../native/extension/gui/wgl_list_wrapper.c | 4 +- .../native/extension/gui/wgl_obj_wrapper.c | 4 +- .../native/extension/sensor/runtime_sensor.c | 38 ++- .../native/extension/sensor/runtime_sensor.h | 15 +- core/iwasm/lib/native/libc/libc_wrapper.c | 126 ++++---- .../runtime/platform/linux-sgx/wasm_native.c | 94 +++--- .../runtime/platform/linux/wasm_native.c | 105 +++--- .../runtime/vmcore-wasm/invokeNative_arm.s | 75 +++++ .../runtime/vmcore-wasm/invokeNative_em64.s | 72 +++++ .../runtime/vmcore-wasm/invokeNative_mips.s | 85 +++++ core/iwasm/runtime/vmcore-wasm/vmcore.cmake | 8 +- core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 76 +---- core/iwasm/runtime/vmcore-wasm/wasm_loader.c | 2 +- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 303 ++++++++++++++++-- core/iwasm/runtime/vmcore-wasm/wasm_runtime.h | 5 + core/shared-lib/mem-alloc/ems/ems_alloc.c | 4 +- core/shared-lib/platform/darwin/bh_platform.c | 0 core/shared-lib/platform/darwin/bh_thread.c | 0 core/shared-lib/platform/darwin/bh_time.c | 0 .../gui/wasm-runtime-wgl/src/ext_lib_export.c | 2 +- .../vgl-wasm-runtime/src/display_indev.h | 45 ++- .../vgl-wasm-runtime/src/ext_lib_export.c | 5 +- .../src/platform/linux/display_indev.c | 47 +-- .../src/platform/zephyr/display_indev.c | 47 +-- test-tools/host-tool/CMakeLists.txt | 1 + test-tools/host-tool/src/main.c | 9 +- 58 files changed, 1283 insertions(+), 490 deletions(-) create mode 100644 core/iwasm/lib/native-interface/req_resp_api.h create mode 100644 core/iwasm/lib/native-interface/timer_api.h create mode 100644 core/iwasm/lib/native-interface/wasm_export_api.h create mode 100644 core/iwasm/runtime/vmcore-wasm/invokeNative_arm.s create mode 100644 core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s create mode 100644 core/iwasm/runtime/vmcore-wasm/invokeNative_mips.s mode change 100755 => 100644 core/shared-lib/platform/darwin/bh_platform.c mode change 100755 => 100644 core/shared-lib/platform/darwin/bh_thread.c mode change 100755 => 100644 core/shared-lib/platform/darwin/bh_time.c diff --git a/core/app-mgr/app-manager/event.c b/core/app-mgr/app-manager/event.c index 2f78a406c3..2295f20fe0 100644 --- a/core/app-mgr/app-manager/event.c +++ b/core/app-mgr/app-manager/event.c @@ -176,7 +176,8 @@ void am_publish_event(request_t * event) if (c->subscriber_id == ID_HOST) { send_request_to_host(event); } else { - module_request_handler(event, (void *)c->subscriber_id); + module_request_handler + (event, (void *)(uintptr_t)c->subscriber_id); } c = c->next; } diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index 3958520a73..4154b33e3c 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -224,8 +224,8 @@ static void app_instance_queue_callback(void *queue_msg) app_manager_printf("Cannot find function _on_timer_callback\n"); break; } - unsigned int timer_id = (unsigned int) bh_message_payload( - queue_msg); + unsigned int timer_id = (unsigned int)(uintptr_t) + bh_message_payload(queue_msg); argv[0] = timer_id; if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) { app_manager_printf("Got exception running wasm code: %s\n", @@ -642,7 +642,8 @@ static bool wasm_app_module_uninstall(request_t *msg) static bool wasm_app_module_handle_host_url(void *queue_msg) { //todo: implement in future - app_manager_printf("App handles host url address %d\n", (int) queue_msg); + app_manager_printf("App handles host url address %d\n", + (int)(uintptr_t)queue_msg); return false; } diff --git a/core/app-mgr/app-manager/resource_reg.c b/core/app-mgr/app-manager/resource_reg.c index bbadcd03f7..4fe477e3db 100644 --- a/core/app-mgr/app-manager/resource_reg.c +++ b/core/app-mgr/app-manager/resource_reg.c @@ -33,7 +33,7 @@ static app_res_register_t * g_resources = NULL; void module_request_handler(request_t *request, void *user_data) { - unsigned int mod_id = (unsigned int) user_data; + unsigned int mod_id = (unsigned int)(uintptr_t)user_data; bh_message_t msg; module_data *m_data; request_t *req; @@ -99,7 +99,7 @@ void targeted_app_request_handler(request_t *request, void *unused) goto end; } - module_request_handler(request, (void *)m_data->id); + module_request_handler(request, (void *)(uintptr_t)m_data->id); end: request->url = url; } @@ -138,7 +138,7 @@ void * am_dispatch_request(request_t *request) while (r) { if (check_url_start(request->url, strlen(request->url), r->url) > 0) { - r->request_handler(request, (void *)r->register_id); + r->request_handler(request, (void *)(uintptr_t)r->register_id); return r; } r = r->next; diff --git a/core/iwasm/lib/app-libs/base/request.c b/core/iwasm/lib/app-libs/base/request.c index 4251e2bfe8..ade6ce4e24 100644 --- a/core/iwasm/lib/app-libs/base/request.c +++ b/core/iwasm/lib/app-libs/base/request.c @@ -18,6 +18,8 @@ #include "request.h" #include "shared_utils.h" #include "wasm_app.h" +#include "req_resp_api.h" +#include "timer_api.h" #define TRANSACTION_TIMEOUT_MS 5000 @@ -138,15 +140,15 @@ static bool register_url_handler(const char *url, // tell app mgr to route this url to me if (reg_type == Reg_Request) - wasm_register_resource((int32)url); + wasm_register_resource(url); else - wasm_sub_event((int32)url); + wasm_sub_event(url); return true; } bool api_register_resource_handler(const char *url, - request_handler_f request_handler) + request_handler_f request_handler) { return register_url_handler(url, request_handler, Reg_Request); } @@ -242,7 +244,7 @@ void api_send_request(request_t * request, response_handler_f response_handler, } } - wasm_post_request((int32)buffer, size); + wasm_post_request(buffer, size); free_req_resp_packet(buffer); } @@ -329,7 +331,7 @@ void api_response_send(response_t *response) if (buffer == NULL) return; - wasm_response_send((int32)buffer, size); + wasm_response_send(buffer, size); free_req_resp_packet(buffer); } @@ -343,7 +345,7 @@ bool api_publish_event(const char *url, int fmt, void *payload, int payload_len) char * buffer = pack_request(request, &size); if (buffer == NULL) return false; - wasm_post_request((int32)buffer, size); + wasm_post_request(buffer, size); free_req_resp_packet(buffer); diff --git a/core/iwasm/lib/app-libs/base/request.h b/core/iwasm/lib/app-libs/base/request.h index e7766dac05..f60b9f6989 100644 --- a/core/iwasm/lib/app-libs/base/request.h +++ b/core/iwasm/lib/app-libs/base/request.h @@ -17,7 +17,6 @@ #ifndef _AEE_REQUEST_H_ #define _AEE_REQUEST_H_ -#include "native_interface.h" #include "shared_utils.h" #ifdef __cplusplus diff --git a/core/iwasm/lib/app-libs/base/timer.c b/core/iwasm/lib/app-libs/base/timer.c index cb042670e4..0b3cd9f010 100644 --- a/core/iwasm/lib/app-libs/base/timer.c +++ b/core/iwasm/lib/app-libs/base/timer.c @@ -14,12 +14,12 @@ * limitations under the License. */ -#include "timer_wasm_app.h" -#include "native_interface.h" - #include #include +#include "timer_wasm_app.h" +#include "timer_api.h" + #if 1 #include #else diff --git a/core/iwasm/lib/app-libs/base/wasm_app.h b/core/iwasm/lib/app-libs/base/wasm_app.h index 081b2bfe29..3513001e47 100644 --- a/core/iwasm/lib/app-libs/base/wasm_app.h +++ b/core/iwasm/lib/app-libs/base/wasm_app.h @@ -32,7 +32,6 @@ #ifndef _LIB_AEE_H_ #define _LIB_AEE_H_ -#include "native_interface.h" #include "shared_utils.h" #include "attr_container.h" #include "request.h" diff --git a/core/iwasm/lib/app-libs/extension/connection/connection.c b/core/iwasm/lib/app-libs/extension/connection/connection.c index 1c7845d4b6..e60504c24c 100644 --- a/core/iwasm/lib/app-libs/extension/connection/connection.c +++ b/core/iwasm/lib/app-libs/extension/connection/connection.c @@ -15,7 +15,7 @@ */ #include "connection.h" -#include "native_interface.h" +#include "connection_api.h" /* Raw connection structure */ typedef struct _connection { @@ -44,7 +44,7 @@ connection_t *api_open_connection(const char *name, char *args_buffer = (char *)args; uint32 handle, args_len = attr_container_get_serialize_length(args); - handle = wasm_open_connection((int32)name, (int32)args_buffer, args_len); + handle = wasm_open_connection(name, args_buffer, args_len); if (handle == -1) return NULL; @@ -91,7 +91,7 @@ void api_close_connection(connection_t *c) int api_send_on_connection(connection_t *conn, const char *data, uint32 len) { - return wasm_send_on_connection(conn->handle, (int32)data, len); + return wasm_send_on_connection(conn->handle, data, len); } bool api_config_connection(connection_t *conn, attr_container_t *cfg) @@ -99,7 +99,7 @@ bool api_config_connection(connection_t *conn, attr_container_t *cfg) char *cfg_buffer = (char *)cfg; uint32 cfg_len = attr_container_get_serialize_length(cfg); - return wasm_config_connection(conn->handle, (int32)cfg_buffer, cfg_len); + return wasm_config_connection(conn->handle, cfg_buffer, cfg_len); } void on_connection_data(uint32 handle, char *buffer, uint32 len) diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c index 5cf8c1c294..5623abe6c7 100644 --- a/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c @@ -15,11 +15,11 @@ */ #include "wgl.h" -#include "native_interface.h" - +#include "bh_platform.h" +#include "gui_api.h" #define ARGC sizeof(argv)/sizeof(uint32) -#define CALL_BTN_NATIVE_FUNC(id) wasm_btn_native_call(id, (int32)argv, ARGC) +#define CALL_BTN_NATIVE_FUNC(id) wasm_btn_native_call(id, argv, ARGC) wgl_obj_t wgl_btn_create(wgl_obj_t par, wgl_obj_t copy) { diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c index df646fbc88..cbfa11ebd7 100644 --- a/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c @@ -15,12 +15,12 @@ */ #include "wgl.h" -#include "native_interface.h" +#include "gui_api.h" #include #define ARGC sizeof(argv)/sizeof(uint32) -#define CALL_CB_NATIVE_FUNC(id) wasm_cb_native_call(id, (uint32)argv, ARGC) +#define CALL_CB_NATIVE_FUNC(id) wasm_cb_native_call(id, argv, ARGC) wgl_obj_t wgl_cb_create(wgl_obj_t par, const wgl_obj_t copy) { diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c index 3a14cdb47f..a602e2aeeb 100644 --- a/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c @@ -16,12 +16,12 @@ #include "wgl.h" -#include "native_interface.h" +#include "gui_api.h" #include #define ARGC sizeof(argv)/sizeof(uint32) -#define CALL_LABEL_NATIVE_FUNC(id) wasm_label_native_call(id, (uint32)argv, ARGC) +#define CALL_LABEL_NATIVE_FUNC(id) wasm_label_native_call(id, argv, ARGC) wgl_obj_t wgl_label_create(wgl_obj_t par, wgl_obj_t copy) { diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c index ad580b7fac..c815964db9 100644 --- a/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c @@ -15,12 +15,12 @@ */ #include "wgl.h" -#include "native_interface.h" +#include "gui_api.h" #include #define ARGC sizeof(argv)/sizeof(uint32) -#define CALL_LIST_NATIVE_FUNC(id) wasm_list_native_call(id, (int32)argv, ARGC) +#define CALL_LIST_NATIVE_FUNC(id) wasm_list_native_call(id, argv, ARGC) wgl_obj_t wgl_list_create(wgl_obj_t par, const wgl_obj_t copy) diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c index d53f8b29f5..5798ca3dd9 100644 --- a/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c @@ -15,12 +15,12 @@ */ #include "wgl.h" -#include "native_interface.h" +#include "gui_api.h" #include #include #define ARGC sizeof(argv)/sizeof(uint32) -#define CALL_OBJ_NATIVE_FUNC(id) wasm_obj_native_call(id, (int32)argv, ARGC) +#define CALL_OBJ_NATIVE_FUNC(id) wasm_obj_native_call(id, argv, ARGC) typedef struct _obj_evt_cb { struct _obj_evt_cb *next; diff --git a/core/iwasm/lib/app-libs/extension/sensor/sensor.c b/core/iwasm/lib/app-libs/extension/sensor/sensor.c index 53f413bf7d..212b2e1661 100644 --- a/core/iwasm/lib/app-libs/extension/sensor/sensor.c +++ b/core/iwasm/lib/app-libs/extension/sensor/sensor.c @@ -15,7 +15,7 @@ */ #include "sensor.h" -#include "native_interface.h" +#include "sensor_api.h" typedef struct _sensor { struct _sensor * next; @@ -31,7 +31,7 @@ sensor_t sensor_open(const char* name, int index, sensor_event_handler_f sensor_event_handler, void *user_data) { - uint32 id = wasm_sensor_open((int32)name, index); + uint32 id = wasm_sensor_open(name, index); if (id == -1) return NULL; @@ -66,7 +66,7 @@ bool sensor_config_with_attr_container(sensor_t sensor, attr_container_t *cfg) char *buffer = (char *)cfg; int len = attr_container_get_serialize_length(cfg); - return wasm_sensor_config_with_attr_container(sensor->handle, (int32)buffer, len); + return wasm_sensor_config_with_attr_container(sensor->handle, buffer, len); } bool sensor_config(sensor_t sensor, int interval, int bit_cfg, int delay) diff --git a/core/iwasm/lib/native-interface/connection_api.h b/core/iwasm/lib/native-interface/connection_api.h index f55583bd9e..21142b70a4 100644 --- a/core/iwasm/lib/native-interface/connection_api.h +++ b/core/iwasm/lib/native-interface/connection_api.h @@ -16,23 +16,28 @@ #ifndef CONNECTION_API_H_ #define CONNECTION_API_H_ + #include "bh_platform.h" #ifdef __cplusplus extern "C" { #endif -uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len); +uint32 +wasm_open_connection(const char *name, char *args_buf, uint32 args_buf_len); -void wasm_close_connection(uint32 handle); +void +wasm_close_connection(uint32 handle); -int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len); +int +wasm_send_on_connection(uint32 handle, const char *data, uint32 data_len); -bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len); +bool +wasm_config_connection(uint32 handle, const char *cfg_buf, uint32 cfg_buf_len); #ifdef __cplusplus } #endif -#endif /* CONNECTION_API_H_ */ +#endif /* end of CONNECTION_API_H_ */ diff --git a/core/iwasm/lib/native-interface/gui_api.h b/core/iwasm/lib/native-interface/gui_api.h index 0b1dbb005b..04031c1fab 100644 --- a/core/iwasm/lib/native-interface/gui_api.h +++ b/core/iwasm/lib/native-interface/gui_api.h @@ -14,19 +14,29 @@ * limitations under the License. */ -#ifndef GUI_API_H_ -#define GUI_API_H_ +#ifndef _GUI_API_H_ +#define _GUI_API_H_ + #include "bh_platform.h" #ifdef __cplusplus extern "C" { #endif -void wasm_obj_native_call(int32 func_id, uint32 argv_offset, uint32 argc); -void wasm_btn_native_call(int32 func_id, uint32 argv_offset, uint32 argc); -void wasm_label_native_call(int32 func_id, uint32 argv_offset, uint32 argc); -void wasm_cb_native_call(int32 func_id, uint32 argv_offset, uint32 argc); -void wasm_list_native_call(int32 func_id, uint32 argv_offset, uint32 argc); +void +wasm_obj_native_call(int32 func_id, uint32 *argv, uint32 argc); + +void +wasm_btn_native_call(int32 func_id, uint32 *argv, uint32 argc); + +void +wasm_label_native_call(int32 func_id, uint32 *argv, uint32 argc); + +void +wasm_cb_native_call(int32 func_id, uint32 *argv, uint32 argc); + +void +wasm_list_native_call(int32 func_id, uint32 *argv, uint32 argc); #ifdef __cplusplus @@ -34,4 +44,4 @@ void wasm_list_native_call(int32 func_id, uint32 argv_offset, uint32 argc); #endif -#endif /* GUI_API_H_ */ +#endif /* end of _GUI_API_H_ */ diff --git a/core/iwasm/lib/native-interface/native_interface.h b/core/iwasm/lib/native-interface/native_interface.h index 0312b1f632..49c7c1e66a 100644 --- a/core/iwasm/lib/native-interface/native_interface.h +++ b/core/iwasm/lib/native-interface/native_interface.h @@ -14,12 +14,13 @@ * limitations under the License. */ -#ifndef DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ -#define DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ +#ifndef _NATIVE_INTERFACE_H_ +#define _NATIVE_INTERFACE_H_ -// note: the bh_plaform.h is the only head file separately -// implemented by both [app] and [native] worlds +/* Note: the bh_plaform.h is the only head file separately + implemented by both [app] and [native] worlds */ #include "bh_platform.h" +#include "wasm_export.h" #define get_module_inst() \ wasm_runtime_get_current_module_inst() @@ -39,52 +40,102 @@ #define module_free(offset) \ wasm_runtime_module_free(module_inst, offset) -char *wa_strdup(const char *); +/*char *wa_strdup(const char *);*/ -bool -wasm_response_send(int32 buffer_offset, int size); - -void wasm_register_resource(int32 url_offset); - -void wasm_post_request(int32 buffer_offset, int size); +/* + * request/response interfaces + */ -void wasm_sub_event(int32 url_offset); +bool +wasm_response_send(wasm_module_inst_t module_inst, + int32 buffer_offset, int size); +void +wasm_register_resource(wasm_module_inst_t module_inst, + int32 url_offset); +void +wasm_post_request(wasm_module_inst_t module_inst, + int32 buffer_offset, int size); +void +wasm_sub_event(wasm_module_inst_t module_inst, + int32 url_offset); /* - * ************* sensor interfaces ************* + * sensor interfaces */ bool -wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay); +wasm_sensor_config(wasm_module_inst_t module_inst, + uint32 sensor, int interval, int bit_cfg, int delay); uint32 -wasm_sensor_open(int32 name_offset, int instance); +wasm_sensor_open(wasm_module_inst_t module_inst, + int32 name_offset, int instance); bool -wasm_sensor_config_with_attr_container(uint32 sensor, int32 buffer_offset, - int len); - +wasm_sensor_config_with_attr_container(wasm_module_inst_t module_inst, + uint32 sensor, + int32 buffer_offset, int len); bool -wasm_sensor_close(uint32 sensor); +wasm_sensor_close(wasm_module_inst_t module_inst, + uint32 sensor); /* - * *** timer interface *** + * timer interfaces */ typedef unsigned int timer_id_t; -timer_id_t wasm_create_timer(int interval, bool is_period, bool auto_start); -void wasm_timer_destory(timer_id_t timer_id); -void wasm_timer_cancel(timer_id_t timer_id); -void wasm_timer_restart(timer_id_t timer_id, int interval); -uint32 wasm_get_sys_tick_ms(void); + +timer_id_t +wasm_create_timer(wasm_module_inst_t module_inst, + int interval, bool is_period, bool auto_start); +void +wasm_timer_destory(wasm_module_inst_t module_inst, timer_id_t timer_id); +void +wasm_timer_cancel(wasm_module_inst_t module_inst, timer_id_t timer_id); +void +wasm_timer_restart(wasm_module_inst_t module_inst, + timer_id_t timer_id, int interval); +uint32 +wasm_get_sys_tick_ms(wasm_module_inst_t module_inst); /* - * *** connection interface *** + * connection interfaces */ -uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len); -void wasm_close_connection(uint32 handle); -int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len); -bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len); -#include "gui_api.h" +uint32 +wasm_open_connection(wasm_module_inst_t module_inst, + int32 name_offset, int32 args_offset, uint32 len); +void +wasm_close_connection(wasm_module_inst_t module_inst, + uint32 handle); +int +wasm_send_on_connection(wasm_module_inst_t module_inst, + uint32 handle, int32 data_offset, uint32 len); +bool +wasm_config_connection(wasm_module_inst_t module_inst, + uint32 handle, int32 cfg_offset, uint32 len); + +/** + * gui interfaces + */ + +void +wasm_obj_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc); + +void +wasm_btn_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc); + +void +wasm_label_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc); + +void +wasm_cb_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc); + +void +wasm_list_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc); + +#endif /* end of _NATIVE_INTERFACE_H */ -#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_PO -C_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ */ diff --git a/core/iwasm/lib/native-interface/readme.txt b/core/iwasm/lib/native-interface/readme.txt index e3b59042b0..7197d58441 100644 --- a/core/iwasm/lib/native-interface/readme.txt +++ b/core/iwasm/lib/native-interface/readme.txt @@ -1,6 +1,6 @@ Attention: ======= -Only add files are shared by both wasm application and native runtime into this directory! +Only add files which are shared by both wasm application and native runtime into this directory! The c files are both compiled into the the WASM APP and native runtime. diff --git a/core/iwasm/lib/native-interface/req_resp_api.h b/core/iwasm/lib/native-interface/req_resp_api.h new file mode 100644 index 0000000000..8b2235712f --- /dev/null +++ b/core/iwasm/lib/native-interface/req_resp_api.h @@ -0,0 +1,43 @@ +/* + * 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 _REQ_RESP_API_H_ +#define _REQ_RESP_API_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool +wasm_response_send(const char *buf, int size); + +void +wasm_register_resource(const char *url); + +void +wasm_post_request(const char *buf, int size); + +void +wasm_sub_event(const char *url); + +#ifdef __cplusplus +} +#endif + +#endif /* end of _REQ_RESP_API_H_ */ + diff --git a/core/iwasm/lib/native-interface/restful_utils.c b/core/iwasm/lib/native-interface/restful_utils.c index 71b5d782ea..e7afad4692 100644 --- a/core/iwasm/lib/native-interface/restful_utils.c +++ b/core/iwasm/lib/native-interface/restful_utils.c @@ -19,7 +19,6 @@ #include #include -#include "native_interface.h" #include "shared_utils.h" /* Serialization of request and response message diff --git a/core/iwasm/lib/native-interface/sensor_api.h b/core/iwasm/lib/native-interface/sensor_api.h index 0f8a8583bd..1adf93b1e7 100644 --- a/core/iwasm/lib/native-interface/sensor_api.h +++ b/core/iwasm/lib/native-interface/sensor_api.h @@ -14,8 +14,9 @@ * limitations under the License. */ -#ifndef DEPS_IWASM_APP_LIBS_NATIVE_INTERFACE_SENSOR_API_H_ -#define DEPS_IWASM_APP_LIBS_NATIVE_INTERFACE_SENSOR_API_H_ +#ifndef _SENSOR_API_H_ +#define _SENSOR_API_H_ + #include "bh_platform.h" #ifdef __cplusplus @@ -29,7 +30,7 @@ bool wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay); bool -wasm_sensor_config_with_attr_container(uint32 sensor, char * buffer, int len); +wasm_sensor_config_with_attr_container(uint32 sensor, char *buffer, int len); bool wasm_sensor_close(uint32 sensor); @@ -38,4 +39,5 @@ wasm_sensor_close(uint32 sensor); } #endif -#endif /* DEPS_IWASM_APP_LIBS_NATIVE_INTERFACE_SENSOR_API_H_ */ +#endif /* end of _SENSOR_API_H_ */ + diff --git a/core/iwasm/lib/native-interface/shared_utils.h b/core/iwasm/lib/native-interface/shared_utils.h index 693dcf9578..70f561b431 100644 --- a/core/iwasm/lib/native-interface/shared_utils.h +++ b/core/iwasm/lib/native-interface/shared_utils.h @@ -14,10 +14,10 @@ * limitations under the License. */ -#ifndef DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_SHARED_UTILS_H_ -#define DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_SHARED_UTILS_H_ +#ifndef _SHARED_UTILS_H_ +#define _SHARED_UTILS_H_ -#include "native_interface.h" +#include "bh_platform.h" #ifdef __cplusplus extern "C" { @@ -71,16 +71,27 @@ typedef struct response { unsigned long reciever; } response_t; -int check_url_start(const char* url, int url_len, const char * leading_str); -bool match_url(char * pattern, char * matched); -char * find_key_value(char * buffer, int buffer_len, char * key, char * value, - int value_len, char delimiter); +int +check_url_start(const char* url, int url_len, const char * leading_str); -request_t *clone_request(request_t *request); -void request_cleaner(request_t *request); +bool +match_url(char * pattern, char * matched); -response_t * clone_response(response_t * response); -void response_cleaner(response_t * response); +char * +find_key_value(char * buffer, int buffer_len, char * key, char * value, + int value_len, char delimiter); + +request_t * +clone_request(request_t *request); + +void +request_cleaner(request_t *request); + +response_t * +clone_response(response_t * response); + +void +response_cleaner(response_t * response); /** * @brief Set fields of response. @@ -95,8 +106,9 @@ void response_cleaner(response_t * response); * * @warning the response pointer MUST NOT be NULL */ -response_t * set_response(response_t * response, int status, int fmt, - const char *payload, int payload_len); +response_t * +set_response(response_t * response, int status, int fmt, + const char *payload, int payload_len); /** * @brief Make a response for a request. @@ -108,8 +120,8 @@ response_t * set_response(response_t * response, int status, int fmt, * * @warning the request and response pointers MUST NOT be NULL */ -response_t * make_response_for_request(request_t * request, - response_t * response); +response_t * +make_response_for_request(request_t * request, response_t * response); /** * @brief Initialize a request. @@ -125,14 +137,24 @@ response_t * make_response_for_request(request_t * request, * * @warning the request pointer MUST NOT be NULL */ -request_t * init_request(request_t * request, char *url, int action, int fmt, - void *payload, int payload_len); +request_t * +init_request(request_t * request, char *url, int action, int fmt, + void *payload, int payload_len); + +char * +pack_request(request_t *request, int * size); + +request_t * +unpack_request(char * packet, int size, request_t * request); + +char * +pack_response(response_t *response, int * size); + +response_t * +unpack_response(char * packet, int size, response_t * response); -char * pack_request(request_t *request, int * size); -request_t * unpack_request(char * packet, int size, request_t * request); -char * pack_response(response_t *response, int * size); -response_t * unpack_response(char * packet, int size, response_t * response); -void free_req_resp_packet(char * packet); +void +free_req_resp_packet(char * packet); #include "wgl_shared_utils.h" @@ -140,4 +162,4 @@ void free_req_resp_packet(char * packet); } #endif -#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_SHARED_UTILS_H_ */ +#endif /* end of _SHARED_UTILS_H_ */ diff --git a/core/iwasm/lib/native-interface/timer_api.h b/core/iwasm/lib/native-interface/timer_api.h new file mode 100644 index 0000000000..81ea839ab0 --- /dev/null +++ b/core/iwasm/lib/native-interface/timer_api.h @@ -0,0 +1,48 @@ +/* + * 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 _TIMER_API_H_ +#define _TIMER_API_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int timer_id_t; + +timer_id_t +wasm_create_timer(int interval, bool is_period, bool auto_start); + +void +wasm_timer_destory(timer_id_t timer_id); + +void +wasm_timer_cancel(timer_id_t timer_id); + +void +wasm_timer_restart(timer_id_t timer_id, int interval); + +uint32 +wasm_get_sys_tick_ms(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of _TIMER_API_H_ */ + diff --git a/core/iwasm/lib/native-interface/wasm_export_api.h b/core/iwasm/lib/native-interface/wasm_export_api.h new file mode 100644 index 0000000000..ed9d570f81 --- /dev/null +++ b/core/iwasm/lib/native-interface/wasm_export_api.h @@ -0,0 +1,102 @@ +/* + * 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 _WASM_EXPORT_H +#define _WASM_EXPORT_H + +#include +#include + +/** + * API exported to WASM application + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get current WASM module instance of the current native thread + * + * @return current WASM module instance of the current native thread, 0 + * if not found + * Note: the return type is uint64_t but not pointer type, because that + * the we only supports WASM-32, in which the pointer type is + * compiled to WASM i32 type, but the pointer type in native can be + * 32-bit and 64-bit. And if the native pointer is 64-bit, data loss + * occurs after converting it to WASM i32 type. + */ +uint64_t +wasm_runtime_get_current_module_inst(); + +/** + * Validate the app address, check whether it belongs to WASM module + * instance's address space, or in its heap space or memory space. + * + * @param module_inst the WASM module instance + * @param app_offset the app address to validate, which is a relative address + * @param size the size bytes of the app address + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_validate_app_addr(uint64_t module_inst, + int32_t app_offset, uint32_t size); + +/** + * Validate the native address, check whether it belongs to WASM module + * instance's address space, or in its heap space or memory space. + * + * @param module_inst the WASM module instance + * @param native_ptr the native address to validate, which is an absolute + * address + * @param size the size bytes of the app address + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_validate_native_addr(uint64_t module_inst, + uint64_t native_ptr, uint32_t size); + +/** + * Convert app address(relative address) to native address(absolute address) + * + * @param module_inst the WASM module instance + * @param app_offset the app adress + * + * @return the native address converted + */ +uint64_t +wasm_runtime_addr_app_to_native(uint64_t module_inst, + int32_t app_offset); + +/** + * Convert native address(absolute address) to app address(relative address) + * + * @param module_inst the WASM module instance + * @param native_ptr the native address + * + * @return the app address converted + */ +int32_t +wasm_runtime_addr_native_to_app(uint64_t module_inst, + uint64_t native_ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of _WASM_EXPORT_H */ diff --git a/core/iwasm/lib/native/base/base_lib_export.c b/core/iwasm/lib/native/base/base_lib_export.c index 353871b6d7..4d259a392b 100644 --- a/core/iwasm/lib/native/base/base_lib_export.c +++ b/core/iwasm/lib/native/base/base_lib_export.c @@ -26,19 +26,17 @@ #endif static uint64 -wasm_runtime_get_current_module_inst_wrapper() +wasm_runtime_get_current_module_inst_wrapper(wasm_module_inst_t module_inst) { - return (uint64)(uintptr_t) - wasm_runtime_get_current_module_inst(); + return (uint64)(uintptr_t)module_inst; } static bool -wasm_runtime_validate_app_addr_wrapper(uint32 inst_part0, uint32 inst_part1, +wasm_runtime_validate_app_addr_wrapper(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, int32 app_offset, uint32 size) { bool ret; - wasm_module_inst_t module_inst = - wasm_runtime_get_current_module_inst(); union { uint64 u64; uint32 parts[2]; } inst; inst.parts[0] = inst_part0; @@ -56,14 +54,13 @@ wasm_runtime_validate_app_addr_wrapper(uint32 inst_part0, uint32 inst_part1, } static bool -wasm_runtime_validate_native_addr_wrapper(uint32 inst_part0, uint32 inst_part1, +wasm_runtime_validate_native_addr_wrapper(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, uint32 native_ptr_part0, uint32 native_ptr_part1, uint32 size) { bool ret; - wasm_module_inst_t module_inst = - wasm_runtime_get_current_module_inst(); union { uint64 u64; uint32 parts[2]; } inst; union { uint64 u64; uint32 parts[2]; } native_ptr; @@ -86,11 +83,10 @@ wasm_runtime_validate_native_addr_wrapper(uint32 inst_part0, uint32 inst_part1, } static uint64 -wasm_runtime_addr_app_to_native_wrapper(uint32 inst_part0, uint32 inst_part1, +wasm_runtime_addr_app_to_native_wrapper(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, int32 app_offset) { - wasm_module_inst_t module_inst = - wasm_runtime_get_current_module_inst(); union { uint64 u64; uint32 parts[2]; } inst; inst.parts[0] = inst_part0; @@ -105,12 +101,11 @@ wasm_runtime_addr_app_to_native_wrapper(uint32 inst_part0, uint32 inst_part1, } static int32 -wasm_runtime_addr_native_to_app_wrapper(uint32 inst_part0, uint32 inst_part1, +wasm_runtime_addr_native_to_app_wrapper(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, uint32 native_ptr_part0, uint32 native_ptr_part1) { - wasm_module_inst_t module_inst = - wasm_runtime_get_current_module_inst(); union { uint64 u64; uint32 parts[2]; } inst; union { uint64 u64; uint32 parts[2]; } native_ptr; diff --git a/core/iwasm/lib/native/base/request_response.c b/core/iwasm/lib/native/base/request_response.c index 641dc549cf..6e6ab59922 100644 --- a/core/iwasm/lib/native/base/request_response.c +++ b/core/iwasm/lib/native/base/request_response.c @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "native_interface.h" #include "app_manager_export.h" #include "coap_ext.h" #include "wasm_export.h" extern void module_request_handler(request_t *request, void *user_data); -bool wasm_response_send(int32 buffer_offset, int size) +bool +wasm_response_send(wasm_module_inst_t module_inst, + int32 buffer_offset, int size) { - wasm_module_inst_t module_inst = get_module_inst(); char *buffer = NULL; if (!validate_app_addr(buffer_offset, size)) @@ -45,9 +45,9 @@ bool wasm_response_send(int32 buffer_offset, int size) return false; } -void wasm_register_resource(int32 url_offset) +void +wasm_register_resource(wasm_module_inst_t module_inst, int32 url_offset) { - wasm_module_inst_t module_inst = get_module_inst(); char *url = NULL; if (!validate_app_addr(url_offset, 1)) @@ -61,9 +61,10 @@ void wasm_register_resource(int32 url_offset) } } -void wasm_post_request(int32 buffer_offset, int size) +void +wasm_post_request(wasm_module_inst_t module_inst, + int32 buffer_offset, int size) { - wasm_module_inst_t module_inst = get_module_inst(); char *buffer = NULL; if (!validate_app_addr(buffer_offset, size)) @@ -92,9 +93,9 @@ void wasm_post_request(int32 buffer_offset, int size) } } -void wasm_sub_event(int32 url_offset) +void +wasm_sub_event(wasm_module_inst_t module_inst, int32 url_offset) { - wasm_module_inst_t module_inst = get_module_inst(); char *url = NULL; if (!validate_app_addr(url_offset, 1)) diff --git a/core/iwasm/lib/native/base/runtime_lib.h b/core/iwasm/lib/native/base/runtime_lib.h index bf4dccfe3b..d264eb84ea 100644 --- a/core/iwasm/lib/native/base/runtime_lib.h +++ b/core/iwasm/lib/native/base/runtime_lib.h @@ -17,7 +17,6 @@ #ifndef LIB_BASE_RUNTIME_LIB_H_ #define LIB_BASE_RUNTIME_LIB_H_ -#include "native_interface.h" #include "runtime_timer.h" diff --git a/core/iwasm/lib/native/base/timer_wrapper.c b/core/iwasm/lib/native/base/timer_wrapper.c index da5c8943fa..c655ed0404 100644 --- a/core/iwasm/lib/native/base/timer_wrapper.c +++ b/core/iwasm/lib/native/base/timer_wrapper.c @@ -37,7 +37,7 @@ void wasm_timer_callback(timer_id_t id, unsigned int mod_id) // !!! the length parameter must be 0, so the receiver will // not free the payload pointer. - bh_post_msg(module->queue, TIMER_EVENT_WASM, (char *) id, 0); + bh_post_msg(module->queue, TIMER_EVENT_WASM, (char *)(uintptr_t)id, 0); } /// @@ -149,30 +149,37 @@ timer_ctx_t get_wasm_timer_ctx() return m->timer_ctx; } -timer_id_t wasm_create_timer(int interval, bool is_period, bool auto_start) +timer_id_t +wasm_create_timer(wasm_module_inst_t module_inst, + int interval, bool is_period, bool auto_start) { return sys_create_timer(get_wasm_timer_ctx(), interval, is_period, auto_start); } -void wasm_timer_destory(timer_id_t timer_id) +void +wasm_timer_destory(wasm_module_inst_t module_inst, timer_id_t timer_id) { sys_timer_destory(get_wasm_timer_ctx(), timer_id); } -void wasm_timer_cancel(timer_id_t timer_id) +void +wasm_timer_cancel(wasm_module_inst_t module_inst, timer_id_t timer_id) { sys_timer_cancel(get_wasm_timer_ctx(), timer_id); } -void wasm_timer_restart(timer_id_t timer_id, int interval) +void +wasm_timer_restart(wasm_module_inst_t module_inst, + timer_id_t timer_id, int interval) { sys_timer_restart(get_wasm_timer_ctx(), timer_id, interval); } extern uint32 get_sys_tick_ms(); -uint32 wasm_get_sys_tick_ms(void) +uint32 +wasm_get_sys_tick_ms(wasm_module_inst_t module_inst) { return (uint32) bh_get_tick_ms(); } diff --git a/core/iwasm/lib/native/extension/connection/connection_wrapper.c b/core/iwasm/lib/native/extension/connection/connection_wrapper.c index 7bcf5860d1..1a163e429e 100644 --- a/core/iwasm/lib/native/extension/connection/connection_wrapper.c +++ b/core/iwasm/lib/native/extension/connection/connection_wrapper.c @@ -23,10 +23,10 @@ * This file is the consumer of connection lib which is implemented by different platforms */ - -uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len) +uint32 +wasm_open_connection(wasm_module_inst_t module_inst, + int32 name_offset, int32 args_offset, uint32 len) { - wasm_module_inst_t module_inst = get_module_inst(); attr_container_t *args; char *name, *args_buf; @@ -44,15 +44,17 @@ uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len) return -1; } -void wasm_close_connection(uint32 handle) +void +wasm_close_connection(wasm_module_inst_t module_inst, uint32 handle) { if (connection_impl._close != NULL) connection_impl._close(handle); } -int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len) +int +wasm_send_on_connection(wasm_module_inst_t module_inst, + uint32 handle, int32 data_offset, uint32 len) { - wasm_module_inst_t module_inst = get_module_inst(); char *data; if (!validate_app_addr(data_offset, len) || @@ -65,9 +67,10 @@ int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len) return -1; } -bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len) +bool +wasm_config_connection(wasm_module_inst_t module_inst, + uint32 handle, int32 cfg_offset, uint32 len) { - wasm_module_inst_t module_inst = get_module_inst(); char *cfg_buf; attr_container_t *cfg; diff --git a/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c index 7b41826d1a..fa46cb66a2 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c @@ -45,7 +45,9 @@ static WGLNativeFuncDef btn_native_func_defs[] = { }; /*************** Native Interface to Wasm App ***********/ -void wasm_btn_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +void +wasm_btn_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc) { uint32 size = sizeof(btn_native_func_defs) / sizeof(WGLNativeFuncDef); diff --git a/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c index 4356433104..d0ed63e075 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c @@ -61,7 +61,9 @@ static WGLNativeFuncDef cb_native_func_defs[] = { }; /*************** Native Interface to Wasm App ***********/ -void wasm_cb_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +void +wasm_cb_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc) { uint32 size = sizeof(cb_native_func_defs) / sizeof(WGLNativeFuncDef); diff --git a/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c index edf5ba49eb..a99b591b3b 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c @@ -60,7 +60,9 @@ static WGLNativeFuncDef label_native_func_defs[] = { }; /*************** Native Interface to Wasm App ***********/ -void wasm_label_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +void +wasm_label_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc) { uint32 size = sizeof(label_native_func_defs) / sizeof(WGLNativeFuncDef); diff --git a/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c index 8822307773..59040fc050 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c @@ -51,7 +51,9 @@ static WGLNativeFuncDef list_native_func_defs[] = { }; /*************** Native Interface to Wasm App ***********/ -void wasm_list_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +void +wasm_list_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc) { uint32 size = sizeof(list_native_func_defs) / sizeof(WGLNativeFuncDef); diff --git a/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c index cd9c724b8b..625077626d 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c @@ -341,7 +341,9 @@ static WGLNativeFuncDef obj_native_func_defs[] = { }; /*************** Native Interface to Wasm App ***********/ -void wasm_obj_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +void +wasm_obj_native_call(wasm_module_inst_t module_inst, + int32 func_id, uint32 argv_offset, uint32 argc) { uint32 size = sizeof(obj_native_func_defs) / sizeof(WGLNativeFuncDef); diff --git a/core/iwasm/lib/native/extension/sensor/runtime_sensor.c b/core/iwasm/lib/native/extension/sensor/runtime_sensor.c index ffaf4826d7..54e1e799e0 100644 --- a/core/iwasm/lib/native/extension/sensor/runtime_sensor.c +++ b/core/iwasm/lib/native/extension/sensor/runtime_sensor.c @@ -22,8 +22,10 @@ static sys_sensor_t * g_sys_sensors = NULL; static int g_sensor_id_max = 0; -static sensor_client_t *find_sensor_client(sys_sensor_t * sensor, - unsigned int client_id, bool remove_if_found); + +static sensor_client_t * +find_sensor_client(sys_sensor_t * sensor, + unsigned int client_id, bool remove_if_found); void (*rechedule_sensor_callback)() = NULL; @@ -32,7 +34,8 @@ void (*rechedule_sensor_callback)() = NULL; * */ -static void sensor_event_cleaner(sensor_event_data_t *sensor_event) +static void +sensor_event_cleaner(sensor_event_data_t *sensor_event) { if (sensor_event->data != NULL) { if (sensor_event->data_fmt == FMT_ATTR_CONTAINER) @@ -44,8 +47,8 @@ static void sensor_event_cleaner(sensor_event_data_t *sensor_event) bh_free(sensor_event); } -static void wasm_sensor_callback(void *client, uint32 sensor_id, - void *user_data) +static void +wasm_sensor_callback(void *client, uint32 sensor_id, void *user_data) { attr_container_t *sensor_data = (attr_container_t *) user_data; attr_container_t *sensor_data_clone; @@ -92,7 +95,10 @@ static void wasm_sensor_callback(void *client, uint32 sensor_id, bh_post_msg2(module->queue, msg); } -bool wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay) +bool +wasm_sensor_config(wasm_module_inst_t module_inst, + uint32 sensor, int interval, + int bit_cfg, int delay) { attr_container_t * attr_cont; sensor_client_t * c; @@ -132,9 +138,10 @@ bool wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay) return true; } -uint32 wasm_sensor_open(int32 name_offset, int instance) +uint32 +wasm_sensor_open(wasm_module_inst_t module_inst, + int32 name_offset, int instance) { - wasm_module_inst_t module_inst = get_module_inst(); char *name = NULL; if (!validate_app_addr(name_offset, 1)) @@ -185,10 +192,11 @@ uint32 wasm_sensor_open(int32 name_offset, int instance) return -1; } -bool wasm_sensor_config_with_attr_container(uint32 sensor, int32 buffer_offset, - int len) +bool +wasm_sensor_config_with_attr_container(wasm_module_inst_t module_inst, + uint32 sensor, int32 buffer_offset, + int len) { - wasm_module_inst_t module_inst = get_module_inst(); char *buffer = NULL; if (!validate_app_addr(buffer_offset, len)) @@ -211,7 +219,8 @@ bool wasm_sensor_config_with_attr_container(uint32 sensor, int32 buffer_offset, return false; } -bool wasm_sensor_close(uint32 sensor) +bool +wasm_sensor_close(wasm_module_inst_t module_inst, uint32 sensor) { unsigned int mod_id = app_manager_get_module_id(Module_WASM_App); unsigned int client_id = mod_id; @@ -271,8 +280,9 @@ void refresh_read_interval(sensor_obj_t sensor) sensor->read_interval = interval; } -sensor_obj_t add_sys_sensor(char * name, char * description, int instance, - uint32 default_interval, void * read_func, void * config_func) +sensor_obj_t +add_sys_sensor(char * name, char * description, int instance, + uint32 default_interval, void * read_func, void * config_func) { sys_sensor_t * s = (sys_sensor_t *) bh_malloc(sizeof(sys_sensor_t)); if (s == NULL) diff --git a/core/iwasm/lib/native/extension/sensor/runtime_sensor.h b/core/iwasm/lib/native/extension/sensor/runtime_sensor.h index ce53392fa3..f19b4f09d9 100644 --- a/core/iwasm/lib/native/extension/sensor/runtime_sensor.h +++ b/core/iwasm/lib/native/extension/sensor/runtime_sensor.h @@ -19,6 +19,8 @@ #include "bh_platform.h" #include "attr_container.h" +#include "wasm_export.h" + struct _sys_sensor; typedef struct _sys_sensor* sensor_obj_t; @@ -60,16 +62,19 @@ int check_sensor_timers(); void reschedule_sensor_read(); uint32 -wasm_sensor_open(int32 name_offset, int instance); +wasm_sensor_open(wasm_module_inst_t module_inst, + int32 name_offset, int instance); bool -wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay); +wasm_sensor_config(wasm_module_inst_t module_inst, + uint32 sensor, int interval, int bit_cfg, int delay); bool -wasm_sensor_config_with_attr_container(uint32 sensor, int32 buffer_offset, - int len); +wasm_sensor_config_with_attr_container(wasm_module_inst_t module_inst, + uint32 sensor, int32 buffer_offset, + int len); bool -wasm_sensor_close(uint32 sensor); +wasm_sensor_close(wasm_module_inst_t module_inst, uint32 sensor); #endif /* LIB_EXTENSION_RUNTIME_SENSOR_H_ */ diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index 8972356ecd..bfd2c53df3 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -34,9 +34,6 @@ 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) @@ -454,9 +451,9 @@ parse_printf_args(wasm_module_inst_t module_inst, int32 fmt_offset, } static int -_printf_wrapper(int32 fmt_offset, int32 va_list_offset) +_printf_wrapper(wasm_module_inst_t module_inst, + 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; @@ -470,9 +467,9 @@ _printf_wrapper(int32 fmt_offset, int32 va_list_offset) } static int -_sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) +_sprintf_wrapper(wasm_module_inst_t module_inst, + int32 str_offset, int32 fmt_offset, int32 va_list_offset) { - wasm_module_inst_t module_inst = get_module_inst(); int32 app_end_offset; struct str_context ctx; char *str; @@ -505,10 +502,10 @@ _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) } static int -_snprintf_wrapper(int32 str_offset, int32 size, int32 fmt_offset, +_snprintf_wrapper(wasm_module_inst_t module_inst, + 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; @@ -537,9 +534,9 @@ _snprintf_wrapper(int32 str_offset, int32 size, int32 fmt_offset, } static int -_puts_wrapper(int32 str_offset) +_puts_wrapper(wasm_module_inst_t module_inst, + int32 str_offset) { - wasm_module_inst_t module_inst = get_module_inst(); const char *str; if (!validate_str_addr(module_inst, str_offset)) @@ -550,16 +547,16 @@ _puts_wrapper(int32 str_offset) } static int -_putchar_wrapper(int c) +_putchar_wrapper(wasm_module_inst_t module_inst, int c) { bh_printf("%c", c); return 1; } static int32 -_strdup_wrapper(int32 str_offset) +_strdup_wrapper(wasm_module_inst_t module_inst, + int32 str_offset) { - wasm_module_inst_t module_inst = get_module_inst(); char *str, *str_ret; uint32 len; int32 str_ret_offset = 0; @@ -583,9 +580,9 @@ _strdup_wrapper(int32 str_offset) } static int32 -_memcmp_wrapper(int32 s1_offset, int32 s2_offset, int32 size) +_memcmp_wrapper(wasm_module_inst_t module_inst, + 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) @@ -598,9 +595,9 @@ _memcmp_wrapper(int32 s1_offset, int32 s2_offset, int32 size) } static int32 -_memcpy_wrapper(int32 dst_offset, int32 src_offset, int32 size) +_memcpy_wrapper(wasm_module_inst_t module_inst, + int32 dst_offset, int32 src_offset, int32 size) { - wasm_module_inst_t module_inst = get_module_inst(); void *dst, *src; if (size == 0) @@ -617,9 +614,9 @@ _memcpy_wrapper(int32 dst_offset, int32 src_offset, int32 size) } static int32 -_memmove_wrapper(int32 dst_offset, int32 src_offset, int32 size) +_memmove_wrapper(wasm_module_inst_t module_inst, + 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) @@ -633,9 +630,9 @@ _memmove_wrapper(int32 dst_offset, int32 src_offset, int32 size) } static int32 -_memset_wrapper(int32 s_offset, int32 c, int32 size) +_memset_wrapper(wasm_module_inst_t module_inst, + 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)) @@ -647,9 +644,9 @@ _memset_wrapper(int32 s_offset, int32 c, int32 size) } static int32 -_strchr_wrapper(int32 s_offset, int32 c) +_strchr_wrapper(wasm_module_inst_t module_inst, + int32 s_offset, int32 c) { - wasm_module_inst_t module_inst = get_module_inst(); const char *s; char *ret; @@ -662,9 +659,9 @@ _strchr_wrapper(int32 s_offset, int32 c) } static int32 -_strcmp_wrapper(int32 s1_offset, int32 s2_offset) +_strcmp_wrapper(wasm_module_inst_t module_inst, + int32 s1_offset, int32 s2_offset) { - wasm_module_inst_t module_inst = get_module_inst(); void *s1, *s2; if (!validate_str_addr(module_inst, s1_offset) @@ -677,9 +674,9 @@ _strcmp_wrapper(int32 s1_offset, int32 s2_offset) } static int32 -_strncmp_wrapper(int32 s1_offset, int32 s2_offset, uint32 size) +_strncmp_wrapper(wasm_module_inst_t module_inst, + 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) @@ -692,9 +689,9 @@ _strncmp_wrapper(int32 s1_offset, int32 s2_offset, uint32 size) } static int32 -_strcpy_wrapper(int32 dst_offset, int32 src_offset) +_strcpy_wrapper(wasm_module_inst_t module_inst, + int32 dst_offset, int32 src_offset) { - wasm_module_inst_t module_inst = get_module_inst(); char *dst, *src; uint32 len; @@ -713,9 +710,9 @@ _strcpy_wrapper(int32 dst_offset, int32 src_offset) } static int32 -_strncpy_wrapper(int32 dst_offset, int32 src_offset, uint32 size) +_strncpy_wrapper(wasm_module_inst_t module_inst, + 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) @@ -729,9 +726,9 @@ _strncpy_wrapper(int32 dst_offset, int32 src_offset, uint32 size) } static uint32 -_strlen_wrapper(int32 s_offset) +_strlen_wrapper(wasm_module_inst_t module_inst, + int32 s_offset) { - wasm_module_inst_t module_inst = get_module_inst(); char *s; if (!validate_str_addr(module_inst, s_offset)) @@ -742,17 +739,17 @@ _strlen_wrapper(int32 s_offset) } static int32 -_malloc_wrapper(uint32 size) +_malloc_wrapper(wasm_module_inst_t module_inst, + uint32 size) { - wasm_module_inst_t module_inst = get_module_inst(); return module_malloc(size); } static int32 -_calloc_wrapper(uint32 nmemb, uint32 size) +_calloc_wrapper(wasm_module_inst_t module_inst, + 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; @@ -769,31 +766,30 @@ _calloc_wrapper(uint32 nmemb, uint32 size) } static void -_free_wrapper(int32 ptr_offset) +_free_wrapper(wasm_module_inst_t module_inst, + 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) +setTempRet0_wrapper(wasm_module_inst_t module_inst, + 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() +getTempRet0_wrapper(wasm_module_inst_t module_inst) { - 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) +_llvm_bswap_i16_wrapper(wasm_module_inst_t module_inst, + uint32 data) { return (data & 0xFFFF0000) | ((data & 0xFF) << 8) @@ -801,7 +797,8 @@ _llvm_bswap_i16_wrapper(uint32 data) } static uint32 -_llvm_bswap_i32_wrapper(uint32 data) +_llvm_bswap_i32_wrapper(wasm_module_inst_t module_inst, + uint32 data) { return ((data & 0xFF) << 24) | ((data & 0xFF00) << 8) @@ -810,10 +807,10 @@ _llvm_bswap_i32_wrapper(uint32 data) } static uint32 -_bitshift64Lshr_wrapper(uint32 uint64_part0, uint32 uint64_part1, +_bitshift64Lshr_wrapper(wasm_module_inst_t module_inst, + uint32 uint64_part0, uint32 uint64_part1, uint32 bits) { - wasm_module_inst_t module_inst = get_module_inst(); union { uint64 value; uint32 parts[2]; @@ -829,10 +826,10 @@ _bitshift64Lshr_wrapper(uint32 uint64_part0, uint32 uint64_part1, } static uint32 -_bitshift64Shl_wrapper(uint32 int64_part0, uint32 int64_part1, +_bitshift64Shl_wrapper(wasm_module_inst_t module_inst, + uint32 int64_part0, uint32 int64_part1, uint32 bits) { - wasm_module_inst_t module_inst = get_module_inst(); union { int64 value; uint32 parts[2]; @@ -848,26 +845,25 @@ _bitshift64Shl_wrapper(uint32 int64_part0, uint32 int64_part1, } static void -_llvm_stackrestore_wrapper(uint32 llvm_stack) +_llvm_stackrestore_wrapper(wasm_module_inst_t module_inst, + uint32 llvm_stack) { - wasm_module_inst_t module_inst = get_module_inst(); bh_printf("_llvm_stackrestore called!\n"); wasm_runtime_set_llvm_stack(module_inst, llvm_stack); } static uint32 -_llvm_stacksave_wrapper() +_llvm_stacksave_wrapper(wasm_module_inst_t module_inst) { - wasm_module_inst_t module_inst = get_module_inst(); bh_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, +_emscripten_memcpy_big_wrapper(wasm_module_inst_t module_inst, + 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) @@ -882,27 +878,27 @@ _emscripten_memcpy_big_wrapper(int32 dst_offset, int32 src_offset, } static void -abort_wrapper(int32 code) +abort_wrapper(wasm_module_inst_t module_inst, + 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) +abortStackOverflow_wrapper(wasm_module_inst_t module_inst, + 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) +nullFunc_X_wrapper(wasm_module_inst_t module_inst, + 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); @@ -912,13 +908,13 @@ nullFunc_X_wrapper(int32 code) #ifdef ENABLE_SPEC_TEST static void -print_i32_wrapper(int i32) +print_i32_wrapper(wasm_module_inst_t module_inst, int i32) { bh_printf("%d\n", i32); } static void -print_wrapper(int i32) +print_wrapper(wasm_module_inst_t module_inst, int i32) { bh_printf("%d\n", i32); } diff --git a/core/iwasm/runtime/platform/linux-sgx/wasm_native.c b/core/iwasm/runtime/platform/linux-sgx/wasm_native.c index 59b081b7b2..b8d64b08c2 100644 --- a/core/iwasm/runtime/platform/linux-sgx/wasm_native.c +++ b/core/iwasm/runtime/platform/linux-sgx/wasm_native.c @@ -35,9 +35,6 @@ #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) @@ -55,7 +52,7 @@ static int32 -__syscall0_wrapper(int32 arg0) +__syscall0_wrapper(WASMModuleInstance *module_inst, int32 arg0) { switch (arg0) { case 199: /* getuid */ @@ -67,7 +64,7 @@ __syscall0_wrapper(int32 arg0) } static int32 -__syscall1_wrapper(int32 arg0, int32 arg1) +__syscall1_wrapper(WASMModuleInstance *module_inst, int32 arg0, int32 arg1) { switch (arg0) { case 6: /* close */ @@ -79,7 +76,8 @@ __syscall1_wrapper(int32 arg0, int32 arg1) } static int32 -__syscall2_wrapper(int32 arg0, int32 arg1, int32 arg2) +__syscall2_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2) { switch (arg0) { case 183: /* getcwd */ @@ -91,10 +89,9 @@ __syscall2_wrapper(int32 arg0, int32 arg1, int32 arg2) } static int32 -__syscall3_wrapper(int32 arg0, int32 arg1, int32 arg2, int32 arg3) +__syscall3_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2, int32 arg3) { - WASMModuleInstance *module_inst = get_module_inst(); - switch (arg0) { case 146: /* writev */ { @@ -145,7 +142,8 @@ __syscall3_wrapper(int32 arg0, int32 arg1, int32 arg2, int32 arg3) } static int32 -__syscall4_wrapper(int32 arg0, int32 arg1, int32 arg2, +__syscall4_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2, int32 arg3, int32 arg4) { bh_printf("##_syscall4 called, syscall id: %d\n", arg0); @@ -153,7 +151,8 @@ __syscall4_wrapper(int32 arg0, int32 arg1, int32 arg2, } static int32 -__syscall5_wrapper(int32 arg0, int32 arg1, int32 arg2, +__syscall5_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2, int32 arg3, int32 arg4, int32 arg5) { switch (arg0) { @@ -166,46 +165,54 @@ __syscall5_wrapper(int32 arg0, int32 arg1, int32 arg2, } #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_WRAPPER0(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id) { \ + return __syscall0_wrapper(module_inst, id); \ } -#define EMCC_SYSCALL_WRAPPER1(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall1_wrapper(id, args[0]); \ +#define EMCC_SYSCALL_WRAPPER1(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall1_wrapper(module_inst, id, args[0]); \ } -#define EMCC_SYSCALL_WRAPPER2(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall2_wrapper(id, args[0], args[1]); \ +#define EMCC_SYSCALL_WRAPPER2(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off){ \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall2_wrapper(module_inst, id, args[0], args[1]); \ } -#define EMCC_SYSCALL_WRAPPER3(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall3_wrapper(id, args[0], args[1], args[2]); \ +#define EMCC_SYSCALL_WRAPPER3(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall3_wrapper(module_inst, id, \ + args[0], args[1], args[2]); \ } -#define EMCC_SYSCALL_WRAPPER4(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall4_wrapper(id, args[0], args[1], args[2], args[3]);\ +#define EMCC_SYSCALL_WRAPPER4(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall4_wrapper(module_inst, id, \ + args[0], args[1], args[2], args[3]); \ } -#define EMCC_SYSCALL_WRAPPER5(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall5_wrapper(id, args[0], args[1], args[2], \ - args[3], args[4]); \ +#define EMCC_SYSCALL_WRAPPER5(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall5_wrapper(module_inst, id, \ + args[0], args[1], args[2], \ + args[3], args[4]); \ } EMCC_SYSCALL_WRAPPER0(199) @@ -224,18 +231,16 @@ EMCC_SYSCALL_WRAPPER3(221) EMCC_SYSCALL_WRAPPER5(140) static int32 -getTotalMemory_wrapper() +getTotalMemory_wrapper(WASMModuleInstance *module_inst) { - 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() +enlargeMemory_wrapper(WASMModuleInstance *module_inst) { 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); @@ -254,9 +259,8 @@ enlargeMemory_wrapper() } static void -_abort_wrapper(int32 code) +_abort_wrapper(WASMModuleInstance *module_inst, int32 code) { - WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst(); char buf[32]; snprintf(buf, sizeof(buf), "env.abort(%i)", code); @@ -264,14 +268,13 @@ _abort_wrapper(int32 code) } static void -abortOnCannotGrowMemory_wrapper() +abortOnCannotGrowMemory_wrapper(WASMModuleInstance *module_inst) { - 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) +___setErrNo_wrapper(WASMModuleInstance *module_inst, int32 error_no) { errno = error_no; } @@ -330,3 +333,4 @@ wasm_platform_native_func_lookup(const char *module_name, return NULL; } + diff --git a/core/iwasm/runtime/platform/linux/wasm_native.c b/core/iwasm/runtime/platform/linux/wasm_native.c index c12e85c75b..638f57344a 100644 --- a/core/iwasm/runtime/platform/linux/wasm_native.c +++ b/core/iwasm/runtime/platform/linux/wasm_native.c @@ -35,9 +35,6 @@ #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) @@ -55,46 +52,46 @@ static int32 -__syscall0_wrapper(int32 arg0) +__syscall0_wrapper(WASMModuleInstance *module_inst, int32 arg0) { switch (arg0) { case 199: /* getuid */ /* TODO */ default: - printf("##_syscall0 called, syscall id: %d\n", arg0); + bh_printf("##_syscall0 called, syscall id: %d\n", arg0); } return 0; } static int32 -__syscall1_wrapper(int32 arg0, int32 arg1) +__syscall1_wrapper(WASMModuleInstance *module_inst, int32 arg0, int32 arg1) { switch (arg0) { case 6: /* close */ /* TODO */ default: - printf("##_syscall1 called, syscall id: %d\n", arg0); + bh_printf("##_syscall1 called, syscall id: %d\n", arg0); } return 0; } static int32 -__syscall2_wrapper(int32 arg0, int32 arg1, int32 arg2) +__syscall2_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2) { switch (arg0) { case 183: /* getcwd */ /* TODO */ default: - printf("##_syscall2 called, syscall id: %d\n", arg0); + bh_printf("##_syscall2 called, syscall id: %d\n", arg0); } return 0; } static int32 -__syscall3_wrapper(int32 arg0, int32 arg1, int32 arg2, int32 arg3) +__syscall3_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2, int32 arg3) { - WASMModuleInstance *module_inst = get_module_inst(); - switch (arg0) { case 54: /* ioctl */ { @@ -152,73 +149,83 @@ __syscall3_wrapper(int32 arg0, int32 arg1, int32 arg2, int32 arg3) case 221: /* fcntl */ /* TODO */ default: - printf("##_syscall3 called, syscall id: %d\n", arg0); + bh_printf("##_syscall3 called, syscall id: %d\n", arg0); } return 0; } static int32 -__syscall4_wrapper(int32 arg0, int32 arg1, int32 arg2, +__syscall4_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2, int32 arg3, int32 arg4) { - printf("##_syscall4 called, syscall id: %d\n", arg0); + bh_printf("##_syscall4 called, syscall id: %d\n", arg0); return 0; } static int32 -__syscall5_wrapper(int32 arg0, int32 arg1, int32 arg2, +__syscall5_wrapper(WASMModuleInstance *module_inst, + int32 arg0, int32 arg1, int32 arg2, int32 arg3, int32 arg4, int32 arg5) { switch (arg0) { case 140: /* llseek */ /* TODO */ default: - printf("##_syscall5 called, args[0]: %d\n", arg0); + 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_WRAPPER0(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id) { \ + return __syscall0_wrapper(module_inst, id); \ } -#define EMCC_SYSCALL_WRAPPER1(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall1_wrapper(id, args[0]); \ +#define EMCC_SYSCALL_WRAPPER1(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall1_wrapper(module_inst, id, args[0]); \ } -#define EMCC_SYSCALL_WRAPPER2(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall2_wrapper(id, args[0], args[1]); \ +#define EMCC_SYSCALL_WRAPPER2(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off){ \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall2_wrapper(module_inst, id, args[0], args[1]); \ } -#define EMCC_SYSCALL_WRAPPER3(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall3_wrapper(id, args[0], args[1], args[2]); \ +#define EMCC_SYSCALL_WRAPPER3(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall3_wrapper(module_inst, id, \ + args[0], args[1], args[2]); \ } -#define EMCC_SYSCALL_WRAPPER4(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall4_wrapper(id, args[0], args[1], args[2], args[3]);\ +#define EMCC_SYSCALL_WRAPPER4(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall4_wrapper(module_inst, id, \ + args[0], args[1], args[2], args[3]); \ } -#define EMCC_SYSCALL_WRAPPER5(id) \ - static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ - GET_EMCC_SYSCALL_ARGS(); \ - return __syscall5_wrapper(id, args[0], args[1], args[2], \ - args[3], args[4]); \ +#define EMCC_SYSCALL_WRAPPER5(id) \ + static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\ + int32 _id, int32 args_off) { \ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall5_wrapper(module_inst, id, \ + args[0], args[1], args[2], \ + args[3], args[4]); \ } EMCC_SYSCALL_WRAPPER0(199) @@ -237,18 +244,16 @@ EMCC_SYSCALL_WRAPPER3(221) EMCC_SYSCALL_WRAPPER5(140) static int32 -getTotalMemory_wrapper() +getTotalMemory_wrapper(WASMModuleInstance *module_inst) { - 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() +enlargeMemory_wrapper(WASMModuleInstance *module_inst) { 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); @@ -267,9 +272,8 @@ enlargeMemory_wrapper() } static void -_abort_wrapper(int32 code) +_abort_wrapper(WASMModuleInstance *module_inst, int32 code) { - WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst(); char buf[32]; snprintf(buf, sizeof(buf), "env.abort(%i)", code); @@ -277,14 +281,13 @@ _abort_wrapper(int32 code) } static void -abortOnCannotGrowMemory_wrapper() +abortOnCannotGrowMemory_wrapper(WASMModuleInstance *module_inst) { - 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) +___setErrNo_wrapper(WASMModuleInstance *module_inst, int32 error_no) { errno = error_no; } diff --git a/core/iwasm/runtime/vmcore-wasm/invokeNative_arm.s b/core/iwasm/runtime/vmcore-wasm/invokeNative_arm.s new file mode 100644 index 0000000000..10f6b591d7 --- /dev/null +++ b/core/iwasm/runtime/vmcore-wasm/invokeNative_arm.s @@ -0,0 +1,75 @@ +/* + * 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. + */ + .text + .align 2 + .global invokeNative + .type invokeNative,function + +/* + * Arguments passed in: + * + * r0 argv + * r1 argc + * r2 function pntr + */ + +invokeNative: + stmfd sp!, {r4, r5, r6, r7, lr} + mov r4, r0 /* get argv */ + mov r5, r1 /* get argc */ + mov ip, r2 /* get function ptr */ + + cmp r5, #2 /* is argc < 2 ? */ + blt return + + ldr r0, [r4], #4 /* argv[0] */ + ldr r1, [r4], #4 /* argv[1] */ + + mov r6, #0 + + cmp r5, #2 + beq call_func + ldr r2, [r4], #4 + cmp r5, #3 + beq call_func + ldr r3, [r4], #4 + + subs r5, r5, #4 /* now we have r0 ~ r3 */ + + /* Ensure address is 8 byte aligned */ + mov r6, r5, lsl#2 + add r6, r6, #7 + bic r6, r6, #7 + add r6, r6, #4 /* +4 because only odd(5) registers are in stack */ + subs sp, sp, r6 /* for stacked args */ + mov r7, sp + +loop_args: + cmp r5, #0 + beq call_func + ldr lr, [r4], #4 + str lr, [r7], #4 + subs r5, r5, #1 + b loop_args + +call_func: + blx ip + + add sp, sp, r6 /* recover sp */ + +return: + ldmfd sp!, {r4, r5, r6, r7, lr} + bx lr diff --git a/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s b/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s new file mode 100644 index 0000000000..d4c922f650 --- /dev/null +++ b/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s @@ -0,0 +1,72 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// Author: Ivan Volosyuk +// + .text + .align 2 +.globl invokeNative + .type invokeNative, @function +invokeNative: + /* rdi - memory */ + /* rsi - n fp args */ + /* rdx - n mem args */ + /* rcx - function ptr */ + + push %rbp + mov %rsp, %rbp + + /* cycle to fill all fp args */ + movq 8(%rdi), %xmm0 + movq 16(%rdi), %xmm1 + movq 24(%rdi), %xmm2 + movq 32(%rdi), %xmm3 + movq 40(%rdi), %xmm4 + movq 48(%rdi), %xmm5 + movq 56(%rdi), %xmm6 + movq 64(%rdi), %xmm7 + + mov %rsp, %r10 /* Check that stack is aligned on */ + and $8, %r10 /* 16 bytes. This code may be removed */ + jz no_abort /* when we are sure that compiler always */ + int3 /* calls us with aligned stack */ +no_abort: + mov %rdx, %r10 /* Align stack on 16 bytes before pushing */ + and $1, %r10 /* stack arguments in case we have an odd */ + shl $3, %r10 /* number of stack arguments */ + sub %r10, %rsp + /* store memory args */ + movq %rcx, %r10 /* func ptr */ + movq %rdx, %rcx /* counter */ + lea 8+64+48-8(%rdi,%rcx,8), %rdx + sub %rsp, %rdx + cmpq $0, %rcx + jz cycle_end +cycle: + push 0(%rsp,%rdx) + loop cycle +cycle_end: + movq 80(%rdi), %rsi + movq 88(%rdi), %rdx + movq 96(%rdi), %rcx + movq 104(%rdi), %r8 + movq 112(%rdi), %r9 + + movq 72(%rdi), %rdi + + call *%r10 + leave + ret + diff --git a/core/iwasm/runtime/vmcore-wasm/invokeNative_mips.s b/core/iwasm/runtime/vmcore-wasm/invokeNative_mips.s new file mode 100644 index 0000000000..bf1ad59657 --- /dev/null +++ b/core/iwasm/runtime/vmcore-wasm/invokeNative_mips.s @@ -0,0 +1,85 @@ +/* + * 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. + */ + + .text + .align 2 + .globl invokeNative + .ent invokeNative + .type invokeNative, @function + +/** + * On function entry parameters: + * $4 = args + * $5 = arg_num + * $6 = func_ptr + */ + +invokeNative: + .frame $fp, 8, $0 + .mask 0x00000000, 0 + .fmask 0x00000000, 0 + + /* Fixed part of frame */ + subu $sp, 8 + + /* save registers */ + sw $31, 4($sp) + sw $fp, 0($sp) + + /* set frame pointer to bottom of fixed frame */ + move $fp, $sp + + /* allocate enough stack space */ + sll $11, $5, 2 + subu $sp, $11 + + /* make 8-byte aligned */ + and $sp, ~7 + + move $9, $sp + move $25, $6 /* $25 = func_ptr */ + +push_args: + beq $5, 0, done /* arg_num == 0 ? */ + lw $8, 0($4) + sw $8, 0($9) + addu $4, 4 + addu $9, 4 + subu $5, 1 /* arg_index-- */ + j push_args + +done: + lw $4, 0($sp) /* Load $4..$7 from stack */ + lw $5, 4($sp) + lw $6, 8($sp) + lw $7, 12($sp) + ldc1 $f12, 0($sp) /* Load $f12, $f13, $f14, $f15 */ + ldc1 $f14, 8($sp) + + jalr $25 /* call function */ + + nop + + /* restore saved registers */ + move $sp, $fp + lw $31, 4($sp) + lw $fp, 0($sp) + + /* pop frame */ + addu $sp, $sp, 8 + + j $31 + .end invokeNative diff --git a/core/iwasm/runtime/vmcore-wasm/vmcore.cmake b/core/iwasm/runtime/vmcore-wasm/vmcore.cmake index 8e3d94ca96..7af218ee6f 100644 --- a/core/iwasm/runtime/vmcore-wasm/vmcore.cmake +++ b/core/iwasm/runtime/vmcore-wasm/vmcore.cmake @@ -17,11 +17,13 @@ set (VMCORE_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) include_directories(${VMCORE_LIB_DIR}) include_directories(${VMCORE_LIB_DIR}/../include) +file (GLOB_RECURSE c_source_all ${VMCORE_LIB_DIR}/*.c) +list (REMOVE_ITEM c_source_all ${VMCORE_LIB_DIR}/invokeNative_general.c) + if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") -file (GLOB_RECURSE source_all ${VMCORE_LIB_DIR}/*.c) +set (source_all ${c_source_all} ${VMCORE_LIB_DIR}/invokeNative_em64.s) else () -file (GLOB_RECURSE source_all ${VMCORE_LIB_DIR}/*.c ${VMCORE_LIB_DIR}/*.s) -list (REMOVE_ITEM source_all ${VMCORE_LIB_DIR}/invokeNative_general.c) +set (source_all ${c_source_all} ${VMCORE_LIB_DIR}/invokeNative_ia32.s) endif () set (VMCORE_LIB_SOURCE ${source_all}) diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index 04cf744008..d4afabe5e1 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -284,7 +284,7 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign) } if (sign && (shift < maxbits) && (byte & 0x40)) { /* Sign extend */ - result |= - (1 << shift); + result |= - ((uint64)1 << shift); } return result; } @@ -622,21 +622,6 @@ FREE_FRAME(WASMThread *self, WASMInterpFrame *frame) wasm_thread_free_wasm_frame(self, frame); } -typedef void (*GenericFunctionPointer)(); -int64 invokeNative(uint32 *args, uint32 sz, GenericFunctionPointer f); - -typedef float64 (*Float64FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef float32 (*Float32FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef int64 (*Int64FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef int32 (*Int32FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef void (*VoidFuncPtr)(uint32*, uint32, GenericFunctionPointer); - -static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative; -static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative; -static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative; -static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative; -static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative; - static void wasm_interp_call_func_native(WASMThread *self, WASMFunctionInstance *cur_func, @@ -644,9 +629,8 @@ wasm_interp_call_func_native(WASMThread *self, { unsigned local_cell_num = 2; WASMInterpFrame *frame; - typedef void (*F)(WASMThread*, uint32 *argv); - union { F f; void *v; } u; - uint32 argv_buf[32], *argv, argc = cur_func->param_cell_num; + uint32 argv_ret[2]; + bool ret; if (!(frame = ALLOC_FRAME (self, wasm_interp_interp_frame_size(local_cell_num), prev_frame))) @@ -658,60 +642,24 @@ wasm_interp_call_func_native(WASMThread *self, wasm_thread_set_cur_frame (self, frame); - if (argc <= 32) - argv = argv_buf; - else { - if (!(argv = wasm_malloc(sizeof(uint32) * argc))) { - wasm_runtime_set_exception(self->module_inst, - "WASM call native failed: allocate memory failed."); - return; - } - } - - word_copy(argv, frame->lp, argc); + ret = wasm_runtime_invoke_native(cur_func->u.func_import->func_ptr_linked, + cur_func->u.func_import->func_type, + self->module_inst, + frame->lp, cur_func->param_cell_num, argv_ret); - u.v = cur_func->u.func_import->func_ptr_linked; - { - WASMType *func_type = cur_func->u.func_import->func_type; - uint8 ret_type = func_type->result_count - ? func_type->types[func_type->param_count] - : VALUE_TYPE_VOID; - GenericFunctionPointer f = (GenericFunctionPointer)(uintptr_t)u.v; - - if (func_type->result_count == 0) { - invokeNative_Void(argv, argc, f); - } - else { - switch (ret_type) { - case VALUE_TYPE_I32: - argv[0] = invokeNative_Int32(argv, argc, f); - break; - case VALUE_TYPE_I64: - PUT_I64_TO_ADDR(argv, invokeNative_Int64(argv, argc, f)); - break; - case VALUE_TYPE_F32: - *(float32*)argv = invokeNative_Float32(argv, argc, f); - break; - case VALUE_TYPE_F64: - PUT_F64_TO_ADDR(argv, invokeNative_Float64(argv, argc, f)); - break; - } - } - } + if (!ret) + return; if (cur_func->ret_cell_num == 1) { - prev_frame->sp[0] = argv[0]; + prev_frame->sp[0] = argv_ret[0]; prev_frame->sp++; } else if (cur_func->ret_cell_num == 2) { - prev_frame->sp[0] = argv[0]; - prev_frame->sp[1] = argv[1]; + prev_frame->sp[0] = argv_ret[0]; + prev_frame->sp[1] = argv_ret[1]; prev_frame->sp += 2; } - if (argc > 32) - wasm_free(argv); - FREE_FRAME(self, frame); wasm_thread_set_cur_frame(self, prev_frame); } diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index dbf8a4dcd1..8057f38053 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -72,7 +72,7 @@ read_leb(const uint8 *buf, const uint8 *buf_end, } if (sign && (shift < maxbits) && (byte & 0x40)) { /* Sign extend */ - result |= - (1 << shift); + result |= - ((uint64)1 << shift); } *p_result = result; return true; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index eec38bcc98..fc46f97d55 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -70,33 +70,41 @@ wasm_runtime_call_wasm(WASMModuleInstance *module_inst, WASMFunctionInstance *function, unsigned argc, uint32 argv[]) { - if (!exec_env) { - if (!module_inst->wasm_stack) { - if (!(module_inst->wasm_stack = - wasm_malloc(module_inst->wasm_stack_size))) { - wasm_runtime_set_exception(module_inst, "allocate memory failed."); - return false; - } - } - - init_wasm_stack(&module_inst->main_tlr.wasm_stack, - module_inst->wasm_stack, module_inst->wasm_stack_size); - } - else { - uintptr_t stack = (uintptr_t)exec_env->stack; - uint32 stack_size; - - /* Set to 8 bytes align */ - stack = (stack + 7) & ~7; - stack_size = exec_env->stack_size - (stack - (uintptr_t)exec_env->stack); + /* Only init stack when no application is running. */ + if (!wasm_runtime_get_self()->cur_frame) { + if (!exec_env) { + if (!module_inst->wasm_stack) { + if (!(module_inst->wasm_stack = + wasm_malloc(module_inst->wasm_stack_size))) { + wasm_runtime_set_exception(module_inst, + "allocate memory failed."); + return false; + } - if (!exec_env->stack || exec_env->stack_size <= 0 - || exec_env->stack_size < stack - (uintptr_t)exec_env->stack) { - wasm_runtime_set_exception(module_inst, "Invalid execution stack info."); - return false; - } + init_wasm_stack(&module_inst->main_tlr.wasm_stack, + module_inst->wasm_stack, + module_inst->wasm_stack_size); + } + } + else { + uintptr_t stack = (uintptr_t)exec_env->stack; + uint32 stack_size; + + /* Set to 8 bytes align */ + stack = (stack + 7) & ~7; + stack_size = exec_env->stack_size + - (stack - (uintptr_t)exec_env->stack); + + if (!exec_env->stack || exec_env->stack_size <= 0 + || exec_env->stack_size < stack - (uintptr_t)exec_env->stack) { + wasm_runtime_set_exception(module_inst, + "Invalid execution stack info."); + return false; + } - init_wasm_stack(&module_inst->main_tlr.wasm_stack, (uint8*)stack, stack_size); + init_wasm_stack(&module_inst->main_tlr.wasm_stack, + (uint8*)stack, stack_size); + } } wasm_interp_call_wasm(function, argc, argv); @@ -1419,3 +1427,248 @@ wasm_runtime_load_aot(uint8 *aot_file, uint32 aot_file_size, return NULL; } +static inline void +word_copy(uint32 *dest, uint32 *src, unsigned num) +{ + for (; num > 0; num--) + *dest++ = *src++; +} + +#define PUT_I64_TO_ADDR(addr, value) do { \ + union { int64 val; uint32 parts[2]; } u; \ + u.val = (value); \ + (addr)[0] = u.parts[0]; \ + (addr)[1] = u.parts[1]; \ + } while (0) + +#define PUT_F64_TO_ADDR(addr, value) do { \ + union { float64 val; uint32 parts[2]; } u; \ + u.val = (value); \ + (addr)[0] = u.parts[0]; \ + (addr)[1] = u.parts[1]; \ + } while (0) + +#if !defined(__x86_64__) && !defined(__amd_64__) + +typedef void (*GenericFunctionPointer)(); +int64 invokeNative(uint32 *args, uint32 sz, GenericFunctionPointer f); + +typedef float64 (*Float64FuncPtr)(uint32*, uint32, GenericFunctionPointer); +typedef float32 (*Float32FuncPtr)(uint32*, uint32, GenericFunctionPointer); +typedef int64 (*Int64FuncPtr)(uint32*, uint32, GenericFunctionPointer); +typedef int32 (*Int32FuncPtr)(uint32*, uint32, GenericFunctionPointer); +typedef void (*VoidFuncPtr)(uint32*, uint32, GenericFunctionPointer); + +static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative; +static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative; +static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative; +static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative; +static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative; + +/* As JavaScript can't represent int64s, emcc compiles C int64 argument + into two WASM i32 arguments, see: + https://github.com/emscripten-core/emscripten/issues/7199 + And also JavaScript float point is always 64-bit, emcc compiles + float32 argument into WASM f64 argument. + But clang compiles C int64 argument into WASM i64 argument, and + compiles C float32 argument into WASM f32 argument. + So for the compatability of emcc and clang, we treat i64 as two i32s, + treat f32 as f64 while passing arguments to the native function, and + require the native function uses two i32 arguments instead one i64 + argument, and uses double argument instead of float argment. */ + +bool +wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, + WASMModuleInstance *module_inst, + uint32 *argv, uint32 argc, uint32 *ret) +{ + union { float64 val; int32 parts[2]; } u; + uint32 argv_buf[32], *argv1 = argv_buf, argc1, i, j = 0; + uint64 size; + + argc1 = func_type->param_count * 2 + 2; + + if (argc1 > sizeof(argv_buf) / sizeof(uint32)) { + size = ((uint64)sizeof(uint32)) * argc1; + if (size >= UINT_MAX + || !(argv1 = wasm_malloc((uint32)size))) { + wasm_runtime_set_exception(module_inst, "allocate memory failed."); + return false; + } + } + + for (i = 0; i < sizeof(WASMModuleInstance*) / sizeof(uint32); i++) + argv1[j++] = ((uint32*)&module_inst)[i]; + + for (i = 0; i < func_type->param_count; i++) { + switch (func_type->types[i]) { + case VALUE_TYPE_I32: + argv1[j++] = *argv++; + break; + case VALUE_TYPE_I64: + case VALUE_TYPE_F64: + argv1[j++] = *argv++; + argv1[j++] = *argv++; + break; + case VALUE_TYPE_F32: + u.val = *(float32*)argv++; +#if defined(__arm__) || defined(__mips__) + /* 64-bit data must be 8 bytes alined in arm and mips */ + if (j & 1) + j++; +#endif + argv1[j++] = u.parts[0]; + argv1[j++] = u.parts[1]; + break; + default: + wasm_assert(0); + break; + } + } + + if (func_type->result_count == 0) { + invokeNative_Void(argv1, argc1, func_ptr); + } + else { + switch (func_type->types[func_type->param_count]) { + case VALUE_TYPE_I32: + ret[0] = invokeNative_Int32(argv1, argc1, func_ptr); + break; + case VALUE_TYPE_I64: + PUT_I64_TO_ADDR(ret, invokeNative_Int64(argv1, argc1, func_ptr)); + break; + case VALUE_TYPE_F32: + *(float32*)ret = invokeNative_Float32(argv1, argc1, func_ptr); + break; + case VALUE_TYPE_F64: + PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, argc1, func_ptr)); + break; + } + } + + if (argv1 != argv_buf) + wasm_free(argv1); + return true; +} + +#else /* else of !defined(__x86_64__) && !defined(__amd_64__) */ + +typedef void (*GenericFunctionPointer)(); +int64 invokeNative(uint64 *args, uint64 n_fps, uint64 n_stacks, GenericFunctionPointer f); + +typedef float64 (*Float64FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); +typedef float32 (*Float32FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); +typedef int64 (*Int64FuncPtr)(uint64*,uint64, uint64, GenericFunctionPointer); +typedef int32 (*Int32FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); +typedef void (*VoidFuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); + +static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative; +static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative; +static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative; +static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative; +static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative; + +#if defined(_WIN32) || defined(_WIN32_) +#define MAX_REG_FLOATS 4 +#define MAX_REG_INTS 4 +#else +#define MAX_REG_FLOATS 8 +#define MAX_REG_INTS 6 +#endif + +bool +wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, + WASMModuleInstance *module_inst, + uint32 *argv, uint32 argc, uint32 *ret) +{ + uint64 argv_buf[32], *argv1 = argv_buf, *fps, *ints, *stacks, size; + uint32 *argv_src = argv, i, j, argc1, n_ints = 0, n_stacks = 0; +#if defined(_WIN32) || defined(_WIN32_) + /* important difference in calling conventions */ +#define n_fps n_ints +#else + int n_fps = 0; +#endif + + argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2; + if (argc1 > sizeof(argv_buf) / sizeof(uint64)) { + size = sizeof(uint64) * argc1; + if (size >= UINT32_MAX + || !(argv1 = wasm_malloc(size))) { + wasm_runtime_set_exception(module_inst, "allocate memory failed."); + return false; + } + } + + fps = argv1 + 1; + ints = fps + MAX_REG_FLOATS; + stacks = ints + MAX_REG_INTS; + + ints[n_ints++] = (uint64)(uintptr_t)module_inst; + + for (i = 0; i < func_type->param_count; i++) { + switch (func_type->types[i]) { + case VALUE_TYPE_I32: + if (n_ints < MAX_REG_INTS) + ints[n_ints++] = *argv_src++; + else + stacks[n_stacks++] = *argv_src++; + break; + case VALUE_TYPE_I64: + for (j = 0; j < 2; j++) { + if (n_ints < MAX_REG_INTS) + ints[n_ints++] = *argv_src++; + else + stacks[n_stacks++] = *argv_src++; + } + break; + case VALUE_TYPE_F32: + if (n_fps < MAX_REG_FLOATS) + *(float64*)&fps[n_fps++] = *(float32*)argv_src++; + else + *(float64*)&stacks[n_stacks++] = *(float32*)argv_src++; + break; + case VALUE_TYPE_F64: + if (n_fps < MAX_REG_FLOATS) + *(float64*)&fps[n_fps++] = *(float64*)argv_src; + else + *(float64*)&stacks[n_stacks++] = *(float64*)argv_src; + argv_src += 2; + break; + default: + wasm_assert(0); + break; + } + } + + if (func_type->result_count == 0) { + invokeNative_Void(argv1, n_fps, n_stacks, func_ptr); + } + else { + switch (func_type->types[func_type->param_count]) { + case VALUE_TYPE_I32: + ret[0] = invokeNative_Int32(argv1, n_fps, n_stacks, func_ptr); + break; + case VALUE_TYPE_I64: + PUT_I64_TO_ADDR(ret, invokeNative_Int64(argv1, n_fps, n_stacks, func_ptr)); + break; + case VALUE_TYPE_F32: + *(float32*)ret = invokeNative_Float32(argv1, n_fps, n_stacks, func_ptr); + break; + case VALUE_TYPE_F64: + PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, n_fps, n_stacks, func_ptr)); + break; + default: + wasm_assert(0); + break; + } + } + + if (argv1 != argv_buf) + wasm_free(argv1); + + return true; +} + +#endif /* end of !defined(__x86_64__) && !defined(__amd_64__) */ + diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h index 30ef58c335..85c0bcf37d 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h @@ -315,6 +315,11 @@ int32 wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst, void *native_ptr); +bool +wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, + WASMModuleInstance *module_inst, + uint32 *argv, uint32 argc, uint32 *ret); + #ifdef __cplusplus } #endif diff --git a/core/shared-lib/mem-alloc/ems/ems_alloc.c b/core/shared-lib/mem-alloc/ems/ems_alloc.c index 2c27b71cf6..ca575f35bd 100644 --- a/core/shared-lib/mem-alloc/ems/ems_alloc.c +++ b/core/shared-lib/mem-alloc/ems/ems_alloc.c @@ -152,7 +152,7 @@ void gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size) bh_assert( hmu && (gc_uint8*) hmu >= heap->base_addr && (gc_uint8*) hmu < heap->base_addr + heap->current_size); - bh_assert(((gc_uint32) hmu_to_obj(hmu) & 7) == 0); + bh_assert(((gc_uint32)(uintptr_t)hmu_to_obj(hmu) & 7) == 0); bh_assert( size > 0 && ((gc_uint8*) hmu) + size @@ -242,7 +242,7 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size) p = node->next; node->next = p->next; - bh_assert(((gc_int32) hmu_to_obj(p) & 7) == 0); + bh_assert(((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) == 0); if ((gc_size_t) node_idx != init_node_idx&& ((gc_size_t)node_idx << 3) >= size + GC_SMALLEST_SIZE) { /* with bigger size*/ diff --git a/core/shared-lib/platform/darwin/bh_platform.c b/core/shared-lib/platform/darwin/bh_platform.c old mode 100755 new mode 100644 diff --git a/core/shared-lib/platform/darwin/bh_thread.c b/core/shared-lib/platform/darwin/bh_thread.c old mode 100755 new mode 100644 diff --git a/core/shared-lib/platform/darwin/bh_time.c b/core/shared-lib/platform/darwin/bh_time.c old mode 100755 new mode 100644 diff --git a/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c b/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c index e478b7e45d..4f696f0ad9 100644 --- a/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c +++ b/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c @@ -1,5 +1,5 @@ #include "lib_export.h" -#include "native_interface.h" +#include "sensor_api.h" #include "connection_api.h" #include "gui_api.h" diff --git a/samples/littlevgl/vgl-wasm-runtime/src/display_indev.h b/samples/littlevgl/vgl-wasm-runtime/src/display_indev.h index 154071e362..cb8d76e0e1 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/display_indev.h +++ b/samples/littlevgl/vgl-wasm-runtime/src/display_indev.h @@ -1,9 +1,10 @@ #ifndef DISPLAY_INDEV_H_ #define DISPLAY_INDEV_H_ #include -#include "bh_platform.h" #include #include +#include "bh_platform.h" +#include "wasm_export.h" #define USE_MOUSE 1 typedef union { @@ -54,21 +55,37 @@ enum { LV_OPA_100 = 255, LV_OPA_COVER = 255, }; -extern void display_init(void); -extern void display_deinit(void); -extern int time_get_ms(); -extern bool touchscreen_read(lv_indev_data_t * data); extern void xpt2046_init(void); -extern void display_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - int32 color_p_offset); -extern void display_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - lv_color_t color_p); -extern void display_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - const lv_color_t * color_p); -extern bool display_input_read(int32 data_offset); -void display_vdb_write(int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, int32 color_p_offset, lv_opa_t opa); + +extern bool touchscreen_read(lv_indev_data_t * data); + extern bool mouse_read(lv_indev_data_t * data); + +extern void display_init(wasm_module_inst_t module_inst); + +extern void display_deinit(wasm_module_inst_t module_inst); + +extern int time_get_ms(wasm_module_inst_t module_inst); + +extern void display_flush(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32 color_p_offset); + +extern void display_fill(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + lv_color_t color_p); + +extern void display_map(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + const lv_color_t * color_p); + +extern bool display_input_read(wasm_module_inst_t module_inst, + int32 data_offset); + +void display_vdb_write(wasm_module_inst_t module_inst, + int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, + lv_coord_t y, int32 color_p_offset, lv_opa_t opa); + #endif diff --git a/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c b/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c index 3897b3b0b4..0f68dd8602 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c @@ -1,5 +1,5 @@ #include "lib_export.h" -#include "native_interface.h" +#include "sensor_api.h" #include "connection_api.h" #include "display_indev.h" @@ -12,6 +12,7 @@ static NativeSymbol extended_native_symbol_defs[] = { EXPORT_WASM_API(display_fill), EXPORT_WASM_API(display_vdb_write), EXPORT_WASM_API(display_map), - EXPORT_WASM_API(time_get_ms), }; + EXPORT_WASM_API(time_get_ms) +}; #include "ext_lib_export.h" diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c index f7d8b5ccec..5fe98d4293 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c @@ -35,7 +35,8 @@ static uint32_t tft_fb[MONITOR_HOR_RES * MONITOR_VER_RES]; -int time_get_ms() +int +time_get_ms(wasm_module_inst_t module_inst) { static struct timeval tv; gettimeofday(&tv, NULL); @@ -157,15 +158,16 @@ void monitor_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, } -void display_init(void) +void +display_init(wasm_module_inst_t module_inst) { } -void display_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - int32 color_p_offset) +void +display_flush(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32 color_p_offset) { - - wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, color_p_offset, 1)) return; lv_color_t * color_p = wasm_runtime_addr_app_to_native(module_inst, @@ -173,21 +175,28 @@ void display_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, monitor_flush(x1, y1, x2, y2, color_p); } -void display_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - lv_color_t color_p) + +void +display_fill(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + lv_color_t color_p) { monitor_fill(x1, y1, x2, y2, color_p); } -void display_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - const lv_color_t * color_p) + +void +display_map(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + const lv_color_t * color_p) { monitor_map(x1, y1, x2, y2, color_p); } -bool display_input_read(int32 data_p_offset) +bool +display_input_read(wasm_module_inst_t module_inst, + int32 data_p_offset) { bool ret; - wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, data_p_offset, 1)) return false; @@ -205,21 +214,23 @@ bool display_input_read(int32 data_p_offset) data_p_offset); data_app->point = data.point; - data_app->user_data_offset = (int32_t)data.user_data; + data_app->user_data_offset = + wasm_runtime_addr_native_to_app(module_inst, data.user_data); data_app->state = data.state; return ret; } -void display_deinit(void) +void +display_deinit(wasm_module_inst_t module_inst) { - } -void display_vdb_write(int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, int32 color_p_offset, lv_opa_t opa) +void +display_vdb_write(wasm_module_inst_t module_inst, + int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, + lv_coord_t y, int32 color_p_offset, lv_opa_t opa) { - wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, color_p_offset, 1)) return; lv_color_t *color = wasm_runtime_addr_app_to_native(module_inst, diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_indev.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_indev.c index 1ed562c028..58ac43f724 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_indev.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_indev.c @@ -24,8 +24,11 @@ #ifndef MONITOR_ZOOM #define MONITOR_ZOOM 1 #endif -int lcd_initialized = 0; -void display_init(void) + +static int lcd_initialized = 0; + +void +display_init(wasm_module_inst_t module_inst) { if (lcd_initialized != 0) { return; @@ -36,10 +39,11 @@ void display_init(void) display_blanking_off(NULL); } -void display_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - int32 color_p_offset) +void +display_flush(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32 color_p_offset) { - wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, color_p_offset, 1)) return; lv_color_t * color_p = wasm_runtime_addr_app_to_native(module_inst, @@ -57,20 +61,24 @@ void display_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, /*lv_flush_ready();*/ } -void display_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - lv_color_t color_p) -{ -} -void display_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - const lv_color_t * color_p) +void +display_fill(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + lv_color_t color_p) { +} +void +display_map(wasm_module_inst_t module_inst, + int32_t x1, int32_t y1, int32_t x2, int32_t y2, + const lv_color_t * color_p) +{ } -bool display_input_read(int32 data_p_offset) +bool +display_input_read(wasm_module_inst_t module_inst, int32 data_p_offset) { - wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, data_p_offset, 1)) return false; lv_indev_data_t * data = wasm_runtime_addr_app_to_native(module_inst, @@ -80,15 +88,17 @@ bool display_input_read(int32 data_p_offset) } -void display_deinit(void) +void +display_deinit(wasm_module_inst_t module_inst) { } -void display_vdb_write(int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, int32 color_p_offset, lv_opa_t opa) +void +display_vdb_write(wasm_module_inst_t module_inst, + int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, + lv_coord_t y, int32 color_p_offset, lv_opa_t opa) { - wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, color_p_offset, 1)) return; lv_color_t *color = wasm_runtime_addr_app_to_native(module_inst, @@ -112,7 +122,8 @@ void display_vdb_write(int32 buf_offset, lv_coord_t buf_w, lv_coord_t x, *(buf_xy + 2) = color->blue; } -int time_get_ms() +int +time_get_ms(wasm_module_inst_t module_inst) { return k_uptime_get_32(); } diff --git a/test-tools/host-tool/CMakeLists.txt b/test-tools/host-tool/CMakeLists.txt index df1512a7b0..ea9438707c 100644 --- a/test-tools/host-tool/CMakeLists.txt +++ b/test-tools/host-tool/CMakeLists.txt @@ -51,6 +51,7 @@ add_definitions(-Wall -Wno-pointer-sign -DMALLOC_MEMORY_FROM_SYSTEM) include_directories( ${CMAKE_CURRENT_LIST_DIR}/src + ${WASM_DIR}/runtime/include ) file (GLOB_RECURSE HOST_TOOL_SRC src/*.c) diff --git a/test-tools/host-tool/src/main.c b/test-tools/host-tool/src/main.c index ead6a9b969..e4a3a48de3 100644 --- a/test-tools/host-tool/src/main.c +++ b/test-tools/host-tool/src/main.c @@ -95,11 +95,6 @@ typedef enum REPLY_PACKET_TYPE { REPLY_TYPE_EVENT = 0, REPLY_TYPE_RESPONSE = 1 } REPLY_PACKET_TYPE; -/* Package Type */ -typedef enum { - Wasm_Module_Bytecode = 0, Wasm_Module_AoT, Package_Type_Unknown = 0xFFFF -} PackageType; - static uint32_t g_timeout_ms = DEFAULT_TIMEOUT_MS; static uint32_t g_alive_time_ms = DEFAULT_ALIVE_TIME_MS; static char *g_redirect_file_name = NULL; @@ -153,7 +148,7 @@ static int send_request(request_t *request, bool is_install_wasm_bytecode_app) return ret; } -static PackageType get_package_type(const char *buf, int size) +static package_type_t get_app_package_type(const char *buf, int size) { if (buf && size > 4) { if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 's' && buf[3] == 'm') @@ -205,7 +200,7 @@ static int install(inst_info *info) request->mid = gen_random_id(); if ((info->module_type == NULL || strcmp(info->module_type, "wasm") == 0) - && get_package_type(app_file_buf, app_size) == Wasm_Module_Bytecode) + && get_app_package_type(app_file_buf, app_size) == Wasm_Module_Bytecode) is_wasm_bytecode_app = true; else is_wasm_bytecode_app = false; From 46fa0097bb673d8a5c322b96946b7790595add33 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Wed, 11 Sep 2019 15:54:44 +0800 Subject: [PATCH 16/18] Remove get_module_inst() and fix issue of call native --- .../lib/native-interface/native_interface.h | 3 - .../lib/native-interface/wasm_export_api.h | 86 +++++++++++--- core/iwasm/lib/native/base/base_lib_export.c | 107 +++++++++++------- .../native/extension/gui/wgl_native_utils.h | 4 + core/iwasm/runtime/include/wasm_export.h | 9 -- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 52 ++++----- 6 files changed, 164 insertions(+), 97 deletions(-) diff --git a/core/iwasm/lib/native-interface/native_interface.h b/core/iwasm/lib/native-interface/native_interface.h index 928297740a..fd8be85b1d 100644 --- a/core/iwasm/lib/native-interface/native_interface.h +++ b/core/iwasm/lib/native-interface/native_interface.h @@ -22,9 +22,6 @@ #include "bh_platform.h" #include "wasm_export.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) diff --git a/core/iwasm/lib/native-interface/wasm_export_api.h b/core/iwasm/lib/native-interface/wasm_export_api.h index ed9d570f81..ebd67b5d37 100644 --- a/core/iwasm/lib/native-interface/wasm_export_api.h +++ b/core/iwasm/lib/native-interface/wasm_export_api.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef _WASM_EXPORT_H -#define _WASM_EXPORT_H +#ifndef _WASM_EXPORT_API_H +#define _WASM_EXPORT_API_H #include #include @@ -28,6 +28,31 @@ extern "C" { #endif +void +wasm_runtime_get_current_module_inst1(uint64_t *p_module_inst); + +bool +wasm_runtime_validate_app_addr1(uint32_t module_inst_part0, + uint32_t module_inst_part1, + int32_t app_offset, uint32_t size); +bool +wasm_runtime_validate_native_addr1(uint32_t module_inst_part0, + uint32_t module_inst_part1, + uint32_t native_ptr_part0, + uint32_t native_ptr_part1, + uint32_t size); +bool +wasm_runtime_addr_app_to_native1(uint32_t module_inst_part0, + uint32_t module_inst_part1, + int32_t app_offset, + uint64_t *p_native_ptr); + +int32_t +wasm_runtime_addr_native_to_app1(uint32_t module_inst_part0, + uint32_t module_inst_part1, + uint32_t native_ptr_part0, + uint32_t native_ptr_part1); + /** * Get current WASM module instance of the current native thread * @@ -39,8 +64,13 @@ extern "C" { * 32-bit and 64-bit. And if the native pointer is 64-bit, data loss * occurs after converting it to WASM i32 type. */ -uint64_t -wasm_runtime_get_current_module_inst(); +static inline uint64_t +wasm_runtime_get_current_module_inst() +{ + uint64_t module_inst; + wasm_runtime_get_current_module_inst1(&module_inst); + return module_inst; +} /** * Validate the app address, check whether it belongs to WASM module @@ -52,9 +82,15 @@ wasm_runtime_get_current_module_inst(); * * @return true if success, false otherwise. */ -bool +static inline bool wasm_runtime_validate_app_addr(uint64_t module_inst, - int32_t app_offset, uint32_t size); + int32_t app_offset, uint32_t size) +{ + union { uint64_t val; uint32_t parts[2]; } u; + u.val = module_inst; + return wasm_runtime_validate_app_addr1(u.parts[0], u.parts[1], + app_offset, size); +} /** * Validate the native address, check whether it belongs to WASM module @@ -67,9 +103,17 @@ wasm_runtime_validate_app_addr(uint64_t module_inst, * * @return true if success, false otherwise. */ -bool +static inline bool wasm_runtime_validate_native_addr(uint64_t module_inst, - uint64_t native_ptr, uint32_t size); + uint64_t native_ptr, uint32_t size) +{ + union { uint64_t val; uint32_t parts[2]; } u1, u2; + u1.val = module_inst; + u2.val = native_ptr; + return wasm_runtime_validate_native_addr1(u1.parts[0], u1.parts[1], + u2.parts[0], u2.parts[1], + size); +} /** * Convert app address(relative address) to native address(absolute address) @@ -79,9 +123,18 @@ wasm_runtime_validate_native_addr(uint64_t module_inst, * * @return the native address converted */ -uint64_t +static inline uint64_t wasm_runtime_addr_app_to_native(uint64_t module_inst, - int32_t app_offset); + int32_t app_offset) +{ + union { uint64_t val; uint32_t parts[2]; } u; + uint64_t native_ptr; + u.val = module_inst; + if (!wasm_runtime_addr_app_to_native1(u.parts[0], u.parts[1], + app_offset, &native_ptr)) + return 0; + return native_ptr; +} /** * Convert native address(absolute address) to app address(relative address) @@ -91,12 +144,19 @@ wasm_runtime_addr_app_to_native(uint64_t module_inst, * * @return the app address converted */ -int32_t +static inline int32_t wasm_runtime_addr_native_to_app(uint64_t module_inst, - uint64_t native_ptr); + uint64_t native_ptr) +{ + union { uint64_t val; uint32_t parts[2]; } u1, u2; + u1.val = module_inst; + u2.val = native_ptr; + return wasm_runtime_addr_native_to_app1(u1.parts[0], u1.parts[1], + u2.parts[0], u2.parts[1]); +} #ifdef __cplusplus } #endif -#endif /* end of _WASM_EXPORT_H */ +#endif /* end of _WASM_EXPORT_API_H */ diff --git a/core/iwasm/lib/native/base/base_lib_export.c b/core/iwasm/lib/native/base/base_lib_export.c index fe891bae6e..eb90f94cfb 100644 --- a/core/iwasm/lib/native/base/base_lib_export.c +++ b/core/iwasm/lib/native/base/base_lib_export.c @@ -25,16 +25,25 @@ #include "base_lib_export.h" #endif -static uint64 -wasm_runtime_get_current_module_inst_wrapper(wasm_module_inst_t module_inst) +static void +wasm_runtime_get_current_module_inst1(wasm_module_inst_t module_inst, + int32 inst_offset) { - return (uint64)(uintptr_t)module_inst; + uint64 *p_module_inst; + + if (!wasm_runtime_validate_app_addr(module_inst, inst_offset, 8)) + return; + + p_module_inst = + wasm_runtime_addr_app_to_native(module_inst, inst_offset); + *p_module_inst = (uint64)(uintptr_t)module_inst; } + static bool -wasm_runtime_validate_app_addr_wrapper(wasm_module_inst_t module_inst, - uint32 inst_part0, uint32 inst_part1, - int32 app_offset, uint32 size) +wasm_runtime_validate_app_addr1(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, + int32 app_offset, uint32 size) { bool ret; union { uint64 u64; uint32 parts[2]; } inst; @@ -43,7 +52,7 @@ wasm_runtime_validate_app_addr_wrapper(wasm_module_inst_t module_inst, inst.parts[1] = inst_part1; if (inst.u64 != (uint64)(uintptr_t)module_inst) { - printf("Invalid module instance\n"); + bh_printf("Invalid module instance\n"); return false; } @@ -54,11 +63,11 @@ wasm_runtime_validate_app_addr_wrapper(wasm_module_inst_t module_inst, } static bool -wasm_runtime_validate_native_addr_wrapper(wasm_module_inst_t module_inst, - uint32 inst_part0, uint32 inst_part1, - uint32 native_ptr_part0, - uint32 native_ptr_part1, - uint32 size) +wasm_runtime_validate_native_addr1(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, + uint32 native_ptr_part0, + uint32 native_ptr_part1, + uint32 size) { bool ret; union { uint64 u64; uint32 parts[2]; } inst; @@ -74,37 +83,49 @@ wasm_runtime_validate_native_addr_wrapper(wasm_module_inst_t module_inst, native_ptr.parts[0] = native_ptr_part0; native_ptr.parts[1] = native_ptr_part1; - ret = wasm_runtime_validate_native_addr(module_inst, - (void*)(uintptr_t)native_ptr.u64, - size); + ret = wasm_runtime_validate_native_addr(module_inst, + (void*)(uintptr_t)native_ptr.u64, + size); if (!ret) wasm_runtime_clear_exception(module_inst); return ret; } -static uint64 -wasm_runtime_addr_app_to_native_wrapper(wasm_module_inst_t module_inst, - uint32 inst_part0, uint32 inst_part1, - int32 app_offset) +static bool +wasm_runtime_addr_app_to_native1(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, + int32 app_offset, + int32 native_ptr_offset) + { union { uint64 u64; uint32 parts[2]; } inst; + uint64 *p_native_ptr; inst.parts[0] = inst_part0; inst.parts[1] = inst_part1; if (inst.u64 != (uint64)(uintptr_t)module_inst) { printf("Invalid module instance\n"); - return 0; + return false; + } + + if (!wasm_runtime_validate_app_addr(module_inst, native_ptr_offset, 8)) { + wasm_runtime_clear_exception(module_inst); + return false; } - return (uint64)(uintptr_t) - wasm_runtime_addr_app_to_native(module_inst, app_offset); + + p_native_ptr = + wasm_runtime_addr_app_to_native(module_inst, native_ptr_offset); + *p_native_ptr = (uint64)(uintptr_t) + wasm_runtime_addr_app_to_native(module_inst, app_offset); + return true; } static int32 -wasm_runtime_addr_native_to_app_wrapper(wasm_module_inst_t module_inst, - uint32 inst_part0, uint32 inst_part1, - uint32 native_ptr_part0, - uint32 native_ptr_part1) +wasm_runtime_addr_native_to_app1(wasm_module_inst_t module_inst, + uint32 inst_part0, uint32 inst_part1, + uint32 native_ptr_part0, + uint32 native_ptr_part1) { union { uint64 u64; uint32 parts[2]; } inst; union { uint64 u64; uint32 parts[2]; } native_ptr; @@ -124,26 +145,26 @@ wasm_runtime_addr_native_to_app_wrapper(wasm_module_inst_t module_inst, } static NativeSymbol extended_native_symbol_defs[] = { -/* TODO: use macro EXPORT_WASM_API() or EXPORT_WASM_API2() to - add functions to register. */ + /* TODO: use macro EXPORT_WASM_API() or EXPORT_WASM_API2() to + add functions to register. */ #ifdef WASM_ENABLE_BASE_LIB - EXPORT_WASM_API(wasm_register_resource), - EXPORT_WASM_API(wasm_response_send), - EXPORT_WASM_API(wasm_post_request), - EXPORT_WASM_API(wasm_sub_event), - EXPORT_WASM_API(wasm_create_timer), - EXPORT_WASM_API(wasm_timer_destroy), - EXPORT_WASM_API(wasm_timer_cancel), - EXPORT_WASM_API(wasm_timer_restart), - EXPORT_WASM_API(wasm_get_sys_tick_ms), + EXPORT_WASM_API(wasm_register_resource), + EXPORT_WASM_API(wasm_response_send), + EXPORT_WASM_API(wasm_post_request), + EXPORT_WASM_API(wasm_sub_event), + EXPORT_WASM_API(wasm_create_timer), + EXPORT_WASM_API(wasm_timer_destroy), + EXPORT_WASM_API(wasm_timer_cancel), + EXPORT_WASM_API(wasm_timer_restart), + EXPORT_WASM_API(wasm_get_sys_tick_ms), #endif - EXPORT_WASM_API2(wasm_runtime_get_current_module_inst), - EXPORT_WASM_API2(wasm_runtime_validate_app_addr), - EXPORT_WASM_API2(wasm_runtime_validate_native_addr), - EXPORT_WASM_API2(wasm_runtime_addr_app_to_native), - EXPORT_WASM_API2(wasm_runtime_addr_native_to_app), - }; + EXPORT_WASM_API(wasm_runtime_get_current_module_inst1), + EXPORT_WASM_API(wasm_runtime_validate_app_addr1), + EXPORT_WASM_API(wasm_runtime_validate_native_addr1), + EXPORT_WASM_API(wasm_runtime_addr_app_to_native1), + EXPORT_WASM_API(wasm_runtime_addr_native_to_app1), +}; int get_base_lib_export_apis(NativeSymbol **p_base_lib_apis) { diff --git a/core/iwasm/lib/native/extension/gui/wgl_native_utils.h b/core/iwasm/lib/native/extension/gui/wgl_native_utils.h index e3d73b5229..201548c523 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_native_utils.h +++ b/core/iwasm/lib/native/extension/gui/wgl_native_utils.h @@ -9,6 +9,7 @@ extern "C" { #include "bh_platform.h" #include "lvgl.h" +#include "wasm_export.h" #define OBJ_ARG_NUM_MAX 4 #define PTR_ARG_NUM_MAX 4 @@ -66,6 +67,9 @@ void wgl_native_func_call(WGLNativeFuncDef *funcs, uint32 argv_offset, uint32 argc); +wasm_module_inst_t wasm_runtime_get_current_module_inst(); +#define get_module_inst() wasm_runtime_get_current_module_inst() + #ifdef __cplusplus } #endif diff --git a/core/iwasm/runtime/include/wasm_export.h b/core/iwasm/runtime/include/wasm_export.h index 955d6a28c9..11b9975334 100644 --- a/core/iwasm/runtime/include/wasm_export.h +++ b/core/iwasm/runtime/include/wasm_export.h @@ -287,15 +287,6 @@ wasm_runtime_detach_current_thread(wasm_module_inst_t module_inst); void* wasm_runtime_get_current_thread_data(); -/** - * Get current WASM module instance of the current native thread - * - * @return current WASM module instance of the current native thread, NULL - * if not found - */ -wasm_module_inst_t -wasm_runtime_get_current_module_inst(); - /** * Allocate memory from the heap of WASM module instance * diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index ca951c78ba..39fa66c9ca 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -1387,7 +1387,6 @@ wasm_runtime_get_native_addr_range(WASMModuleInstance *module_inst, return true; } - uint32 wasm_runtime_get_temp_ret(WASMModuleInstance *module_inst) { @@ -1465,28 +1464,19 @@ static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative; static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative; static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative; -/* As JavaScript can't represent int64s, emcc compiles C int64 argument - into two WASM i32 arguments, see: - https://github.com/emscripten-core/emscripten/issues/7199 - And also JavaScript float point is always 64-bit, emcc compiles - float32 argument into WASM f64 argument. - But clang compiles C int64 argument into WASM i64 argument, and - compiles C float32 argument into WASM f32 argument. - So for the compatability of emcc and clang, we treat i64 as two i32s, - treat f32 as f64 while passing arguments to the native function, and - require the native function uses two i32 arguments instead one i64 - argument, and uses double argument instead of float argment. */ - bool wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, WASMModuleInstance *module_inst, uint32 *argv, uint32 argc, uint32 *ret) { - union { float64 val; int32 parts[2]; } u; uint32 argv_buf[32], *argv1 = argv_buf, argc1, i, j = 0; uint64 size; +#if !defined(__arm__) && !defined(__mips__) + argc1 = argc + 2; +#else argc1 = func_type->param_count * 2 + 2; +#endif if (argc1 > sizeof(argv_buf) / sizeof(uint32)) { size = ((uint64)sizeof(uint32)) * argc1; @@ -1500,6 +1490,10 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, for (i = 0; i < sizeof(WASMModuleInstance*) / sizeof(uint32); i++) argv1[j++] = ((uint32*)&module_inst)[i]; +#if !defined(__arm__) && !defined(__mips__) + word_copy(argv1 + j, argv, argc); + j += argc; +#else for (i = 0; i < func_type->param_count; i++) { switch (func_type->types[i]) { case VALUE_TYPE_I32: @@ -1507,25 +1501,23 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, break; case VALUE_TYPE_I64: case VALUE_TYPE_F64: + /* 64-bit data must be 8 bytes alined in arm and mips */ + if (j & 1) + j++; argv1[j++] = *argv++; argv1[j++] = *argv++; break; case VALUE_TYPE_F32: - u.val = *(float32*)argv++; -#if defined(__arm__) || defined(__mips__) - /* 64-bit data must be 8 bytes alined in arm and mips */ - if (j & 1) - j++; -#endif - argv1[j++] = u.parts[0]; - argv1[j++] = u.parts[1]; + argv1[j++] = *argv++; break; default: wasm_assert(0); break; } } +#endif + argc1 = j; if (func_type->result_count == 0) { invokeNative_Void(argv1, argc1, func_ptr); } @@ -1543,6 +1535,9 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, case VALUE_TYPE_F64: PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, argc1, func_ptr)); break; + default: + wasm_assert(0); + break; } } @@ -1582,7 +1577,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, uint32 *argv, uint32 argc, uint32 *ret) { uint64 argv_buf[32], *argv1 = argv_buf, *fps, *ints, *stacks, size; - uint32 *argv_src = argv, i, j, argc1, n_ints = 0, n_stacks = 0; + uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0; #if defined(_WIN32) || defined(_WIN32_) /* important difference in calling conventions */ #define n_fps n_ints @@ -1615,12 +1610,11 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, stacks[n_stacks++] = *argv_src++; break; case VALUE_TYPE_I64: - for (j = 0; j < 2; j++) { - if (n_ints < MAX_REG_INTS) - ints[n_ints++] = *argv_src++; - else - stacks[n_stacks++] = *argv_src++; - } + if (n_ints < MAX_REG_INTS) + ints[n_ints++] = *(uint64*)argv_src; + else + stacks[n_stacks++] = *(uint64*)argv_src; + argv_src += 2; break; case VALUE_TYPE_F32: if (n_fps < MAX_REG_FLOATS) From 3a696f60cde27a75a93163d5c0706982b2ef578e Mon Sep 17 00:00:00 2001 From: wenyongh Date: Mon, 16 Sep 2019 14:41:15 +0800 Subject: [PATCH 17/18] Refine wgl lib: remove module_inst parameter from widget functions; move function index check to runtime instantiate --- .../native/extension/gui/wgl_btn_wrapper.c | 3 +- .../lib/native/extension/gui/wgl_cb_wrapper.c | 17 ++++++----- .../native/extension/gui/wgl_label_wrapper.c | 17 ++++++----- .../native/extension/gui/wgl_list_wrapper.c | 3 +- .../native/extension/gui/wgl_native_utils.c | 29 ++++++++++++------- .../native/extension/gui/wgl_native_utils.h | 12 ++++---- .../native/extension/gui/wgl_obj_wrapper.c | 3 +- core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 7 ++--- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 15 ++++++++-- 9 files changed, 65 insertions(+), 41 deletions(-) diff --git a/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c index fa46cb66a2..04ed88a066 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c @@ -51,7 +51,8 @@ wasm_btn_native_call(wasm_module_inst_t module_inst, { uint32 size = sizeof(btn_native_func_defs) / sizeof(WGLNativeFuncDef); - wgl_native_func_call(btn_native_func_defs, + wgl_native_func_call(module_inst, + btn_native_func_defs, size, func_id, argv_offset, diff --git a/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c index d0ed63e075..b999ffa343 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c @@ -23,12 +23,14 @@ /* ------------------------------------------------------------------------- * Label widget native function wrappers * -------------------------------------------------------------------------*/ -static int32 _cb_create(lv_obj_t *par, lv_obj_t *copy) +static int32 +_cb_create(lv_obj_t *par, lv_obj_t *copy) { return wgl_native_wigdet_create(WIDGET_TYPE_CB, par, copy); } -static int32 _cb_get_text_length(lv_obj_t *cb) +static int32 +_cb_get_text_length(lv_obj_t *cb) { const char *text = lv_cb_get_text(cb); @@ -38,9 +40,9 @@ static int32 _cb_get_text_length(lv_obj_t *cb) return strlen(text); } -static int32 _cb_get_text(lv_obj_t *cb, char *buffer, int buffer_len) +static char * +_cb_get_text(lv_obj_t *cb, char *buffer, int buffer_len) { - wasm_module_inst_t module_inst = get_module_inst(); const char *text = lv_cb_get_text(cb); if (text == NULL) @@ -49,7 +51,7 @@ static int32 _cb_get_text(lv_obj_t *cb, char *buffer, int buffer_len) strncpy(buffer, text, buffer_len - 1); buffer[buffer_len - 1] = '\0'; - return addr_native_to_app(buffer); + return buffer; } static WGLNativeFuncDef cb_native_func_defs[] = { @@ -57,7 +59,7 @@ static WGLNativeFuncDef cb_native_func_defs[] = { { CB_FUNC_ID_SET_TEXT, lv_cb_set_text, NO_RET, 2, {0, -1}, {1, -1} }, { CB_FUNC_ID_SET_STATIC_TEXT, lv_cb_set_static_text, NO_RET, 2, {0, -1}, {1, -1} }, { CB_FUNC_ID_GET_TEXT_LENGTH, _cb_get_text_length, HAS_RET, 1, {0, -1}, {-1} }, - { CB_FUNC_ID_GET_TEXT, _cb_get_text, HAS_RET, 3, {0, -1}, {1, -1} }, + { CB_FUNC_ID_GET_TEXT, _cb_get_text, RET_PTR, 3, {0, -1}, {1, -1} }, }; /*************** Native Interface to Wasm App ***********/ @@ -67,7 +69,8 @@ wasm_cb_native_call(wasm_module_inst_t module_inst, { uint32 size = sizeof(cb_native_func_defs) / sizeof(WGLNativeFuncDef); - wgl_native_func_call(cb_native_func_defs, + wgl_native_func_call(module_inst, + cb_native_func_defs, size, func_id, argv_offset, diff --git a/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c index a99b591b3b..3c39382d82 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c @@ -23,12 +23,14 @@ /* ------------------------------------------------------------------------- * Label widget native function wrappers * -------------------------------------------------------------------------*/ -static int32 _label_create(lv_obj_t *par, lv_obj_t *copy) +static int32 +_label_create(lv_obj_t *par, lv_obj_t *copy) { return wgl_native_wigdet_create(WIDGET_TYPE_LABEL, par, copy); } -static int32 _label_get_text_length(lv_obj_t *label) +static int32 +_label_get_text_length(lv_obj_t *label) { char *text = lv_label_get_text(label); @@ -38,9 +40,9 @@ static int32 _label_get_text_length(lv_obj_t *label) return strlen(text); } -static int32 _label_get_text(lv_obj_t *label, char *buffer, int buffer_len) +static char * +_label_get_text(lv_obj_t *label, char *buffer, int buffer_len) { - wasm_module_inst_t module_inst = get_module_inst(); char *text = lv_label_get_text(label); if (text == NULL) @@ -49,14 +51,14 @@ static int32 _label_get_text(lv_obj_t *label, char *buffer, int buffer_len) strncpy(buffer, text, buffer_len - 1); buffer[buffer_len - 1] = '\0'; - return addr_native_to_app(buffer); + return buffer; } static WGLNativeFuncDef label_native_func_defs[] = { { LABEL_FUNC_ID_CREATE, _label_create, HAS_RET, 2, {0 | NULL_OK, 1 | NULL_OK, -1}, {-1} }, { LABEL_FUNC_ID_SET_TEXT, lv_label_set_text, NO_RET, 2, {0, -1}, {1, -1} }, { LABEL_FUNC_ID_GET_TEXT_LENGTH, _label_get_text_length, HAS_RET, 1, {0, -1}, {-1} }, - { LABEL_FUNC_ID_GET_TEXT, _label_get_text, HAS_RET, 3, {0, -1}, {1, -1} }, + { LABEL_FUNC_ID_GET_TEXT, _label_get_text, RET_PTR, 3, {0, -1}, {1, -1} }, }; /*************** Native Interface to Wasm App ***********/ @@ -66,7 +68,8 @@ wasm_label_native_call(wasm_module_inst_t module_inst, { uint32 size = sizeof(label_native_func_defs) / sizeof(WGLNativeFuncDef); - wgl_native_func_call(label_native_func_defs, + wgl_native_func_call(module_inst, + label_native_func_defs, size, func_id, argv_offset, diff --git a/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c index 59040fc050..2d633ac62e 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c @@ -57,7 +57,8 @@ wasm_list_native_call(wasm_module_inst_t module_inst, { uint32 size = sizeof(list_native_func_defs) / sizeof(WGLNativeFuncDef); - wgl_native_func_call(list_native_func_defs, + wgl_native_func_call(module_inst, + list_native_func_defs, size, func_id, argv_offset, diff --git a/core/iwasm/lib/native/extension/gui/wgl_native_utils.c b/core/iwasm/lib/native/extension/gui/wgl_native_utils.c index 98bd85c65f..1d51a7ae15 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_native_utils.c +++ b/core/iwasm/lib/native/extension/gui/wgl_native_utils.c @@ -7,7 +7,7 @@ #include -#define THROW_EXC(msg) wasm_runtime_set_exception(get_module_inst(), msg); +#define THROW_EXC(msg) wasm_runtime_set_exception(module_inst, msg); void wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception); @@ -44,7 +44,8 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy) return 0; } -static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)()) +static void invokeNative(wasm_module_inst_t module_inst, + intptr_t argv[], uint32 argc, void (*native_code)()) { switch(argc) { case 0: @@ -87,20 +88,20 @@ static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)()) default: /* FIXME: If this happen, add more cases. */ - wasm_runtime_set_exception(get_module_inst(), - "the argument number of native function exceeds maximum"); + THROW_EXC("the argument number of native function exceeds maximum"); return; } } typedef void (*GenericFunctionPointer)(); -typedef int32 (*Int32FuncPtr)(intptr_t *, uint32, GenericFunctionPointer); -typedef void (*VoidFuncPtr)(intptr_t *, uint32, GenericFunctionPointer); +typedef int32 (*Int32FuncPtr)(wasm_module_inst_t, intptr_t *, uint32, GenericFunctionPointer); +typedef void (*VoidFuncPtr)(wasm_module_inst_t, intptr_t *, uint32, GenericFunctionPointer); static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative; static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative; -void wgl_native_func_call(WGLNativeFuncDef *funcs, +void wgl_native_func_call(wasm_module_inst_t module_inst, + WGLNativeFuncDef *funcs, uint32 size, int32 func_id, uint32 argv_offset, @@ -109,7 +110,6 @@ void wgl_native_func_call(WGLNativeFuncDef *funcs, WGLNativeFuncDef *func_def = funcs; WGLNativeFuncDef *func_def_end = func_def + size; uint32 *argv; - wasm_module_inst_t module_inst = get_module_inst(); if (!validate_app_addr(argv_offset, argc * sizeof(uint32))) return; @@ -173,13 +173,20 @@ void wgl_native_func_call(WGLNativeFuncDef *funcs, } if (func_def->has_ret == NO_RET) - invokeNative_Void(argv_copy, + invokeNative_Void(module_inst, + argv_copy, func_def->arg_num, func_def->func_ptr); - else - argv[0] = invokeNative_Int32(argv_copy, + else { + argv[0] = invokeNative_Int32(module_inst, + argv_copy, func_def->arg_num, func_def->func_ptr); + /* Convert to app memory offset if return value is a + * native address pointer */ + if (func_def->has_ret == RET_PTR) + argv[0] = addr_native_to_app((char *)(intptr_t)argv[0]); + } if (argv_copy != argv_copy_buf) bh_free(argv_copy); diff --git a/core/iwasm/lib/native/extension/gui/wgl_native_utils.h b/core/iwasm/lib/native/extension/gui/wgl_native_utils.h index 201548c523..1761e28f71 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_native_utils.h +++ b/core/iwasm/lib/native/extension/gui/wgl_native_utils.h @@ -17,8 +17,12 @@ extern "C" { #define NULL_OK 0x80 enum { + /* The function has a normal return value (not a pointer) */ HAS_RET, - NO_RET + /* The function doesn't have return value */ + NO_RET, + /* The function's return value is a native address pointer */ + RET_PTR }; enum { @@ -61,15 +65,13 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy); -void wgl_native_func_call(WGLNativeFuncDef *funcs, +void wgl_native_func_call(wasm_module_inst_t module_inst, + WGLNativeFuncDef *funcs, uint32 size, int32 func_id, uint32 argv_offset, uint32 argc); -wasm_module_inst_t wasm_runtime_get_current_module_inst(); -#define get_module_inst() wasm_runtime_get_current_module_inst() - #ifdef __cplusplus } #endif diff --git a/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c index 625077626d..158b413163 100644 --- a/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c +++ b/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c @@ -347,7 +347,8 @@ wasm_obj_native_call(wasm_module_inst_t module_inst, { uint32 size = sizeof(obj_native_func_defs) / sizeof(WGLNativeFuncDef); - wgl_native_func_call(obj_native_func_defs, + wgl_native_func_call(module_inst, + obj_native_func_defs, size, func_id, argv_offset, diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index d4afabe5e1..73e9f9035a 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -880,11 +880,8 @@ wasm_interp_call_func_bytecode(WASMThread *self, } fidx = ((uint32*)table->base_addr)[val]; - if (fidx >= module->function_count) { - wasm_runtime_set_exception(module, "function index is overflow"); - goto got_exception; - } - + /* Skip function index check, it has been checked + in wasm module instantiate */ cur_func = module->functions + fidx; if (cur_func->is_import_func) diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index 39fa66c9ca..0e992bb4f8 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -741,7 +741,7 @@ wasm_runtime_instantiate(WASMModule *module, WASMTableSeg *table_seg; WASMDataSeg *data_seg; WASMGlobalInstance *globals = NULL, *global; - uint32 global_count, addr_data_size = 0, global_data_size = 0, i; + uint32 global_count, addr_data_size = 0, global_data_size = 0, i, j; uint32 base_offset, length, memory_size; uint8 *global_data, *global_data_end, *addr_data, *addr_data_end; uint8 *memory_data; @@ -927,6 +927,15 @@ wasm_runtime_instantiate(WASMModule *module, module_inst->default_table->cur_size) length = module_inst->default_table->cur_size - table_seg->base_offset.u.i32; + /* Check function index */ + for (j = 0; j < length; j++) { + if (table_seg->func_indexes[j] >= module_inst->function_count) { + set_error_buf(error_buf, error_buf_size, + "function index is overflow"); + wasm_runtime_deinstantiate(module_inst); + return NULL; + } + } memcpy(table_data + table_seg->base_offset.u.i32, table_seg->func_indexes, length * sizeof(uint32)); } @@ -1618,9 +1627,9 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, break; case VALUE_TYPE_F32: if (n_fps < MAX_REG_FLOATS) - *(float64*)&fps[n_fps++] = *(float32*)argv_src++; + *(float32*)&fps[n_fps++] = *(float32*)argv_src++; else - *(float64*)&stacks[n_stacks++] = *(float32*)argv_src++; + *(float32*)&stacks[n_stacks++] = *(float32*)argv_src++; break; case VALUE_TYPE_F64: if (n_fps < MAX_REG_FLOATS) From cd896e161a4a78dda67fd01ffafe6451c002b9be Mon Sep 17 00:00:00 2001 From: wenyongh Date: Thu, 19 Sep 2019 17:02:31 +0800 Subject: [PATCH 18/18] Refine interpreter call native process, refine memory boudary check --- .../runtime/vmcore-wasm/invokeNative_em64.s | 110 +++++++++--------- .../runtime/vmcore-wasm/invokeNative_ia32.s | 66 ++++------- core/iwasm/runtime/vmcore-wasm/wasm_interp.c | 48 ++++---- core/iwasm/runtime/vmcore-wasm/wasm_runtime.c | 46 ++++---- 4 files changed, 127 insertions(+), 143 deletions(-) diff --git a/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s b/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s index d4c922f650..c031f82628 100644 --- a/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s +++ b/core/iwasm/runtime/vmcore-wasm/invokeNative_em64.s @@ -1,72 +1,70 @@ -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You 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. -// -// Author: Ivan Volosyuk -// +/* + * 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. + */ .text .align 2 .globl invokeNative .type invokeNative, @function invokeNative: - /* rdi - memory */ - /* rsi - n fp args */ - /* rdx - n mem args */ - /* rcx - function ptr */ + /* rdi - function ptr */ + /* rsi - argv */ + /* rdx - n_stacks */ push %rbp mov %rsp, %rbp - /* cycle to fill all fp args */ - movq 8(%rdi), %xmm0 - movq 16(%rdi), %xmm1 - movq 24(%rdi), %xmm2 - movq 32(%rdi), %xmm3 - movq 40(%rdi), %xmm4 - movq 48(%rdi), %xmm5 - movq 56(%rdi), %xmm6 - movq 64(%rdi), %xmm7 - - mov %rsp, %r10 /* Check that stack is aligned on */ - and $8, %r10 /* 16 bytes. This code may be removed */ - jz no_abort /* when we are sure that compiler always */ - int3 /* calls us with aligned stack */ -no_abort: - mov %rdx, %r10 /* Align stack on 16 bytes before pushing */ - and $1, %r10 /* stack arguments in case we have an odd */ - shl $3, %r10 /* number of stack arguments */ - sub %r10, %rsp + mov %rdx, %r10 + mov %rsp, %r11 /* Check that stack is aligned on */ + and $8, %r11 /* 16 bytes. This code may be removed */ + je check_stack_succ /* when we are sure that compiler always */ + int3 /* calls us with aligned stack */ +check_stack_succ: + mov %r10, %r11 /* Align stack on 16 bytes before pushing */ + and $1, %r11 /* stack arguments in case we have an odd */ + shl $3, %r11 /* number of stack arguments */ + sub %r11, %rsp /* store memory args */ - movq %rcx, %r10 /* func ptr */ - movq %rdx, %rcx /* counter */ - lea 8+64+48-8(%rdi,%rcx,8), %rdx - sub %rsp, %rdx + movq %rdi, %r11 /* func ptr */ + movq %r10, %rcx /* counter */ + lea 64+48-8(%rsi,%rcx,8), %r10 + sub %rsp, %r10 cmpq $0, %rcx - jz cycle_end -cycle: - push 0(%rsp,%rdx) - loop cycle -cycle_end: - movq 80(%rdi), %rsi - movq 88(%rdi), %rdx - movq 96(%rdi), %rcx - movq 104(%rdi), %r8 - movq 112(%rdi), %r9 + je push_args_end +push_args: + push 0(%rsp,%r10) + loop push_args +push_args_end: + /* fill all fp args */ + movq 0x00(%rsi), %xmm0 + movq 0x08(%rsi), %xmm1 + movq 0x10(%rsi), %xmm2 + movq 0x18(%rsi), %xmm3 + movq 0x20(%rsi), %xmm4 + movq 0x28(%rsi), %xmm5 + movq 0x30(%rsi), %xmm6 + movq 0x38(%rsi), %xmm7 - movq 72(%rdi), %rdi + /* fill all int args */ + movq 0x40(%rsi), %rdi + movq 0x50(%rsi), %rdx + movq 0x58(%rsi), %rcx + movq 0x60(%rsi), %r8 + movq 0x68(%rsi), %r9 + movq 0x48(%rsi), %rsi - call *%r10 + call *%r11 leave ret diff --git a/core/iwasm/runtime/vmcore-wasm/invokeNative_ia32.s b/core/iwasm/runtime/vmcore-wasm/invokeNative_ia32.s index 8c1d843e0b..6c41d211aa 100644 --- a/core/iwasm/runtime/vmcore-wasm/invokeNative_ia32.s +++ b/core/iwasm/runtime/vmcore-wasm/invokeNative_ia32.s @@ -1,56 +1,38 @@ -// 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. +/* + * 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. + */ -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You 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. -// -// Author: Ivan Volosyuk -// .text .align 2 .globl invokeNative .type invokeNative, @function invokeNative: - push %ebp movl %esp, %ebp - push %ecx - movl 8(%ebp), %eax /* eax = argv */ - movl 12(%ebp), %ecx /* ecx = argc */ + movl 16(%ebp), %ecx /* ecx = argc */ + movl 12(%ebp), %edx /* edx = argv */ test %ecx, %ecx - je restore_ecx /* if ecx == 0, skip pushing arguments */ - leal -4(%eax,%ecx,4), %eax /* eax = eax + ecx * 4 - 4 */ - subl %esp, %eax /* eax = eax - esp */ + jz skip_push_args /* if ecx == 0, skip pushing arguments */ + leal -4(%edx,%ecx,4), %edx /* edx = edx + ecx * 4 - 4 */ + subl %esp, %edx /* edx = edx - esp */ 1: - push 0(%esp,%eax) + push 0(%esp,%edx) loop 1b /* loop ecx counts */ -restore_ecx: - movl -4(%ebp), %ecx /* restore ecx */ - movl 16(%ebp), %eax /* eax = func_ptr */ - call *%eax +skip_push_args: + movl 8(%ebp), %edx /* edx = func_ptr */ + call *%edx leave ret diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index 73e9f9035a..a7d00e9b4e 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -75,17 +75,17 @@ GET_F64_FROM_ADDR (uint32 *addr) #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ #if WASM_ENABLE_EXT_MEMORY_SPACE != 0 -#define CHECK_EXT_MEMORY_SPACE() \ +#define CHECK_EXT_MEMORY_SPACE() \ else if (module->ext_mem_data \ && module->ext_mem_base_offset <= offset1 \ && offset1 < module->ext_mem_base_offset \ + module->ext_mem_size) { \ + /* If offset1 is in valid range, maddr must also be in valid range, \ + no need to check it again. */ \ maddr = module->ext_mem_data \ + (offset1 - module->ext_mem_base_offset); \ - if (maddr < module->ext_mem_data) \ - goto out_of_bounds; \ - maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ - if (maddr1 > module->ext_mem_data_end) \ + if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > \ + module->ext_mem_data_end) \ goto out_of_bounds; \ } #else @@ -94,26 +94,25 @@ GET_F64_FROM_ADDR (uint32 *addr) #define CHECK_MEMORY_OVERFLOW() do { \ uint32 offset1 = offset + addr; \ - uint8 *maddr1; \ - if (flags != 2) \ - LOG_VERBOSE("unaligned load/store in wasm interp, flag is: %d.\n", flags);\ - if (offset1 < offset) \ - goto out_of_bounds; \ - if (offset1 < heap_base_offset) { \ + /* if (flags != 2) \ + LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\ + /* The WASM spec doesn't require that the dynamic address operand must be \ + unsigned, so we don't check whether integer overflow or not here. */ \ + /* if (offset1 < offset) \ + goto out_of_bounds; */ \ + if (offset1 < memory_data_size) { \ + /* If offset1 is in valid range, maddr must also be in valid range, \ + no need to check it again. */ \ maddr = memory->memory_data + offset1; \ - if (maddr < memory->base_addr) \ - goto out_of_bounds; \ - maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ - if (maddr1 > memory->end_addr) \ + if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > memory->end_addr) \ goto out_of_bounds; \ } \ - else if (offset1 < memory->heap_base_offset \ - + (memory->heap_data_end - memory->heap_data)) { \ + else if (offset1 > heap_base_offset \ + && offset1 < heap_base_offset + heap_data_size) { \ + /* If offset1 is in valid range, maddr must also be in valid range, \ + no need to check it again. */ \ maddr = memory->heap_data + offset1 - memory->heap_base_offset; \ - if (maddr < memory->heap_data) \ - goto out_of_bounds; \ - maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ - if (maddr1 > memory->heap_data_end) \ + if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > memory->heap_data_end) \ goto out_of_bounds; \ } \ CHECK_EXT_MEMORY_SPACE() \ @@ -684,7 +683,11 @@ wasm_interp_call_func_bytecode(WASMThread *self, { WASMModuleInstance *module = self->module_inst; WASMMemoryInstance *memory = module->default_memory; - int32 heap_base_offset = memory ? memory->heap_base_offset : 0; + uint32 memory_data_size = memory + ? NumBytesPerPage * memory->cur_page_count : 0; + uint32 heap_base_offset = memory ? memory->heap_base_offset : 0; + uint32 heap_data_size = memory + ? memory->heap_data_end - memory->heap_data : 0; WASMTableInstance *table = module->default_table; uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2; WASMInterpFrame *frame = NULL; @@ -1302,6 +1305,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, PUSH_I32(prev_page_count); /* update the memory instance ptr */ memory = module->default_memory; + memory_data_size = NumBytesPerPage * memory->cur_page_count; } (void)reserved; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index 0e992bb4f8..2802499874 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -1459,13 +1459,13 @@ word_copy(uint32 *dest, uint32 *src, unsigned num) #if !defined(__x86_64__) && !defined(__amd_64__) typedef void (*GenericFunctionPointer)(); -int64 invokeNative(uint32 *args, uint32 sz, GenericFunctionPointer f); +int64 invokeNative(GenericFunctionPointer f, uint32 *args, uint32 sz); -typedef float64 (*Float64FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef float32 (*Float32FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef int64 (*Int64FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef int32 (*Int32FuncPtr)(uint32*, uint32, GenericFunctionPointer); -typedef void (*VoidFuncPtr)(uint32*, uint32, GenericFunctionPointer); +typedef float64 (*Float64FuncPtr)(GenericFunctionPointer f, uint32*, uint32); +typedef float32 (*Float32FuncPtr)(GenericFunctionPointer f, uint32*, uint32); +typedef int64 (*Int64FuncPtr)(GenericFunctionPointer f, uint32*, uint32); +typedef int32 (*Int32FuncPtr)(GenericFunctionPointer f, uint32*, uint32); +typedef void (*VoidFuncPtr)(GenericFunctionPointer f, uint32*, uint32); static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative; static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative; @@ -1528,21 +1528,21 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, argc1 = j; if (func_type->result_count == 0) { - invokeNative_Void(argv1, argc1, func_ptr); + invokeNative_Void(func_ptr, argv1, argc1); } else { switch (func_type->types[func_type->param_count]) { case VALUE_TYPE_I32: - ret[0] = invokeNative_Int32(argv1, argc1, func_ptr); + ret[0] = invokeNative_Int32(func_ptr, argv1, argc1); break; case VALUE_TYPE_I64: - PUT_I64_TO_ADDR(ret, invokeNative_Int64(argv1, argc1, func_ptr)); + PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, argc1)); break; case VALUE_TYPE_F32: - *(float32*)ret = invokeNative_Float32(argv1, argc1, func_ptr); + *(float32*)ret = invokeNative_Float32(func_ptr, argv1, argc1); break; case VALUE_TYPE_F64: - PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, argc1, func_ptr)); + PUT_F64_TO_ADDR(ret, invokeNative_Float64(func_ptr, argv1, argc1)); break; default: wasm_assert(0); @@ -1558,13 +1558,13 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, #else /* else of !defined(__x86_64__) && !defined(__amd_64__) */ typedef void (*GenericFunctionPointer)(); -int64 invokeNative(uint64 *args, uint64 n_fps, uint64 n_stacks, GenericFunctionPointer f); +int64 invokeNative(GenericFunctionPointer f, uint64 *args, uint64 n_stacks); -typedef float64 (*Float64FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); -typedef float32 (*Float32FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); -typedef int64 (*Int64FuncPtr)(uint64*,uint64, uint64, GenericFunctionPointer); -typedef int32 (*Int32FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); -typedef void (*VoidFuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer); +typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint64*, uint64); +typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint64*, uint64); +typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64*,uint64); +typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64*, uint64); +typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64*, uint64); static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative; static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative; @@ -1604,7 +1604,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, } } - fps = argv1 + 1; + fps = argv1; ints = fps + MAX_REG_FLOATS; stacks = ints + MAX_REG_INTS; @@ -1645,21 +1645,21 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type, } if (func_type->result_count == 0) { - invokeNative_Void(argv1, n_fps, n_stacks, func_ptr); + invokeNative_Void(func_ptr, argv1, n_stacks); } else { switch (func_type->types[func_type->param_count]) { case VALUE_TYPE_I32: - ret[0] = invokeNative_Int32(argv1, n_fps, n_stacks, func_ptr); + ret[0] = invokeNative_Int32(func_ptr, argv1, n_stacks); break; case VALUE_TYPE_I64: - PUT_I64_TO_ADDR(ret, invokeNative_Int64(argv1, n_fps, n_stacks, func_ptr)); + PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, n_stacks)); break; case VALUE_TYPE_F32: - *(float32*)ret = invokeNative_Float32(argv1, n_fps, n_stacks, func_ptr); + *(float32*)ret = invokeNative_Float32(func_ptr, argv1, n_stacks); break; case VALUE_TYPE_F64: - PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, n_fps, n_stacks, func_ptr)); + PUT_F64_TO_ADDR(ret, invokeNative_Float64(func_ptr, argv1, n_stacks)); break; default: wasm_assert(0);