Skip to content

Commit 552f850

Browse files
authored
Fix __wasi_subscription_t inconsistent with wasi-libc issue (#964)
Fix __wasi_subscription_t structure definition inconsistent with wasi-libc definition issue, reported by #961, tested with sleep, poll API and other wasi cases on x86-64, x86-32 and arm32 targets.
1 parent e0511fe commit 552f850

File tree

2 files changed

+116
-62
lines changed

2 files changed

+116
-62
lines changed

core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h

Lines changed: 92 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -441,47 +441,100 @@ _Static_assert(sizeof(void *) != 4 ||
441441
_Static_assert(sizeof(void *) != 8 ||
442442
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
443443

444+
/**
445+
* The contents of a `subscription` when type is `eventtype::clock`.
446+
*/
447+
typedef struct __wasi_subscription_clock_t {
448+
/**
449+
* The clock against which to compare the timestamp.
450+
*/
451+
__wasi_clockid_t clock_id;
452+
453+
uint8_t __paddings1[4];
454+
455+
/**
456+
* The absolute or relative timestamp.
457+
*/
458+
__wasi_timestamp_t timeout;
459+
460+
/**
461+
* The amount of time that the implementation may wait additionally
462+
* to coalesce with other events.
463+
*/
464+
__wasi_timestamp_t precision;
465+
466+
/**
467+
* Flags specifying whether the timeout is absolute or relative
468+
*/
469+
__wasi_subclockflags_t flags;
470+
471+
uint8_t __paddings2[4];
472+
473+
} __wasi_subscription_clock_t __attribute__((aligned(8)));
474+
475+
_Static_assert(sizeof(__wasi_subscription_clock_t) == 32, "witx calculated size");
476+
_Static_assert(_Alignof(__wasi_subscription_clock_t) == 8, "witx calculated align");
477+
_Static_assert(offsetof(__wasi_subscription_clock_t, clock_id) == 0, "witx calculated offset");
478+
_Static_assert(offsetof(__wasi_subscription_clock_t, timeout) == 8, "witx calculated offset");
479+
_Static_assert(offsetof(__wasi_subscription_clock_t, precision) == 16, "witx calculated offset");
480+
_Static_assert(offsetof(__wasi_subscription_clock_t, flags) == 24, "witx calculated offset");
481+
482+
/**
483+
* The contents of a `subscription` when type is type is
484+
* `eventtype::fd_read` or `eventtype::fd_write`.
485+
*/
486+
typedef struct __wasi_subscription_fd_readwrite_t {
487+
/**
488+
* The file descriptor on which to wait for it to become ready for reading or writing.
489+
*/
490+
__wasi_fd_t fd;
491+
492+
} __wasi_subscription_fd_readwrite_t;
493+
494+
_Static_assert(sizeof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated size");
495+
_Static_assert(_Alignof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated align");
496+
_Static_assert(offsetof(__wasi_subscription_fd_readwrite_t, fd) == 0, "witx calculated offset");
497+
498+
/**
499+
* The contents of a `subscription`.
500+
*/
501+
typedef union __wasi_subscription_u_u_t {
502+
__wasi_subscription_clock_t clock;
503+
__wasi_subscription_fd_readwrite_t fd_readwrite;
504+
} __wasi_subscription_u_u_t ;
505+
506+
typedef struct __wasi_subscription_u_t {
507+
__wasi_eventtype_t type;
508+
__wasi_subscription_u_u_t u;
509+
} __wasi_subscription_u_t __attribute__((aligned(8)));
510+
511+
_Static_assert(sizeof(__wasi_subscription_u_t) == 40, "witx calculated size");
512+
_Static_assert(_Alignof(__wasi_subscription_u_t) == 8, "witx calculated align");
513+
_Static_assert(offsetof(__wasi_subscription_u_t, u) == 8, "witx calculated union offset");
514+
_Static_assert(sizeof(__wasi_subscription_u_u_t) == 32, "witx calculated union size");
515+
_Static_assert(_Alignof(__wasi_subscription_u_u_t) == 8, "witx calculated union align");
516+
517+
/**
518+
* Subscription to an event.
519+
*/
444520
typedef struct __wasi_subscription_t {
521+
/**
522+
* User-provided value that is attached to the subscription in the
523+
* implementation and returned through `event::userdata`.
524+
*/
445525
__wasi_userdata_t userdata;
446-
__wasi_eventtype_t type;
447-
uint8_t __paddings[7];
448-
union __wasi_subscription_u {
449-
struct __wasi_subscription_u_clock_t {
450-
__wasi_userdata_t identifier;
451-
__wasi_clockid_t clock_id;
452-
uint8_t __paddings1[4];
453-
__wasi_timestamp_t timeout;
454-
__wasi_timestamp_t precision;
455-
__wasi_subclockflags_t flags;
456-
uint8_t __paddings2[6];
457-
} clock;
458-
struct __wasi_subscription_u_fd_readwrite_t {
459-
__wasi_fd_t fd;
460-
} fd_readwrite;
461-
} u;
462-
} __wasi_subscription_t __attribute__((aligned(8)));
463-
_Static_assert(
464-
offsetof(__wasi_subscription_t, userdata) == 0, "non-wasi data layout");
465-
_Static_assert(
466-
offsetof(__wasi_subscription_t, type) == 8, "non-wasi data layout");
467-
_Static_assert(
468-
offsetof(__wasi_subscription_t, u.clock.identifier) == 16,
469-
"non-wasi data layout");
470-
_Static_assert(
471-
offsetof(__wasi_subscription_t, u.clock.clock_id) == 24,
472-
"non-wasi data layout");
473-
_Static_assert(
474-
offsetof(__wasi_subscription_t, u.clock.timeout) == 32, "non-wasi data layout");
475-
_Static_assert(
476-
offsetof(__wasi_subscription_t, u.clock.precision) == 40,
477-
"non-wasi data layout");
478-
_Static_assert(
479-
offsetof(__wasi_subscription_t, u.clock.flags) == 48, "non-wasi data layout");
480-
_Static_assert(
481-
offsetof(__wasi_subscription_t, u.fd_readwrite.fd) == 16,
482-
"non-wasi data layout");
483-
_Static_assert(sizeof(__wasi_subscription_t) == 56, "non-wasi data layout");
484-
_Static_assert(_Alignof(__wasi_subscription_t) == 8, "non-wasi data layout");
526+
527+
/**
528+
* The type of the event to which to subscribe, and its contents
529+
*/
530+
__wasi_subscription_u_t u;
531+
532+
} __wasi_subscription_t;
533+
534+
_Static_assert(sizeof(__wasi_subscription_t) == 48, "witx calculated size");
535+
_Static_assert(_Alignof(__wasi_subscription_t) == 8, "witx calculated align");
536+
_Static_assert(offsetof(__wasi_subscription_t, userdata) == 0, "witx calculated offset");
537+
_Static_assert(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset");
485538

486539
#if defined(WASMTIME_SSP_WASI_API)
487540
#define WASMTIME_SSP_SYSCALL_NAME(name) \

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

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,19 +2418,19 @@ wasmtime_ssp_poll_oneoff(
24182418
size_t *nevents) NO_LOCK_ANALYSIS
24192419
{
24202420
// Sleeping.
2421-
if (nsubscriptions == 1 && in[0].type == __WASI_EVENTTYPE_CLOCK) {
2421+
if (nsubscriptions == 1 && in[0].u.type == __WASI_EVENTTYPE_CLOCK) {
24222422
out[0] = (__wasi_event_t){
24232423
.userdata = in[0].userdata,
2424-
.type = in[0].type,
2424+
.type = in[0].u.type,
24252425
};
24262426
#if CONFIG_HAS_CLOCK_NANOSLEEP
24272427
clockid_t clock_id;
2428-
if (convert_clockid(in[0].u.clock.clock_id, &clock_id)) {
2428+
if (convert_clockid(in[0].u.u.clock.clock_id, &clock_id)) {
24292429
struct timespec ts;
2430-
convert_timestamp(in[0].u.clock.timeout, &ts);
2430+
convert_timestamp(in[0].u.u.clock.timeout, &ts);
24312431
int ret = clock_nanosleep(
24322432
clock_id,
2433-
(in[0].u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME) != 0
2433+
(in[0].u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME) != 0
24342434
? TIMER_ABSTIME
24352435
: 0,
24362436
&ts, NULL);
@@ -2441,9 +2441,9 @@ wasmtime_ssp_poll_oneoff(
24412441
out[0].error = __WASI_ENOTSUP;
24422442
}
24432443
#else
2444-
switch (in[0].u.clock.clock_id) {
2444+
switch (in[0].u.u.clock.clock_id) {
24452445
case __WASI_CLOCK_MONOTONIC:
2446-
if ((in[0].u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
2446+
if ((in[0].u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
24472447
!= 0) {
24482448
// TODO(ed): Implement.
24492449
fputs("Unimplemented absolute sleep on monotonic clock\n",
@@ -2454,12 +2454,12 @@ wasmtime_ssp_poll_oneoff(
24542454
// Perform relative sleeps on the monotonic clock also using
24552455
// nanosleep(). This is incorrect, but good enough for now.
24562456
struct timespec ts;
2457-
convert_timestamp(in[0].u.clock.timeout, &ts);
2457+
convert_timestamp(in[0].u.u.clock.timeout, &ts);
24582458
nanosleep(&ts, NULL);
24592459
}
24602460
break;
24612461
case __WASI_CLOCK_REALTIME:
2462-
if ((in[0].u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
2462+
if ((in[0].u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
24632463
!= 0) {
24642464
// Sleeping to an absolute point in time can only be done
24652465
// by waiting on a condition variable.
@@ -2473,15 +2473,16 @@ wasmtime_ssp_poll_oneoff(
24732473
return -1;
24742474
}
24752475
mutex_lock(&mutex);
2476-
cond_timedwait(&cond, &mutex, in[0].u.clock.timeout, true);
2476+
cond_timedwait(&cond, &mutex, in[0].u.u.clock.timeout,
2477+
true);
24772478
mutex_unlock(&mutex);
24782479
mutex_destroy(&mutex);
24792480
cond_destroy(&cond);
24802481
}
24812482
else {
24822483
// Relative sleeps can be done using nanosleep().
24832484
struct timespec ts;
2484-
convert_timestamp(in[0].u.clock.timeout, &ts);
2485+
convert_timestamp(in[0].u.u.clock.timeout, &ts);
24852486
nanosleep(&ts, NULL);
24862487
}
24872488
break;
@@ -2519,18 +2520,18 @@ wasmtime_ssp_poll_oneoff(
25192520
const __wasi_subscription_t *clock_subscription = NULL;
25202521
for (size_t i = 0; i < nsubscriptions; ++i) {
25212522
const __wasi_subscription_t *s = &in[i];
2522-
switch (s->type) {
2523+
switch (s->u.type) {
25232524
case __WASI_EVENTTYPE_FD_READ:
25242525
case __WASI_EVENTTYPE_FD_WRITE:
25252526
{
25262527
__wasi_errno_t error =
2527-
fd_object_get_locked(&fos[i], ft, s->u.fd_readwrite.fd,
2528+
fd_object_get_locked(&fos[i], ft, s->u.u.fd_readwrite.fd,
25282529
__WASI_RIGHT_POLL_FD_READWRITE, 0);
25292530
if (error == 0) {
25302531
// Proper file descriptor on which we can poll().
25312532
pfds[i] = (struct pollfd){
25322533
.fd = fd_number(fos[i]),
2533-
.events = s->type == __WASI_EVENTTYPE_FD_READ
2534+
.events = s->u.type == __WASI_EVENTTYPE_FD_READ
25342535
? POLLRDNORM
25352536
: POLLWRNORM,
25362537
};
@@ -2542,14 +2543,14 @@ wasmtime_ssp_poll_oneoff(
25422543
out[(*nevents)++] = (__wasi_event_t){
25432544
.userdata = s->userdata,
25442545
.error = error,
2545-
.type = s->type,
2546+
.type = s->u.type,
25462547
};
25472548
}
25482549
break;
25492550
}
25502551
case __WASI_EVENTTYPE_CLOCK:
25512552
if (clock_subscription == NULL
2552-
&& (s->u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
2553+
&& (s->u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
25532554
== 0) {
25542555
// Relative timeout.
25552556
fos[i] = NULL;
@@ -2565,7 +2566,7 @@ wasmtime_ssp_poll_oneoff(
25652566
out[(*nevents)++] = (__wasi_event_t){
25662567
.userdata = s->userdata,
25672568
.error = __WASI_ENOSYS,
2568-
.type = s->type,
2569+
.type = s->u.type,
25692570
};
25702571
break;
25712572
}
@@ -2579,7 +2580,7 @@ wasmtime_ssp_poll_oneoff(
25792580
timeout = 0;
25802581
}
25812582
else if (clock_subscription != NULL) {
2582-
__wasi_timestamp_t ts = clock_subscription->u.clock.timeout / 1000000;
2583+
__wasi_timestamp_t ts = clock_subscription->u.u.clock.timeout / 1000000;
25832584
timeout = ts > INT_MAX ? -1 : (int)ts;
25842585
}
25852586
else {
@@ -2603,7 +2604,7 @@ wasmtime_ssp_poll_oneoff(
26032604
for (size_t i = 0; i < nsubscriptions; ++i) {
26042605
if (pfds[i].fd >= 0) {
26052606
__wasi_filesize_t nbytes = 0;
2606-
if (in[i].type == __WASI_EVENTTYPE_FD_READ) {
2607+
if (in[i].u.type == __WASI_EVENTTYPE_FD_READ) {
26072608
int l;
26082609
if (ioctl(fd_number(fos[i]), FIONREAD, &l) == 0)
26092610
nbytes = (__wasi_filesize_t)l;
@@ -2622,22 +2623,22 @@ wasmtime_ssp_poll_oneoff(
26222623
#else
26232624
.error = __WASI_EBADF,
26242625
#endif
2625-
.type = in[i].type,
2626+
.type = in[i].u.type,
26262627
};
26272628
}
26282629
else if ((pfds[i].revents & POLLERR) != 0) {
26292630
// File descriptor is in an error state.
26302631
out[(*nevents)++] = (__wasi_event_t){
26312632
.userdata = in[i].userdata,
26322633
.error = __WASI_EIO,
2633-
.type = in[i].type,
2634+
.type = in[i].u.type,
26342635
};
26352636
}
26362637
else if ((pfds[i].revents & POLLHUP) != 0) {
26372638
// End-of-file.
26382639
out[(*nevents)++] = (__wasi_event_t){
26392640
.userdata = in[i].userdata,
2640-
.type = in[i].type,
2641+
.type = in[i].u.type,
26412642
.u.fd_readwrite.nbytes = nbytes,
26422643
.u.fd_readwrite.flags =
26432644
__WASI_EVENT_FD_READWRITE_HANGUP,
@@ -2647,7 +2648,7 @@ wasmtime_ssp_poll_oneoff(
26472648
// Read or write possible.
26482649
out[(*nevents)++] = (__wasi_event_t){
26492650
.userdata = in[i].userdata,
2650-
.type = in[i].type,
2651+
.type = in[i].u.type,
26512652
.u.fd_readwrite.nbytes = nbytes,
26522653
};
26532654
}

0 commit comments

Comments
 (0)