Merge branch main into dev/wasi-libc-windows

This commit is contained in:
Wenyong Huang
2023-10-08 15:03:35 +08:00
151 changed files with 5909 additions and 2046 deletions

View File

@ -69,3 +69,7 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush()
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -359,3 +359,7 @@ os_thread_get_stack_boundary()
/* TODO: get alios stack boundary */
return NULL;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}

View File

@ -140,16 +140,12 @@ seekdir(DIR *__dir, long __location);
#endif
#if __ANDROID_API__ < 24
ssize_t
preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset);
ssize_t
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_extension.h"
#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP
static bool g_blocking_op_inited = false;
static int g_blocking_op_signo = SIGUSR1;
static sigset_t g_blocking_op_sigmask;
static void
blocking_op_sighandler(int signo)
{
/* nothing */
}
void
os_set_signal_number_for_blocking_op(int signo)
{
g_blocking_op_signo = signo;
}
int
os_blocking_op_init()
{
if (g_blocking_op_inited) {
return BHT_OK;
}
sigemptyset(&g_blocking_op_sigmask);
sigaddset(&g_blocking_op_sigmask, g_blocking_op_signo);
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = blocking_op_sighandler;
if (sigaction(g_blocking_op_signo, &sa, NULL)) {
return BHT_ERROR;
}
g_blocking_op_inited = true;
return BHT_OK;
}
void
os_begin_blocking_op()
{
pthread_sigmask(SIG_UNBLOCK, &g_blocking_op_sigmask, NULL);
}
void
os_end_blocking_op()
{
pthread_sigmask(SIG_BLOCK, &g_blocking_op_sigmask, NULL);
}
int
os_wakeup_blocking_op(korp_tid tid)
{
int ret = pthread_kill(tid, g_blocking_op_signo);
if (ret != 0) {
return BHT_ERROR;
}
return BHT_OK;
}
#endif /* OS_ENABLE_WAKEUP_BLOCKING_OP */

View File

