| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef _GNU_SOURCE
- #define _GNU_SOURCE /* for O_DIRECT */
- #endif
- #include "wasm-native.h"
- #include "wasm-runtime.h"
- #include "wasm_log.h"
- #include "wasm_memory.h"
- #include "wasm_platform_log.h"
- #include <sys/ioctl.h>
- #include <sys/uio.h>
- #include <sys/syscall.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <pwd.h>
- #include <fcntl.h>
- #include <errno.h>
- #define get_module_inst() \
- wasm_runtime_get_current_module_inst()
- #define validate_app_addr(offset, size) \
- wasm_runtime_validate_app_addr(module_inst, offset, size)
- #define addr_app_to_native(offset) \
- wasm_runtime_addr_app_to_native(module_inst, offset)
- #define addr_native_to_app(ptr) \
- wasm_runtime_addr_native_to_app(module_inst, ptr)
- #define module_malloc(size) \
- wasm_runtime_module_malloc(module_inst, size)
- #define module_free(offset) \
- wasm_runtime_module_free(module_inst, offset)
- static int32
- __syscall0_wrapper(int32 arg0)
- {
- switch (arg0) {
- case 199: /* getuid */
- /* TODO */
- default:
- 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:
- 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:
- 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 54: /* ioctl */
- {
- /* Implement syscall 54 and syscall 146 to support printf()
- for non SIDE_MODULE=1 mode */
- struct winsize *wsz;
- if (!validate_app_addr(arg3, sizeof(struct winsize)))
- return 0;
- wsz = (struct winsize*)addr_app_to_native(arg3);
- return syscall(54, arg1, arg2, wsz);
- }
- case 145: /* readv */
- case 146: /* writev */
- {
- /* Implement syscall 54 and syscall 146 to support printf()
- for non SIDE_MODULE=1 mode */
- uint32 iovcnt = arg3, i;
- struct iovec *vec_begin, *vec;
- if (!validate_app_addr(arg2, sizeof(struct iovec)))
- return 0;
- vec_begin = vec = (struct iovec*)addr_app_to_native(arg2);
- for (i = 0; i < iovcnt; i++, vec++) {
- if (vec->iov_len > 0) {
- if (!validate_app_addr((int32)vec->iov_base, 1))
- return 0;
- vec->iov_base = addr_app_to_native((int32)vec->iov_base);
- }
- }
- if (arg0 == 145)
- return syscall(145, arg1, vec_begin, arg3);
- else
- return syscall(146, arg1, vec_begin, arg3);
- }
- case 3: /* read*/
- case 5: /* open */
- case 221: /* fcntl */
- /* TODO */
- default:
- printf("##_syscall3 called, syscall id: %d\n", arg0);
- }
- return 0;
- }
- static int32
- __syscall4_wrapper(int32 arg0, int32 arg1, int32 arg2,
- int32 arg3, int32 arg4)
- {
- 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:
- 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;
- }
|