Skip to content

Commit d8ee771

Browse files
authored
Add Cosmopolitan Libc Platform (#2598)
This PR adds the Cosmopolitan Libc platform enabling compatibility with multiple x86_64 operating systems with the same binary. The platform is similar to the Linux platform, but for now only x86_64 with interpreter modes are supported. The only major change to the core is `posix.c/convert_errno()` was rewritten to use a switch statement. With Cosmopolitan errno values depend on the currently running operating system, and so they are non-constant and cannot be used in array designators. However, the `cosmocc` compiler allows non-constant case labels in switch statements, enabling the new version. And updated wamr-test-suites script to add `-j <platform>` option. The spec tests can be ran via `CC=cosmocc ./test_wamr.sh -j cosmopolitan -t classic-interp` or `CC=cosmocc ./test_wamr.sh -j cosmopolitan -t fast-interp`.
1 parent 8987432 commit d8ee771

File tree

11 files changed

+512
-94
lines changed

11 files changed

+512
-94
lines changed

core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c

+90-89
Original file line numberDiff line numberDiff line change
@@ -60,98 +60,99 @@ static_assert(sizeof(struct iovec) == sizeof(__wasi_ciovec_t),
6060
static __wasi_errno_t
6161
convert_errno(int error)
6262
{
63-
static const __wasi_errno_t errors[] = {
64-
#define X(v) [v] = __WASI_##v
65-
X(E2BIG),
66-
X(EACCES),
67-
X(EADDRINUSE),
68-
X(EADDRNOTAVAIL),
69-
X(EAFNOSUPPORT),
70-
X(EAGAIN),
71-
X(EALREADY),
72-
X(EBADF),
73-
X(EBADMSG),
74-
X(EBUSY),
75-
X(ECANCELED),
76-
X(ECHILD),
77-
X(ECONNABORTED),
78-
X(ECONNREFUSED),
79-
X(ECONNRESET),
80-
X(EDEADLK),
81-
X(EDESTADDRREQ),
82-
X(EDOM),
83-
X(EDQUOT),
84-
X(EEXIST),
85-
X(EFAULT),
86-
X(EFBIG),
87-
X(EHOSTUNREACH),
88-
X(EIDRM),
89-
X(EILSEQ),
90-
X(EINPROGRESS),
91-
X(EINTR),
92-
X(EINVAL),
93-
X(EIO),
94-
X(EISCONN),
95-
X(EISDIR),
96-
X(ELOOP),
97-
X(EMFILE),
98-
X(EMLINK),
99-
X(EMSGSIZE),
100-
X(EMULTIHOP),
101-
X(ENAMETOOLONG),
102-
X(ENETDOWN),
103-
X(ENETRESET),
104-
X(ENETUNREACH),
105-
X(ENFILE),
106-
X(ENOBUFS),
107-
X(ENODEV),
108-
X(ENOENT),
109-
X(ENOEXEC),
110-
X(ENOLCK),
111-
X(ENOLINK),
112-
X(ENOMEM),
113-
X(ENOMSG),
114-
X(ENOPROTOOPT),
115-
X(ENOSPC),
116-
X(ENOSYS),
63+
__wasi_errno_t code = __WASI_ENOSYS;
64+
#define X(v) \
65+
case v: \
66+
code = __WASI_##v; \
67+
break;
68+
switch (error) {
69+
X(E2BIG)
70+
X(EACCES)
71+
X(EADDRINUSE)
72+
X(EADDRNOTAVAIL)
73+
X(EAFNOSUPPORT)
74+
X(EAGAIN)
75+
X(EALREADY)
76+
X(EBADF)
77+
X(EBADMSG)
78+
X(EBUSY)
79+
X(ECANCELED)
80+
X(ECHILD)
81+
X(ECONNABORTED)
82+
X(ECONNREFUSED)
83+
X(ECONNRESET)
84+
X(EDEADLK)
85+
X(EDESTADDRREQ)
86+
X(EDOM)
87+
X(EDQUOT)
88+
X(EEXIST)
89+
X(EFAULT)
90+
X(EFBIG)
91+
X(EHOSTUNREACH)
92+
X(EIDRM)
93+
X(EILSEQ)
94+
X(EINPROGRESS)
95+
X(EINTR)
96+
X(EINVAL)
97+
X(EIO)
98+
X(EISCONN)
99+
X(EISDIR)
100+
X(ELOOP)
101+
X(EMFILE)
102+
X(EMLINK)
103+
X(EMSGSIZE)
104+
X(EMULTIHOP)
105+
X(ENAMETOOLONG)
106+
X(ENETDOWN)
107+
X(ENETRESET)
108+
X(ENETUNREACH)
109+
X(ENFILE)
110+
X(ENOBUFS)
111+
X(ENODEV)
112+
X(ENOENT)
113+
X(ENOEXEC)
114+
X(ENOLCK)
115+
X(ENOLINK)
116+
X(ENOMEM)
117+
X(ENOMSG)
118+
X(ENOPROTOOPT)
119+
X(ENOSPC)
120+
X(ENOSYS)
117121
#ifdef ENOTCAPABLE
118-
X(ENOTCAPABLE),
122+
X(ENOTCAPABLE)
119123
#endif
120-
X(ENOTCONN),
121-
X(ENOTDIR),
122-
X(ENOTEMPTY),
123-
X(ENOTRECOVERABLE),
124-
X(ENOTSOCK),
125-
X(ENOTSUP),
126-
X(ENOTTY),
127-
X(ENXIO),
128-
X(EOVERFLOW),
129-
X(EOWNERDEAD),
130-
X(EPERM),
131-
X(EPIPE),
132-
X(EPROTO),
133-
X(EPROTONOSUPPORT),
134-
X(EPROTOTYPE),
135-
X(ERANGE),
136-
X(EROFS),
137-
X(ESPIPE),
138-
X(ESRCH),
139-
X(ESTALE),
140-
X(ETIMEDOUT),
141-
X(ETXTBSY),
142-
X(EXDEV),
124+
X(ENOTCONN)
125+
X(ENOTDIR)
126+
X(ENOTEMPTY)
127+
X(ENOTRECOVERABLE)
128+
X(ENOTSOCK)
129+
X(ENOTSUP)
130+
X(ENOTTY)
131+
X(ENXIO)
132+
X(EOVERFLOW)
133+
X(EOWNERDEAD)
134+
X(EPERM)
135+
X(EPIPE)
136+
X(EPROTO)
137+
X(EPROTONOSUPPORT)
138+
X(EPROTOTYPE)
139+
X(ERANGE)
140+
X(EROFS)
141+
X(ESPIPE)
142+
X(ESRCH)
143+
X(ESTALE)
144+
X(ETIMEDOUT)
145+
X(ETXTBSY)
146+
X(EXDEV)
147+
default:
148+
if (error == EOPNOTSUPP)
149+
code = __WASI_ENOTSUP;
150+
else if (code == EWOULDBLOCK)
151+
code = __WASI_EAGAIN;
152+
break;
153+
}
143154
#undef X
144-
#if EOPNOTSUPP != ENOTSUP
145-
[EOPNOTSUPP] = __WASI_ENOTSUP,
146-
#endif
147-
#if EWOULDBLOCK != EAGAIN
148-
[EWOULDBLOCK] = __WASI_EAGAIN,
149-
#endif
150-
};
151-
if (error < 0 || (size_t)error >= sizeof(errors) / sizeof(errors[0])
152-
|| errors[error] == 0)
153-
return __WASI_ENOSYS;
154-
return errors[error];
155+
return code;
155156
}
156157

157158
static bool

core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
#endif
6666
#endif
6767

68-
#if !defined(__APPLE__) && !defined(ESP_PLATFORM)
68+
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(__COSMOPOLITAN__)
6969
#define CONFIG_HAS_POSIX_FALLOCATE 1
7070
#else
7171
#define CONFIG_HAS_POSIX_FALLOCATE 0
@@ -83,7 +83,8 @@
8383
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
8484
#endif
8585

86-
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX)
86+
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) \
87+
&& !defined(__COSMOPOLITAN__)
8788
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
8889
#else
8990
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0