@ -5,6 +5,10 @@
#include "platform_api_vmcore.h"
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
#include <libkern/OSCacheControl.h>
#endif
#ifndef BH_ENABLE_TRACE_MMAP
#define BH_ENABLE_TRACE_MMAP 0
#endif
@ -36,7 +40,11 @@ void *
os_mmap(void *hint, size_t size, int prot, int flags)
{
int map_prot = PROT_NONE;
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT;
#else
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
#endif
uint64 request_size, page_size;
uint8 *addr = MAP_FAILED;
uint32 i;
@ -251,3 +259,11 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
sys_icache_invalidate(start, len);
#endif
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <time.h>
#include "platform_api_extension.h"
int
os_usleep(uint32 usec)
{
struct timespec ts;
int ret;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
ret = nanosleep(&ts, NULL);
return ret == 0 ? 0 : -1;
}

View File

@ -53,7 +53,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr,
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
bh_sockaddr->port = ntohs(addr->sin_port);
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->is_ipv4 = true;
return BHT_OK;
}
@ -65,12 +65,12 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr,
bh_sockaddr->port = ntohs(addr->sin6_port);
for (i = 0; i < sizeof(bh_sockaddr->addr_bufer.ipv6)
/ sizeof(bh_sockaddr->addr_bufer.ipv6[0]);
for (i = 0; i < sizeof(bh_sockaddr->addr_buffer.ipv6)
/ sizeof(bh_sockaddr->addr_buffer.ipv6[0]);
i++) {
uint16 part_addr = addr->sin6_addr.s6_addr[i * 2]
| (addr->sin6_addr.s6_addr[i * 2 + 1] << 8);
bh_sockaddr->addr_bufer.ipv6[i] = ntohs(part_addr);
bh_sockaddr->addr_buffer.ipv6[i] = ntohs(part_addr);
}
bh_sockaddr->is_ipv4 = false;
@ -91,7 +91,7 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
addr->sin_port = htons(bh_sockaddr->port);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4);
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4);
*socklen = sizeof(*addr);
}
#ifdef IPPROTO_IPV6
@ -101,10 +101,10 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
addr->sin6_port = htons(bh_sockaddr->port);
addr->sin6_family = AF_INET6;
for (i = 0; i < sizeof(bh_sockaddr->addr_bufer.ipv6)
/ sizeof(bh_sockaddr->addr_bufer.ipv6[0]);
for (i = 0; i < sizeof(bh_sockaddr->addr_buffer.ipv6)
/ sizeof(bh_sockaddr->addr_buffer.ipv6[0]);
i++) {
uint16 part_addr = htons(bh_sockaddr->addr_bufer.ipv6[i]);
uint16 part_addr = htons(bh_sockaddr->addr_buffer.ipv6[i]);
addr->sin6_addr.s6_addr[i * 2] = 0xff & part_addr;
addr->sin6_addr.s6_addr[i * 2 + 1] = (0xff00 & part_addr) >> 8;
}
@ -799,7 +799,7 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
{
assert(imr_multiaddr);
if (is_ipv6) {
#ifdef IPPROTO_IPV6
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
struct ipv6_mreq mreq;
for (int i = 0; i < 8; i++) {
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =
@ -837,7 +837,7 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
{
assert(imr_multiaddr);
if (is_ipv6) {
#ifdef IPPROTO_IPV6
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
struct ipv6_mreq mreq;
for (int i = 0; i < 8; i++) {
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =

View File

@ -39,6 +39,9 @@ os_thread_wrapper(void *arg)
#ifdef OS_ENABLE_HW_BOUND_CHECK
if (os_thread_signal_init(handler) != 0)
return NULL;
#endif
#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP
os_end_blocking_op();
#endif
start_func(thread_arg);
#ifdef OS_ENABLE_HW_BOUND_CHECK
@ -470,6 +473,14 @@ os_thread_get_stack_boundary()
return addr;
}
void
os_thread_jit_write_protect_np(bool enabled)
{
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
pthread_jit_write_protect_np(enabled);
#endif
}
#ifdef OS_ENABLE_HW_BOUND_CHECK
#define SIG_ALT_STACK_SIZE (32 * 1024)
@ -564,8 +575,8 @@ mask_signals(int how)
pthread_sigmask(how, &set, NULL);
}
static os_thread_local_attribute struct sigaction prev_sig_act_SIGSEGV;
static os_thread_local_attribute struct sigaction prev_sig_act_SIGBUS;
static struct sigaction prev_sig_act_SIGSEGV;
static struct sigaction prev_sig_act_SIGBUS;
/* ASAN is not designed to work with custom stack unwind or other low-level \
things. > Ignore a function that does some low-level magic. (e.g. walking \
@ -596,9 +607,12 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
prev_sig_act->sa_sigaction(sig_num, sig_info, sig_ucontext);
}
else if (prev_sig_act
&& ((void *)prev_sig_act->sa_sigaction == SIG_DFL
|| (void *)prev_sig_act->sa_sigaction == SIG_IGN)) {
sigaction(sig_num, prev_sig_act, NULL);
&& prev_sig_act->sa_handler
/* Filter out SIG_DFL and SIG_IGN here, they will
run into the else branch below */
&& (void *)prev_sig_act->sa_handler != SIG_DFL
&& (void *)prev_sig_act->sa_handler != SIG_IGN) {
prev_sig_act->sa_handler(sig_num);
}
/* Output signal info and then crash if signal is unhandled */
else {

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
int
bh_platform_init()
{
return 0;
}
void
bh_platform_destroy()
{}
int
os_printf(const char *format, ...)
{
int ret = 0;
va_list ap;
va_start(ap, format);
#ifndef BH_VPRINTF
ret += vprintf(format, ap);
#else
ret += BH_VPRINTF(format, ap);
#endif
va_end(ap);
return ret;
}
int
os_vprintf(const char *format, va_list ap)
{
#ifndef BH_VPRINTF
return vprintf(format, ap);
#else
return BH_VPRINTF(format, ap);
#endif
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* Copyright (C) 2023 Dylibso. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <limits.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <sched.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/resource.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BH_PLATFORM_COSMOPOLITAN
#define BH_PLATFORM_COSMOPOLITAN
#endif
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define os_thread_local_attribute __thread
#define bh_socket_t int
#if WASM_DISABLE_WRITE_GS_BASE == 0
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#define os_writegsbase(base_addr) \
do { \
uint64 __gs_value = (uint64)(uintptr_t)base_addr; \
asm volatile("wrgsbase %0" ::"r"(__gs_value) : "memory"); \
} while (0)
#if 0
/* _writegsbase_u64 also works, but need to add -mfsgsbase flag for gcc */
#include <immintrin.h>
#define os_writegsbase(base_addr) \
_writegsbase_u64(((uint64)(uintptr_t)base_addr))
#endif
#endif
#endif
#if WASM_DISABLE_HW_BOUND_CHECK == 0
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
#include <setjmp.h>
#define OS_ENABLE_HW_BOUND_CHECK
typedef jmp_buf korp_jmpbuf;
#define os_setjmp setjmp
#define os_longjmp longjmp
#define os_alloca alloca
#define os_getpagesize getpagesize
typedef void (*os_signal_handler)(void *sig_addr);
int
os_thread_signal_init(os_signal_handler handler);
void
os_thread_signal_destroy();
bool
os_thread_signal_inited();
void
os_signal_unmask();
void
os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#ifdef __cplusplus
}
#endif
#endif /* end of _PLATFORM_INTERNAL_H */

View File

@ -0,0 +1,19 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# Copyright (C) 2023 Dylibso. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_COSMOPOLITAN)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})

View File

@ -103,6 +103,12 @@ os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -100,6 +100,10 @@ void
#endif
}
void
os_icache_flush(void *start, size_t len)
{}
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
void *
os_get_dbus_mirror(void *ibus)

View File

@ -53,6 +53,10 @@ os_thread_get_stack_boundary(void)
#endif
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
int
os_usleep(uint32 usec)
{

View File

@ -30,7 +30,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen,
assert(socklen >= sizeof(struct sockaddr_in));
bh_sockaddr->port = ntohs(addr->sin_port);
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->is_ipv4 = true;
return BHT_OK;
}

View File

@ -102,6 +102,12 @@ os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -373,6 +373,34 @@ os_sem_getvalue(korp_sem *sem, int *sval);
int
os_sem_unlink(const char *name);
/**
* Initialize process-global state for os_wakeup_blocking_op.
*/
int
os_blocking_op_init();
/**
* Start accepting os_wakeup_blocking_op requests for the calling thread.
*/
void
os_begin_blocking_op();
/**
* Stop accepting os_wakeup_blocking_op requests for the calling thread.
*/
void
os_end_blocking_op();
/**
* Wake up the specified thread.
*
* For example, on posix-like platforms, this can be implemented by
* sending a signal (w/o SA_RESTART) which interrupts a blocking
* system call.
*/
int
os_wakeup_blocking_op(korp_tid tid);
/****************************************************
* Section 2 *
* Socket support *
@ -392,7 +420,7 @@ typedef union {
} bh_ip_addr_buffer_t;
typedef struct {
bh_ip_addr_buffer_t addr_bufer;
bh_ip_addr_buffer_t addr_buffer;
uint16 port;
bool is_ipv4;
} bh_sockaddr_t;

View File

@ -81,6 +81,13 @@ os_self_thread(void);
uint8 *
os_thread_get_stack_boundary(void);
/**
* Set whether the MAP_JIT region write protection is enabled for this thread.
* Pass true to make the region executable, false to make it writable.
*/
void
os_thread_jit_write_protect_np(bool enabled);
/**
************** mutext APIs ***********
* vmcore: Not required until pthread is supported by runtime
@ -143,6 +150,12 @@ os_get_dbus_mirror(void *ibus);
void
os_dcache_flush(void);
/**
* Flush instruction cache.
*/
void
os_icache_flush(void *start, size_t len);
#ifdef __cplusplus
}
#endif

View File

@ -195,3 +195,7 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -261,7 +261,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen,
assert(socklen >= sizeof(struct sockaddr_in));
bh_sockaddr->port = ntohs(addr->sin_port);
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->is_ipv4 = true;
return BHT_OK;
}
@ -279,7 +279,7 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
addr->sin_port = htons(bh_sockaddr->port);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4);
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4);
*socklen = sizeof(*addr);
return BHT_OK;
}

