소스 검색

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
dongheng 3 년 전
부모
커밋
071b8c2510

+ 4 - 0
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)
 

+ 8 - 7
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

+ 190 - 0
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;
+}

+ 63 - 0
core/shared/platform/esp-idf/platform_internal.h

@@ -18,6 +18,9 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <dirent.h>
 
 #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