core/shared/platform/common/posix/posix_socket.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
799799
{
800800
assert(imr_multiaddr);
801801
if (is_ipv6) {
802-
#ifdef IPPROTO_IPV6
802+
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
803803
struct ipv6_mreq mreq;
804804
for (int i = 0; i < 8; i++) {
805805
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =
@@ -837,7 +837,7 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
837837
{
838838
assert(imr_multiaddr);
839839
if (is_ipv6) {
840-
#ifdef IPPROTO_IPV6
840+
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
841841
struct ipv6_mreq mreq;
842842
for (int i = 0; i < 8; i++) {
843843
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (C) 2019 Intel Corporation. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
*/
5+
6+
#include "platform_api_vmcore.h"
7+
8+
int
9+
bh_platform_init()
10+
{
11+
return 0;
12+
}
13+
14+
void
15+
bh_platform_destroy()
16+
{}
17+
18+
int
19+
os_printf(const char *format, ...)
20+
{
21+
int ret = 0;
22+
va_list ap;
23+
24+
va_start(ap, format);
25+
#ifndef BH_VPRINTF
26+
ret += vprintf(format, ap);
27+
#else
28+
ret += BH_VPRINTF(format, ap);
29+
#endif
30+
va_end(ap);
31+
32+
return ret;
33+
}
34+
35+
int
36+
os_vprintf(const char *format, va_list ap)
37+
{
38+
#ifndef BH_VPRINTF
39+
return vprintf(format, ap);
40+
#else
41+
return BH_VPRINTF(format, ap);
42+
#endif
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (C) 2019 Intel Corporation. All rights reserved.
3+
* Copyright (C) 2023 Dylibso. All rights reserved.
4+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
*/
6+
7+
#ifndef _PLATFORM_INTERNAL_H
8+
#define _PLATFORM_INTERNAL_H
9+
10+
#include <inttypes.h>
11+
#include <stdbool.h>
12+
#include <assert.h>
13+
#include <time.h>
14+
#include <string.h>
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <math.h>
18+
#include <stdarg.h>
19+
#include <ctype.h>
20+
#include <pthread.h>
21+
#include <signal.h>
22+
#include <semaphore.h>
23+
#include <limits.h>
24+
#include <dirent.h>
25+
#include <fcntl.h>
26+
#include <unistd.h>
27+
#include <poll.h>
28+
#include <sched.h>
29+
#include <errno.h>
30+
#include <netinet/in.h>
31+
#include <sys/types.h>
32+
#include <sys/stat.h>
33+
#include <sys/mman.h>
34+
#include <sys/time.h>
35+
#include <sys/uio.h>
36+
#include <sys/ioctl.h>
37+
#include <sys/socket.h>
38+
#include <sys/resource.h>
39+
40+
#ifdef __cplusplus
41+
extern "C" {
42+
#endif
43+
44+
#ifndef BH_PLATFORM_COSMOPOLITAN
45+
#define BH_PLATFORM_COSMOPOLITAN
46+
#endif
47+
48+
/* Stack size of applet threads's native part. */
49+
#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
50+
51+
/* Default thread priority */
52+
#define BH_THREAD_DEFAULT_PRIORITY 0
53+
54+
typedef pthread_t korp_tid;
55+
typedef pthread_mutex_t korp_mutex;
56+
typedef pthread_cond_t korp_cond;
57+
typedef pthread_t korp_thread;
58+
typedef sem_t korp_sem;
59+
60+
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
61+
62+
#define os_thread_local_attribute __thread
63+
64+
#define bh_socket_t int
65+
66+
#if WASM_DISABLE_WRITE_GS_BASE == 0
67+
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
68+
#define os_writegsbase(base_addr) \
69+
do { \
70+
uint64 __gs_value = (uint64)(uintptr_t)base_addr; \
71+
asm volatile("wrgsbase %0" ::"r"(__gs_value) : "memory"); \
72+
} while (0)
73+
#if 0
74+
/* _writegsbase_u64 also works, but need to add -mfsgsbase flag for gcc */
75+
#include <immintrin.h>
76+
#define os_writegsbase(base_addr) \
77+
_writegsbase_u64(((uint64)(uintptr_t)base_addr))
78+
#endif
79+
#endif
80+
#endif
81+
82+
#if WASM_DISABLE_HW_BOUND_CHECK == 0
83+
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
84+
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
85+
|| defined(BUILD_TARGET_RISCV64_LP64)
86+
87+
#include <setjmp.h>
88+
89+
#define OS_ENABLE_HW_BOUND_CHECK
90+
91+
typedef jmp_buf korp_jmpbuf;
92+
93+
#define os_setjmp setjmp
94+
#define os_longjmp longjmp
95+
#define os_alloca alloca
96+
97+
#define os_getpagesize getpagesize
98+
99+
typedef void (*os_signal_handler)(void *sig_addr);
100+
101+
int
102+
os_thread_signal_init(os_signal_handler handler);
103+
104+
void
105+
os_thread_signal_destroy();
106+
107+
bool
108+
os_thread_signal_inited();
109+
110+
void
111+
os_signal_unmask();
112+
113+
void
114+
os_sigreturn();
115+
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
116+
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
117+
118+
#ifdef __cplusplus
119+
}
120+
#endif
121+
122+
#endif /* end of _PLATFORM_INTERNAL_H */

0 commit comments

Comments
 (0)