View File

@ -211,6 +211,10 @@ os_thread_get_stack_boundary()
return NULL;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
int
os_rwlock_init(korp_rwlock *lock)
{

View File

@ -116,6 +116,12 @@ os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -144,6 +144,10 @@ os_dcache_flush()
bus_sync();
}
void
os_icache_flush(void *start, size_t len)
{}
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
void *
os_get_dbus_mirror(void *ibus)

View File

@ -124,6 +124,12 @@ utimensat(int fd, const char *path, const struct timespec ts[2], int flag);
DIR *
fdopendir(int fd);
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -79,3 +79,7 @@ os_dcache_flush(void)
irq_unlock(key);
#endif
}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -430,3 +430,7 @@ os_thread_get_stack_boundary()
return NULL;
#endif
}
void
os_thread_jit_write_protect_np(bool enabled)
{}

View File

@ -140,6 +140,10 @@ os_thread_get_stack_boundary(void)
return tid->stack_addr;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
int
os_mutex_init(korp_mutex *mutex)
{
@ -207,3 +211,7 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -73,3 +73,7 @@ os_getpagesize()
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -768,6 +768,10 @@ os_thread_get_stack_boundary()
return thread_stack_boundary;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
#ifdef OS_ENABLE_HW_BOUND_CHECK
static os_thread_local_attribute bool thread_signal_inited = false;

View File

@ -214,6 +214,10 @@ os_dcache_flush()
#endif
}
void
os_icache_flush(void *start, size_t len)
{}
void
set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func,
exec_mem_free_func_t free_func)

View File

@ -574,3 +574,7 @@ os_thread_get_stack_boundary()
return NULL;
#endif
}
void
os_thread_jit_write_protect_np(bool enabled)
{}