From 071b8c25100aa7e9483e2cefcd491d28fb88468b Mon Sep 17 00:00:00 2001 From: dongheng <930490596@qq.com> Date: Mon, 15 Aug 2022 16:17:28 +0800 Subject: [PATCH] esp-idf: Make esp-idf support Libc WASI (#1356) esp-idf: Make esp-idf support Libc WASI 1. Support to get WASM APP libs' DIR from upper layer 2. Add SSP support for esp-idf platform 3. Change the errno of readlinkat --- core/app-framework/app_framework.cmake | 4 + .../src/ssp_config.h | 15 +- .../shared/platform/esp-idf/espidf_platform.c | 190 ++++++++++++++++++ .../platform/esp-idf/platform_internal.h | 63 ++++++ 4 files changed, 265 insertions(+), 7 deletions(-) diff --git a/core/app-framework/app_framework.cmake b/core/app-framework/app_framework.cmake index 8ad43dec1..b8a63d856 100644 --- a/core/app-framework/app_framework.cmake +++ b/core/app-framework/app_framework.cmake @@ -33,6 +33,10 @@ function (add_module_native arg) ${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native/*.h ${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native/*.inl ) + + LIST (APPEND WASM_APP_LIBS_DIR ${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native) + set (WASM_APP_LIBS_DIR ${WASM_APP_LIBS_DIR} PARENT_SCOPE) + LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header}) set (RUNTIME_LIB_HEADER_LIST ${RUNTIME_LIB_HEADER_LIST} PARENT_SCOPE) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index 47b65ca82..68b0faf34 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -25,8 +25,8 @@ // On Linux, prefer to use getrandom, though it isn't available in // GLIBC before 2.25. -#if defined(__linux__) \ - && (!defined(__GLIBC__) || __GLIBC__ > 2 \ +#if (defined(__linux__) || defined(ESP_PLATFORM)) \ + && (!defined(__GLIBC__) || __GLIBC__ > 2 \ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) #define CONFIG_HAS_GETRANDOM 1 #else @@ -39,13 +39,14 @@ #define CONFIG_HAS_CAP_ENTER 0 #endif -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__) +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__) \ + && !defined(ESP_PLATFORM) #define CONFIG_HAS_CLOCK_NANOSLEEP 1 #else #define CONFIG_HAS_CLOCK_NANOSLEEP 0 #endif -#if !defined(__APPLE__) && !defined(__FreeBSD__) +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(ESP_PLATFORM) #define CONFIG_HAS_FDATASYNC 1 #else #define CONFIG_HAS_FDATASYNC 0 @@ -63,13 +64,13 @@ #endif #endif -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(ESP_PLATFORM) #define CONFIG_HAS_POSIX_FALLOCATE 1 #else #define CONFIG_HAS_POSIX_FALLOCATE 0 #endif -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(ESP_PLATFORM) #define CONFIG_HAS_PREADV 1 #else #define CONFIG_HAS_PREADV 0 @@ -87,7 +88,7 @@ #define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0 #endif -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(ESP_PLATFORM) #define CONFIG_HAS_PWRITEV 1 #else #define CONFIG_HAS_PWRITEV 0 diff --git a/core/shared/platform/esp-idf/espidf_platform.c b/core/shared/platform/esp-idf/espidf_platform.c index af6be88cb..896190db5 100644 --- a/core/shared/platform/esp-idf/espidf_platform.c +++ b/core/shared/platform/esp-idf/espidf_platform.c @@ -58,3 +58,193 @@ os_usleep(uint32 usec) { return usleep(usec); } + +/* Below parts of readv & writev are ported from Nuttx, under Apache License + * v2.0 */ + +ssize_t +readv(int fildes, const struct iovec *iov, int iovcnt) +{ + ssize_t ntotal; + ssize_t nread; + size_t remaining; + uint8_t *buffer; + int i; + + /* Process each entry in the struct iovec array */ + + for (i = 0, ntotal = 0; i < iovcnt; i++) { + /* Ignore zero-length reads */ + + if (iov[i].iov_len > 0) { + buffer = iov[i].iov_base; + remaining = iov[i].iov_len; + + /* Read repeatedly as necessary to fill buffer */ + + do { + /* NOTE: read() is a cancellation point */ + + nread = read(fildes, buffer, remaining); + + /* Check for a read error */ + + if (nread < 0) { + return nread; + } + + /* Check for an end-of-file condition */ + + else if (nread == 0) { + return ntotal; + } + + /* Update pointers and counts in order to handle partial + * buffer reads. + */ + + buffer += nread; + remaining -= nread; + ntotal += nread; + } while (remaining > 0); + } + } + + return ntotal; +} + +ssize_t +writev(int fildes, const struct iovec *iov, int iovcnt) +{ + ssize_t ntotal; + ssize_t nwritten; + size_t remaining; + uint8_t *buffer; + int i; + + /* Process each entry in the struct iovec array */ + + for (i = 0, ntotal = 0; i < iovcnt; i++) { + /* Ignore zero-length writes */ + + if (iov[i].iov_len > 0) { + buffer = iov[i].iov_base; + remaining = iov[i].iov_len; + + /* Write repeatedly as necessary to write the entire buffer */ + + do { + /* NOTE: write() is a cancellation point */ + + nwritten = write(fildes, buffer, remaining); + + /* Check for a write error */ + + if (nwritten < 0) { + return ntotal ? ntotal : -1; + } + + /* Update pointers and counts in order to handle partial + * buffer writes. + */ + + buffer += nwritten; + remaining -= nwritten; + ntotal += nwritten; + } while (remaining > 0); + } + } + + return ntotal; +} + +int +openat(int fd, const char *path, int oflags, ...) +{ + errno = ENOSYS; + return -1; +} + +int +fstatat(int fd, const char *path, struct stat *buf, int flag) +{ + errno = ENOSYS; + return -1; +} + +int +mkdirat(int fd, const char *path, mode_t mode) +{ + errno = ENOSYS; + return -1; +} + +ssize_t +readlinkat(int fd, const char *path, char *buf, size_t bufsize) +{ + errno = EINVAL; + return -1; +} + +int +linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) +{ + errno = ENOSYS; + return -1; +} + +int +renameat(int fromfd, const char *from, int tofd, const char *to) +{ + errno = ENOSYS; + return -1; +} + +int +symlinkat(const char *target, int fd, const char *path) +{ + errno = ENOSYS; + return -1; +} + +int +unlinkat(int fd, const char *path, int flag) +{ + errno = ENOSYS; + return -1; +} + +int +utimensat(int fd, const char *path, const struct timespec ts[2], int flag) +{ + errno = ENOSYS; + return -1; +} + +DIR * +fdopendir(int fd) +{ + errno = ENOSYS; + return NULL; +} + +int +ftruncate(int fd, off_t length) +{ + errno = ENOSYS; + return -1; +} + +int +futimens(int fd, const struct timespec times[2]) +{ + errno = ENOSYS; + return -1; +} + +int +nanosleep(const struct timespec *req, struct timespec *rem) +{ + errno = ENOSYS; + return -1; +} \ No newline at end of file diff --git a/core/shared/platform/esp-idf/platform_internal.h b/core/shared/platform/esp-idf/platform_internal.h index 9a0a4afd4..7b4d35ccd 100644 --- a/core/shared/platform/esp-idf/platform_internal.h +++ b/core/shared/platform/esp-idf/platform_internal.h @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #include "esp_pthread.h" #include "esp_timer.h" @@ -43,6 +46,66 @@ typedef unsigned int korp_sem; /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 5 +/* Special value for tv_nsec field of timespec */ + +#define UTIME_NOW ((1l << 30) - 1l) +#ifndef __cplusplus +#define UTIME_OMIT ((1l << 30) - 2l) +#endif + +#ifdef DT_UNKNOWN +#undef DT_UNKNOWN +#endif + +#ifdef DT_REG +#undef DT_REG +#endif + +#ifdef DT_DIR +#undef DT_DIR +#endif + +/* Below parts of d_type define are ported from Nuttx, under Apache License v2.0 + */ + +/* File type code for the d_type field in dirent structure. + * Note that because of the simplified filesystem organization of the NuttX, + * top-level, pseudo-file system, an inode can be BOTH a file and a directory + */ + +#define DTYPE_UNKNOWN 0 +#define DTYPE_FIFO 1 +#define DTYPE_CHR 2 +#define DTYPE_SEM 3 +#define DTYPE_DIRECTORY 4 +#define DTYPE_MQ 5 +#define DTYPE_BLK 6 +#define DTYPE_SHM 7 +#define DTYPE_FILE 8 +#define DTYPE_MTD 9 +#define DTYPE_LINK 10 +#define DTYPE_SOCK 12 + +/* The d_type field of the dirent structure is not specified by POSIX. It + * is a non-standard, 4.5BSD extension that is implemented by most OSs. A + * POSIX compliant OS may not implement the d_type field at all. Many OS's + * (including glibc) may use the following alternative naming for the file + * type names: + */ + +#define DT_UNKNOWN DTYPE_UNKNOWN +#define DT_FIFO DTYPE_FIFO +#define DT_CHR DTYPE_CHR +#define DT_SEM DTYPE_SEM +#define DT_DIR DTYPE_DIRECTORY +#define DT_MQ DTYPE_MQ +#define DT_BLK DTYPE_BLK +#define DT_SHM DTYPE_SHM +#define DT_REG DTYPE_FILE +#define DT_MTD DTYPE_MTD +#define DT_LNK DTYPE_LINK +#define DT_SOCK DTYPE_SOCK + #ifdef __cplusplus } #endif