diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 82f70ca3dc..e0aedc4c16 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -4195,13 +4195,13 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name) bh_print_time("Begin to emit object file"); if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) { - char cmd[1024]; int ret; if (comp_ctx->external_llc_compiler) { - const char *stack_usage_flag = ""; - char bc_file_name[64]; - char su_file_name[65]; /* See the comment below */ + char *stack_usage_flag = ""; + char bc_file_name[64] = { 0 }; + char su_file_name[65] = { 0 }; + char *argv[10] = { 0 }; if (comp_ctx->stack_usage_file != NULL) { /* @@ -4229,14 +4229,16 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name) return false; } - snprintf(cmd, sizeof(cmd), "%s%s %s -o %s %s", - comp_ctx->external_llc_compiler, stack_usage_flag, - comp_ctx->llc_compiler_flags ? comp_ctx->llc_compiler_flags - : "-O3 -c", - file_name, bc_file_name); - LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd); + argv[0] = stack_usage_flag; + argv[1] = comp_ctx->llc_compiler_flags + ? (char *)comp_ctx->llc_compiler_flags + : "-O3 -c"; + argv[2] = "-o"; + argv[3] = file_name; + argv[4] = bc_file_name; + argv[5] = NULL; - ret = bh_system(cmd); + ret = os_execve(comp_ctx->external_llc_compiler, argv, 6); /* remove temp bitcode file */ unlink(bc_file_name); @@ -4263,7 +4265,8 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name) } } else if (comp_ctx->external_asm_compiler) { - char asm_file_name[64]; + char asm_file_name[64] = { 0 }; + char *argv[10] = { 0 }; if (!aot_generate_tempfile_name("wamrc-asm", "s", asm_file_name, sizeof(asm_file_name))) { @@ -4282,14 +4285,15 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name) return false; } - snprintf(cmd, sizeof(cmd), "%s %s -o %s %s", - comp_ctx->external_asm_compiler, - comp_ctx->asm_compiler_flags ? comp_ctx->asm_compiler_flags - : "-O3 -c", - file_name, asm_file_name); - LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd); + argv[0] = comp_ctx->asm_compiler_flags + ? (char *)comp_ctx->asm_compiler_flags + : "-O3 -c"; + argv[1] = "-o"; + argv[2] = file_name; + argv[3] = asm_file_name; + argv[4] = NULL; - ret = bh_system(cmd); + ret = os_execve(comp_ctx->external_asm_compiler, argv, 5); /* remove temp assembly file */ unlink(asm_file_name); diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 097727d132..6d128950c5 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -4361,18 +4361,23 @@ aot_obj_data_create(AOTCompContext *comp_ctx) else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) { /* Emit to assembly file instead for arc target as it cannot emit to object file */ - char file_name[] = "wasm-XXXXXX", buf[128]; + char file_name[] = "wasm-XXXXXX"; + char assembly_file_name[64] = { 0 }; + char object_file_name[64] = { 0 }; int ret; + char *argv[] = { "-mcpu=arcem", "-o", object_file_name, "-c", + assembly_file_name, NULL }; if (!bh_mkstemp(file_name, sizeof(file_name))) { aot_set_last_error("make temp file failed."); goto fail; } - snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); + snprintf(assembly_file_name, sizeof(assembly_file_name) - 1, "%s.s", + file_name); if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine, - comp_ctx->module, buf, LLVMAssemblyFile, - &err) + comp_ctx->module, assembly_file_name, + LLVMAssemblyFile, &err) != 0) { if (err) { LLVMDisposeMessage(err); @@ -4385,14 +4390,14 @@ aot_obj_data_create(AOTCompContext *comp_ctx) /* call arc gcc to compile assembly file to object file */ /* TODO: get arc gcc from environment variable firstly and check whether the toolchain exists actually */ - snprintf(buf, sizeof(buf), "%s%s%s%s%s%s", - "/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc ", - "-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s"); + snprintf(object_file_name, sizeof(object_file_name) - 1, "%s.o", + file_name); /* TODO: use try..catch to handle possible exceptions */ - ret = bh_system(buf); + /* TODO: use ZEPHYR_SDK_INSTALL_DIR to construct the path */ + ret = os_execve("/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc", + argv, 6); /* remove temp assembly file */ - snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); - unlink(buf); + unlink(assembly_file_name); if (ret != 0) { aot_set_last_error("failed to compile asm file to obj file " @@ -4401,12 +4406,10 @@ aot_obj_data_create(AOTCompContext *comp_ctx) } /* create memory buffer from object file */ - snprintf(buf, sizeof(buf), "%s%s", file_name, ".o"); - ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, &obj_data->mem_buf, - &err); + ret = LLVMCreateMemoryBufferWithContentsOfFile( + object_file_name, &obj_data->mem_buf, &err); /* remove temp object file */ - snprintf(buf, sizeof(buf), "%s%s", file_name, ".o"); - unlink(buf); + unlink(object_file_name); if (ret != 0) { if (err) { diff --git a/core/shared/platform/alios/alios_platform.c b/core/shared/platform/alios/alios_platform.c index a3752b4395..8c9da895c9 100644 --- a/core/shared/platform/alios/alios_platform.c +++ b/core/shared/platform/alios/alios_platform.c @@ -85,3 +85,10 @@ os_invalid_raw_handle(void) { return -1; } + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + /* not implemented */ + return -1; +} diff --git a/core/shared/platform/android/platform_internal.h b/core/shared/platform/android/platform_internal.h index 7abf863f81..d5ec2ecc37 100644 --- a/core/shared/platform/android/platform_internal.h +++ b/core/shared/platform/android/platform_internal.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #ifdef __cplusplus diff --git a/core/shared/platform/common/posix/posix_exec.c b/core/shared/platform/common/posix/posix_exec.c new file mode 100644 index 0000000000..e3a77bcc5f --- /dev/null +++ b/core/shared/platform/common/posix/posix_exec.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_vmcore.h" + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + pid_t pid; + int ret; + /* no environment variables */ + char *const envp[] = { NULL }; + + if (pathname == NULL) { + goto fail; + } + + if (argc > 0) { + if (argv == NULL) { + goto fail; + } + + /* The `argv[]` must be terminated by a NULL pointer. */ + if (argv[argc - 1] != NULL) { + goto fail; + } + } + + pid = fork(); + if (pid < 0) { + perror("fork failed: "); + goto fail; + } + + if (pid == 0) { + /* child process */ + ret = execve(pathname, argv, envp); + if (ret == -1) { + perror("execve failed(from child): "); + } + /* _exit() for thread safe? */ + exit(ret); + } + else { + /* parent process */ + int status; + + ret = waitpid(pid, &status, 0); + if (ret == -1) { + perror("waitpid failed: "); + goto fail; + } + + if (WIFEXITED(status)) { + /* child terminated normally with exit code */ + ret = WEXITSTATUS(status); + if (ret != 0) { + printf("execute failed(from parent) with exit code: %d\n", ret); + } + } + else { + /* + * child terminated abnormally. + * include if killed or stopped by a signal + */ + goto fail; + } + } + + return ret; +fail: + return -1; +} \ No newline at end of file diff --git a/core/shared/platform/cosmopolitan/platform_internal.h b/core/shared/platform/cosmopolitan/platform_internal.h index 5c73ed5a65..8048d783a1 100644 --- a/core/shared/platform/cosmopolitan/platform_internal.h +++ b/core/shared/platform/cosmopolitan/platform_internal.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/core/shared/platform/darwin/platform_internal.h b/core/shared/platform/darwin/platform_internal.h index 928aad7246..5e059464db 100644 --- a/core/shared/platform/darwin/platform_internal.h +++ b/core/shared/platform/darwin/platform_internal.h @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/core/shared/platform/freebsd/platform_internal.h b/core/shared/platform/freebsd/platform_internal.h index 01a6e824fc..3f9ce4a1d8 100644 --- a/core/shared/platform/freebsd/platform_internal.h +++ b/core/shared/platform/freebsd/platform_internal.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/core/shared/platform/include/platform_api_vmcore.h b/core/shared/platform/include/platform_api_vmcore.h index 1fa524f9e8..21aa6f4579 100644 --- a/core/shared/platform/include/platform_api_vmcore.h +++ b/core/shared/platform/include/platform_api_vmcore.h @@ -185,6 +185,26 @@ os_dcache_flush(void); void os_icache_flush(void *start, size_t len); +/* + * Executes a program referred to by cmd in bash/cmd.exe + * Always be sure that argv[argc-1] == NULL + * + * @param pathname The program to execute. need to be absolute path. + * @param argv The command line arguments. + * @param argc The number of command line arguments. + * + * like to execute "ls -l /tmp": + * os_execve("/bin/ls", (char *const []){ "-l", "/tmp", NULL }, 3); + * + * @return 0 if success + * -1 if can't execute the program or can't get exit code. + * like fork() failed, execve() failed, waitpid() failed + * or the program is not terminated normally(via exit() or main()) + * other values indicate exit code. + */ +int +os_execve(const char *pathname, char *const argv[], int argc); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/linux-sgx/sgx_platform.c b/core/shared/platform/linux-sgx/sgx_platform.c index db350bc8f4..a701794dc2 100644 --- a/core/shared/platform/linux-sgx/sgx_platform.c +++ b/core/shared/platform/linux-sgx/sgx_platform.c @@ -221,3 +221,10 @@ os_dcache_flush(void) void os_icache_flush(void *start, size_t len) {} + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + /* not implemented */ + return -1; +} diff --git a/core/shared/platform/linux/platform_internal.h b/core/shared/platform/linux/platform_internal.h index 865180273e..ae20d62dbe 100644 --- a/core/shared/platform/linux/platform_internal.h +++ b/core/shared/platform/linux/platform_internal.h @@ -22,10 +22,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/core/shared/platform/nuttx/platform_internal.h b/core/shared/platform/nuttx/platform_internal.h index fef2122da8..1a7bd87ac0 100644 --- a/core/shared/platform/nuttx/platform_internal.h +++ b/core/shared/platform/nuttx/platform_internal.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #ifdef __cplusplus diff --git a/core/shared/platform/riot/riot_platform.c b/core/shared/platform/riot/riot_platform.c index b48033247a..5285e18edf 100644 --- a/core/shared/platform/riot/riot_platform.c +++ b/core/shared/platform/riot/riot_platform.c @@ -101,3 +101,10 @@ os_invalid_raw_handle(void) { return -1; } + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + /* not implemented */ + return -1; +} diff --git a/core/shared/platform/rt-thread/rtt_platform.c b/core/shared/platform/rt-thread/rtt_platform.c index 904bb52ed1..d97cb0860a 100644 --- a/core/shared/platform/rt-thread/rtt_platform.c +++ b/core/shared/platform/rt-thread/rtt_platform.c @@ -210,3 +210,10 @@ os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution) { return 0; } + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + /* not implemented */ + return -1; +} diff --git a/core/shared/platform/vxworks/platform_internal.h b/core/shared/platform/vxworks/platform_internal.h index 6a6b00f4be..dc98c06222 100644 --- a/core/shared/platform/vxworks/platform_internal.h +++ b/core/shared/platform/vxworks/platform_internal.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/core/shared/platform/windows/platform_init.c b/core/shared/platform/windows/platform_init.c index 96bcf9ab1a..1f84dcd1e7 100644 --- a/core/shared/platform/windows/platform_init.c +++ b/core/shared/platform/windows/platform_init.c @@ -72,8 +72,66 @@ os_getpagesize() void os_dcache_flush(void) -{} +{ +} void os_icache_flush(void *start, size_t len) -{} \ No newline at end of file +{ +} + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + DWORD exit_code; + int ret; + + if (pathname == NULL) { + goto fail; + } + + if (argc > 0) { + if (argv == NULL) { + goto fail; + } + + /* The `argv[]` must be terminated by a NULL pointer. */ + if (argv[argc - 1] != NULL) { + goto fail; + } + } + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + + if (!CreateProcess(pathname, (LPSTR)argv[0], + /* security attributes */ + NULL, NULL, + /* not inherited handlers */ + FALSE, + /* creation flags */ + 0, + /* not use parent's environment */ + NULL, + /* not use parent's directory */ + NULL, &si, &pi)) { + printf("CreateProcess failed: %d\n", GetLastError()); + goto fail; + } + + WaitForSingleObject(pi.hProcess, INFINITE); + + if (!GetExitCodeProcess(pi.hProcess, &exit_code)) { + printf("GetExitCodeProcess failed: %d\n", GetLastError()); + goto fail; + } + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return exit_code; + +fail: + return -1; +} diff --git a/core/shared/platform/zephyr/zephyr_platform.c b/core/shared/platform/zephyr/zephyr_platform.c index 3280e542f6..cd86599170 100644 --- a/core/shared/platform/zephyr/zephyr_platform.c +++ b/core/shared/platform/zephyr/zephyr_platform.c @@ -261,3 +261,10 @@ os_invalid_raw_handle(void) { return -1; } + +int +os_execve(const char *pathname, char *const argv[], int argc) +{ + /* not implemented */ + return -1; +} diff --git a/core/shared/utils/bh_common.c b/core/shared/utils/bh_common.c index 62f36caf1a..6ed4ad5123 100644 --- a/core/shared/utils/bh_common.c +++ b/core/shared/utils/bh_common.c @@ -167,20 +167,6 @@ wa_strdup(const char *s) } #if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0 -int -bh_system(const char *cmd) -{ - int ret; - -#if !(defined(_WIN32) || defined(_WIN32_)) - ret = system(cmd); -#else - ret = _spawnlp(_P_WAIT, "cmd.exe", "/c", cmd, NULL); -#endif - - return ret; -} - #if defined(_WIN32) || defined(_WIN32_) errno_t _mktemp_s(char *nameTemplate, size_t sizeInChars); diff --git a/core/shared/utils/bh_common.h b/core/shared/utils/bh_common.h index 093e622081..4455001c42 100644 --- a/core/shared/utils/bh_common.h +++ b/core/shared/utils/bh_common.h @@ -67,10 +67,6 @@ char * wa_strdup(const char *s); #if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0 -/* Executes a system command in bash/cmd.exe */ -int -bh_system(const char *cmd); - /* Tests whether can create a temporary file with the given name */ bool bh_mkstemp(char *filename, size_t name_len);