Skip to content

Commit 93b1a7d

Browse files
lucasAbadFrlum1n0us
authored andcommitted
zephyr: Enable WASI support for file system and sockets on zephyr (#3633)
To address #3311. This work also implements the WASI support on Zephyr. Note that some comments haven't been addressed and will be fixed in the further patches.
1 parent d95b0e3 commit 93b1a7d

48 files changed

Lines changed: 9679 additions & 134 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,14 @@ blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
175175
#ifndef BH_PLATFORM_WINDOWS
176176
/* REVISIT: apply the os_file_handle style abstraction for pollfd? */
177177
__wasi_errno_t
178-
blocking_op_poll(wasm_exec_env_t exec_env, struct pollfd *pfds, nfds_t nfds,
179-
int timeout_ms, int *retp)
178+
blocking_op_poll(wasm_exec_env_t exec_env, os_poll_file_handle *pfds,
179+
os_nfds_t nfds, int timeout_ms, int *retp)
180180
{
181181
int ret;
182182
if (!wasm_runtime_begin_blocking_op(exec_env)) {
183183
return __WASI_EINTR;
184184
}
185-
ret = poll(pfds, nfds, timeout_ms);
185+
ret = os_poll(pfds, nfds, timeout_ms);
186186
wasm_runtime_end_blocking_op(exec_env);
187187
if (ret == -1) {
188188
return convert_errno(errno);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
5757

5858
#ifndef BH_PLATFORM_WINDOWS
5959
__wasi_errno_t
60-
blocking_op_poll(wasm_exec_env_t exec_env, struct pollfd *pfds, nfds_t nfds,
61-
int timeout, int *retp);
60+
blocking_op_poll(wasm_exec_env_t exec_env, os_poll_file_handle *pfds,
61+
os_nfds_t nfds, int timeout, int *retp);
6262
#endif
6363

6464
#endif /* end of _BLOCKING_OP_H_ */

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,12 @@ static inline bool
196196
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
197197
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
198198
{
199+
#if defined(BH_PLATFORM_ZEPHYR)
200+
// TODO: Implement this for Zephyr
201+
return false;
202+
#else
199203
int ret;
200-
struct timespec ts = {
204+
os_timespec ts = {
201205
.tv_sec = (time_t)(timeout / 1000000000),
202206
.tv_nsec = (long)(timeout % 1000000000),
203207
};
@@ -210,8 +214,8 @@ cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
210214
* realtime clock.
211215
*/
212216
if (cond->clock != CLOCK_REALTIME) {
213-
struct timespec ts_monotonic;
214-
struct timespec ts_realtime;
217+
os_timespec ts_monotonic;
218+
os_timespec ts_realtime;
215219

216220
clock_gettime(cond->clock, &ts_monotonic);
217221
ts.tv_sec -= ts_monotonic.tv_sec;
@@ -229,7 +233,7 @@ cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
229233
++ts.tv_sec;
230234
}
231235
}
232-
#endif
236+
#endif /* !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK */
233237
}
234238
else {
235239
#if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
@@ -241,7 +245,7 @@ cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
241245
return ret == ETIMEDOUT;
242246
#else
243247
/* Convert to absolute timeout. */
244-
struct timespec ts_now;
248+
os_timespec ts_now;
245249
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
246250
clock_gettime(cond->clock, &ts_now);
247251
#else
@@ -253,13 +257,14 @@ cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
253257
ts.tv_nsec -= 1000000000;
254258
++ts.tv_sec;
255259
}
256-
#endif
260+
#endif /* CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP */
257261
}
258262

259263
ret = pthread_cond_timedwait(&cond->object, &lock->object, &ts);
260264
bh_assert((ret == 0 || ret == ETIMEDOUT)
261265
&& "pthread_cond_timedwait() failed");
262266
return ret == ETIMEDOUT;
267+
#endif /* BH_PLATFORM_ZEPHYR */
263268
}
264269
#endif
265270

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

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -356,16 +356,20 @@ fd_table_get_entry(struct fd_table *ft, __wasi_fd_t fd,
356356
REQUIRES_SHARED(ft->lock)
357357
{
358358
// Test for file descriptor existence.
359-
if (fd >= ft->size)
359+
if (fd >= ft->size) {
360360
return __WASI_EBADF;
361+
}
362+
361363
struct fd_entry *fe = &ft->entries[fd];
362-
if (fe->object == NULL)
364+
if (fe->object == NULL) {
363365
return __WASI_EBADF;
366+
}
364367

365368
// Validate rights.
366369
if ((~fe->rights_base & rights_base) != 0
367-
|| (~fe->rights_inheriting & rights_inheriting) != 0)
370+
|| (~fe->rights_inheriting & rights_inheriting) != 0) {
368371
return __WASI_ENOTCAPABLE;
372+
}
369373
*ret = fe;
370374
return 0;
371375
}
@@ -426,28 +430,28 @@ fd_table_attach(struct fd_table *ft, __wasi_fd_t fd, struct fd_object *fo,
426430
__wasi_rights_t rights_base, __wasi_rights_t rights_inheriting)
427431
REQUIRES_EXCLUSIVE(ft->lock) CONSUMES(fo->refcount)
428432
{
429-
assert(ft->size > fd && "File descriptor table too small");
433+
bh_assert(ft->size > fd && "File descriptor table too small");
430434
struct fd_entry *fe = &ft->entries[fd];
431-
assert(fe->object == NULL
432-
&& "Attempted to overwrite an existing descriptor");
435+
bh_assert(fe->object == NULL
436+
&& "Attempted to overwrite an existing descriptor");
433437
fe->object = fo;
434438
fe->rights_base = rights_base;
435439
fe->rights_inheriting = rights_inheriting;
436440
++ft->used;
437-
assert(ft->size >= ft->used * 2 && "File descriptor too full");
441+
bh_assert(ft->size >= ft->used * 2 && "File descriptor too full");
438442
}
439443

440444
// Detaches a file descriptor from the file descriptor table.
441445
static void
442446
fd_table_detach(struct fd_table *ft, __wasi_fd_t fd, struct fd_object **fo)
443447
REQUIRES_EXCLUSIVE(ft->lock) PRODUCES((*fo)->refcount)
444448
{
445-
assert(ft->size > fd && "File descriptor table too small");
449+
bh_assert(ft->size > fd && "File descriptor table too small");
446450
struct fd_entry *fe = &ft->entries[fd];
447451
*fo = fe->object;
448-
assert(*fo != NULL && "Attempted to detach nonexistent descriptor");
452+
bh_assert(*fo != NULL && "Attempted to detach nonexistent descriptor");
449453
fe->object = NULL;
450-
assert(ft->used > 0 && "Reference count mismatch");
454+
bh_assert(ft->used > 0 && "Reference count mismatch");
451455
--ft->used;
452456
}
453457

@@ -636,7 +640,7 @@ fd_table_insert_existing(struct fd_table *ft, __wasi_fd_t in,
636640
static __wasi_errno_t
637641
fd_table_unused(struct fd_table *ft, __wasi_fd_t *out) REQUIRES_SHARED(ft->lock)
638642
{
639-
assert(ft->size > ft->used && "File descriptor table has no free slots");
643+
bh_assert(ft->size > ft->used && "File descriptor table has no free slots");
640644
for (;;) {
641645
uintmax_t random_fd = 0;
642646
__wasi_errno_t error = random_uniform(ft->size, &random_fd);
@@ -1550,7 +1554,8 @@ path_put(struct path_access *pa) UNLOCKS(pa->fd_object->refcount)
15501554
{
15511555
if (pa->path_start)
15521556
wasm_runtime_free(pa->path_start);
1553-
if (pa->fd_object->file_handle != pa->fd)
1557+
/* Can't use `!=` operator when `os_file_handle` is a struct */
1558+
if (!os_compare_file_handle(pa->fd_object->file_handle, pa->fd))
15541559
os_close(pa->fd, false);
15551560
fd_object_release(NULL, pa->fd_object);
15561561
}
@@ -1891,7 +1896,7 @@ wasmtime_ssp_fd_filestat_get(wasm_exec_env_t exec_env, struct fd_table *curfds,
18911896
}
18921897

18931898
static void
1894-
convert_timestamp(__wasi_timestamp_t in, struct timespec *out)
1899+
convert_timestamp(__wasi_timestamp_t in, os_timespec *out)
18951900
{
18961901
// Store sub-second remainder.
18971902
#if defined(__SYSCALL_SLONG_TYPE)
@@ -2089,7 +2094,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
20892094
size_t nsubscriptions,
20902095
size_t *nevents) NO_LOCK_ANALYSIS
20912096
{
2092-
#ifdef BH_PLATFORM_WINDOWS
2097+
#if defined(BH_PLATFORM_WINDOWS) || defined(BH_PLATFORM_ZEPHYR)
20932098
return __WASI_ENOSYS;
20942099
#else
20952100
// Sleeping.
@@ -2101,7 +2106,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
21012106
#if CONFIG_HAS_CLOCK_NANOSLEEP
21022107
clockid_t clock_id;
21032108
if (wasi_clockid_to_clockid(in[0].u.u.clock.clock_id, &clock_id)) {
2104-
struct timespec ts;
2109+
os_timespec ts;
21052110
convert_timestamp(in[0].u.u.clock.timeout, &ts);
21062111
int ret = clock_nanosleep(
21072112
clock_id,
@@ -2128,7 +2133,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
21282133
else {
21292134
// Perform relative sleeps on the monotonic clock also using
21302135
// nanosleep(). This is incorrect, but good enough for now.
2131-
struct timespec ts;
2136+
os_timespec ts;
21322137
convert_timestamp(in[0].u.u.clock.timeout, &ts);
21332138
nanosleep(&ts, NULL);
21342139
}
@@ -2156,7 +2161,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
21562161
}
21572162
else {
21582163
// Relative sleeps can be done using nanosleep().
2159-
struct timespec ts;
2164+
os_timespec ts;
21602165
convert_timestamp(in[0].u.u.clock.timeout, &ts);
21612166
nanosleep(&ts, NULL);
21622167
}
@@ -2181,7 +2186,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
21812186
wasm_runtime_malloc((uint32)(nsubscriptions * sizeof(*fos)));
21822187
if (fos == NULL)
21832188
return __WASI_ENOMEM;
2184-
struct pollfd *pfds =
2189+
os_poll_file_handle *pfds =
21852190
wasm_runtime_malloc((uint32)(nsubscriptions * sizeof(*pfds)));
21862191
if (pfds == NULL) {
21872192
wasm_runtime_free(fos);
@@ -2206,7 +2211,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
22062211
__WASI_RIGHT_POLL_FD_READWRITE, 0);
22072212
if (error == 0) {
22082213
// Proper file descriptor on which we can poll().
2209-
pfds[i] = (struct pollfd){
2214+
pfds[i] = (os_poll_file_handle){
22102215
.fd = fos[i]->file_handle,
22112216
.events = s->u.type == __WASI_EVENTTYPE_FD_READ
22122217
? POLLIN
@@ -2216,7 +2221,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
22162221
else {
22172222
// Invalid file descriptor or rights missing.
22182223
fos[i] = NULL;
2219-
pfds[i] = (struct pollfd){ .fd = -1 };
2224+
pfds[i] = (os_poll_file_handle){ .fd = -1 };
22202225
out[(*nevents)++] = (__wasi_event_t){
22212226
.userdata = s->userdata,
22222227
.error = error,
@@ -2231,15 +2236,15 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
22312236
== 0) {
22322237
// Relative timeout.
22332238
fos[i] = NULL;
2234-
pfds[i] = (struct pollfd){ .fd = -1 };
2239+
pfds[i] = (os_poll_file_handle){ .fd = -1 };
22352240
clock_subscription = s;
22362241
break;
22372242
}
22382243
// Fallthrough.
22392244
default:
22402245
// Unsupported event.
22412246
fos[i] = NULL;
2242-
pfds[i] = (struct pollfd){ .fd = -1 };
2247+
pfds[i] = (os_poll_file_handle){ .fd = -1 };
22432248
out[(*nevents)++] = (__wasi_event_t){
22442249
.userdata = s->userdata,
22452250
.error = __WASI_ENOSYS,
@@ -2283,7 +2288,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
22832288
__wasi_filesize_t nbytes = 0;
22842289
if (in[i].u.type == __WASI_EVENTTYPE_FD_READ) {
22852290
int l;
2286-
if (ioctl(fos[i]->file_handle, FIONREAD, &l) == 0)
2291+
if (os_ioctl(fos[i]->file_handle, FIONREAD, &l) == 0)
22872292
nbytes = (__wasi_filesize_t)l;
22882293
}
22892294
if ((pfds[i].revents & POLLNVAL) != 0) {
@@ -2449,7 +2454,7 @@ wasi_addr_to_string(const __wasi_addr_t *addr, char *buf, size_t buflen)
24492454
if (addr->kind == IPv4) {
24502455
const char *format = "%u.%u.%u.%u";
24512456

2452-
assert(buflen >= 16);
2457+
bh_assert(buflen >= 16);
24532458

24542459
snprintf(buf, buflen, format, addr->addr.ip4.addr.n0,
24552460
addr->addr.ip4.addr.n1, addr->addr.ip4.addr.n2,
@@ -2461,14 +2466,13 @@ wasi_addr_to_string(const __wasi_addr_t *addr, char *buf, size_t buflen)
24612466
const char *format = "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x";
24622467
__wasi_addr_ip6_t ipv6 = addr->addr.ip6.addr;
24632468

2464-
assert(buflen >= 40);
2469+
bh_assert(buflen >= 40);
24652470

24662471
snprintf(buf, buflen, format, ipv6.n0, ipv6.n1, ipv6.n2, ipv6.n3,
24672472
ipv6.h0, ipv6.h1, ipv6.h2, ipv6.h3);
24682473

24692474
return true;
24702475
}
2471-
24722476
return false;
24732477
}
24742478

@@ -2575,9 +2579,11 @@ wasi_ssp_sock_connect(wasm_exec_env_t exec_env, struct fd_table *curfds,
25752579
}
25762580

25772581
error = fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_BIND, 0);
2578-
if (error != __WASI_ESUCCESS)
2582+
if (error != __WASI_ESUCCESS) {
25792583
return error;
2584+
}
25802585

2586+
/* Consume __wasi_addr_t */
25812587
ret = blocking_op_socket_connect(exec_env, fo->file_handle, buf,
25822588
addr->kind == IPv4 ? addr->addr.ip4.port
25832589
: addr->addr.ip6.port);
@@ -2726,10 +2732,10 @@ wasi_ssp_sock_open(wasm_exec_env_t exec_env, struct fd_table *curfds,
27262732
}
27272733

27282734
if (SOCKET_DGRAM == socktype) {
2729-
assert(wasi_type == __WASI_FILETYPE_SOCKET_DGRAM);
2735+
bh_assert(wasi_type == __WASI_FILETYPE_SOCKET_DGRAM);
27302736
}
27312737
else {
2732-
assert(wasi_type == __WASI_FILETYPE_SOCKET_STREAM);
2738+
bh_assert(wasi_type == __WASI_FILETYPE_SOCKET_STREAM);
27332739
}
27342740

27352741
// TODO: base rights and inheriting rights ?
@@ -2847,6 +2853,9 @@ wasmtime_ssp_sock_recv_from(wasm_exec_env_t exec_env, struct fd_table *curfds,
28472853
return error;
28482854
}
28492855

2856+
wasi_addr_to_bh_sockaddr(src_addr, &sockaddr);
2857+
2858+
/* Consume bh_sockaddr_t instead of __wasi_addr_t */
28502859
ret = blocking_op_socket_recv_from(exec_env, fo->file_handle, buf, buf_len,
28512860
0, &sockaddr);
28522861
fd_object_release(exec_env, fo);
@@ -2912,6 +2921,7 @@ wasmtime_ssp_sock_send_to(wasm_exec_env_t exec_env, struct fd_table *curfds,
29122921

29132922
wasi_addr_to_bh_sockaddr(dest_addr, &sockaddr);
29142923

2924+
/* Consume bh_sockaddr instead of __wasi_addr_t */
29152925
ret = blocking_op_socket_send_to(exec_env, fo->file_handle, buf, buf_len, 0,
29162926
&sockaddr);
29172927
fd_object_release(exec_env, fo);
@@ -2943,8 +2953,10 @@ wasmtime_ssp_sock_shutdown(wasm_exec_env_t exec_env, struct fd_table *curfds,
29432953
__wasi_errno_t
29442954
wasmtime_ssp_sched_yield(void)
29452955
{
2946-
#ifdef BH_PLATFORM_WINDOWS
2956+
#if defined(BH_PLATFORM_WINDOWS)
29472957
SwitchToThread();
2958+
#elif defined(BH_PLATFORM_ZEPHYR)
2959+
k_yield();
29482960
#else
29492961
if (sched_yield() < 0)
29502962
return convert_errno(errno);

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ random_buf(void *buf, size_t len)
6666
return ret ? __WASI_EINVAL : __WASI_ESUCCESS;
6767
}
6868

69+
#elif defined(BH_PLATFORM_ZEPHYR)
70+
#include <zephyr/random/random.h>
71+
// Maybe having an OS abstraction api would be a good idea
72+
// because every platform is implementing this function.
73+
// we could have a function like `os_random_buf`
74+
// and call `os_random_buf.` in the SSP wrapper `random_buf`.
75+
76+
__wasi_errno_t
77+
random_buf(void *buf, size_t len)
78+
{
79+
sys_rand_get(buf, len);
80+
return __WASI_ESUCCESS;
81+
}
82+
6983
#else
7084

7185
static int urandom = -1;

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,16 @@
4242
#define CONFIG_HAS_GETRANDOM 0
4343
#endif
4444

45-
#if defined(__CloudABI__) || defined(BH_PLATFORM_FREERTOS)
45+
#if defined(__CloudABI__) || defined(BH_PLATFORM_FREERTOS) \
46+
|| defined(BH_PLATFORM_ZEPHYR)
4647
#define CONFIG_HAS_CAP_ENTER 1
4748
#else
4849
#define CONFIG_HAS_CAP_ENTER 0
4950
#endif
5051

5152
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__) \
5253
&& !defined(ESP_PLATFORM) && !defined(DISABLE_CLOCK_NANOSLEEP) \
53-
&& !defined(BH_PLATFORM_FREERTOS)
54+
&& !defined(BH_PLATFORM_FREERTOS) && !defined(BH_PLATFORM_ZEPHYR)
5455
#define CONFIG_HAS_CLOCK_NANOSLEEP 1
5556
#else
5657
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
@@ -63,7 +64,8 @@
6364
#endif
6465

6566
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) && !defined(_WIN32) \
66-
&& !defined(__COSMOPOLITAN__) && !defined(BH_PLATFORM_FREERTOS)
67+
&& !defined(__COSMOPOLITAN__) && !defined(BH_PLATFORM_FREERTOS) \
68+
&& !defined(BH_PLATFORM_ZEPHYR)
6769
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
6870
#else
6971
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0

0 commit comments

Comments
 (0)