Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/lib/host/wasi/wasifunc.cpp
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
#include "host/wasi/wasifunc.h"
5
#include "common/filesystem.h"
6
#include "common/spdlog.h"
7
#include "executor/executor.h"
8
#include "host/wasi/environ.h"
9
#include "runtime/instance/memory.h"
10
11
#include <algorithm>
12
#include <array>
13
#include <limits>
14
#include <numeric>
15
#include <type_traits>
16
#include <vector>
17
18
#if defined(_MSC_VER) && !defined(__clang__)
19
#define __restrict__ __restrict
20
#endif
21
22
namespace WasmEdge {
23
namespace Host {
24
25
namespace {
26
27
template <typename Container>
28
0
inline __wasi_size_t calculateBufferSize(const Container &Array) noexcept {
29
0
  std::vector<__wasi_size_t> Lengths(Array.size());
30
0
  std::transform(Array.begin(), Array.end(), Lengths.begin(),
31
0
                 [](const auto &String) -> __wasi_size_t {
32
0
                   return static_cast<__wasi_size_t>(String.size()) +
33
0
                          UINT32_C(1);
34
0
                 });
35
0
  return std::accumulate(Lengths.begin(), Lengths.end(), UINT32_C(0));
36
0
}
37
38
template <typename T> struct WasiRawType {
39
  using Type = std::underlying_type_t<T>;
40
};
41
template <> struct WasiRawType<uint8_t> {
42
  using Type = uint8_t;
43
};
44
template <> struct WasiRawType<uint16_t> {
45
  using Type = uint16_t;
46
};
47
template <> struct WasiRawType<uint32_t> {
48
  using Type = uint32_t;
49
};
50
template <> struct WasiRawType<uint64_t> {
51
  using Type = uint64_t;
52
};
53
54
template <typename T> using WasiRawTypeT = typename WasiRawType<T>::Type;
55
56
template <typename T> WASI::WasiExpect<T> cast(uint64_t) noexcept;
57
58
template <>
59
WASI::WasiExpect<__wasi_clockid_t>
60
0
cast<__wasi_clockid_t>(uint64_t ClockId) noexcept {
61
0
  switch (static_cast<WasiRawTypeT<__wasi_clockid_t>>(ClockId)) {
62
0
  case __WASI_CLOCKID_REALTIME:
63
0
  case __WASI_CLOCKID_MONOTONIC:
64
0
  case __WASI_CLOCKID_PROCESS_CPUTIME_ID:
65
0
  case __WASI_CLOCKID_THREAD_CPUTIME_ID:
66
0
    return static_cast<__wasi_clockid_t>(ClockId);
67
0
  default:
68
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
69
0
  }
70
0
}
71
72
template <>
73
WASI::WasiExpect<__wasi_advice_t>
74
0
cast<__wasi_advice_t>(uint64_t Advice) noexcept {
75
0
  switch (WasiRawTypeT<__wasi_advice_t>(Advice)) {
76
0
  case __WASI_ADVICE_NORMAL:
77
0
  case __WASI_ADVICE_SEQUENTIAL:
78
0
  case __WASI_ADVICE_RANDOM:
79
0
  case __WASI_ADVICE_WILLNEED:
80
0
  case __WASI_ADVICE_DONTNEED:
81
0
  case __WASI_ADVICE_NOREUSE:
82
0
    return static_cast<__wasi_advice_t>(Advice);
83
0
  default:
84
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
85
0
  }
86
0
}
87
88
template <>
89
WASI::WasiExpect<__wasi_whence_t>
90
0
cast<__wasi_whence_t>(uint64_t Whence) noexcept {
91
0
  switch (WasiRawTypeT<__wasi_whence_t>(Whence)) {
92
0
  case __WASI_WHENCE_SET:
93
0
  case __WASI_WHENCE_CUR:
94
0
  case __WASI_WHENCE_END:
95
0
    return static_cast<__wasi_whence_t>(Whence);
96
0
  default:
97
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
98
0
  }
99
0
}
100
101
template <>
102
WASI::WasiExpect<__wasi_eventtype_t>
103
0
cast<__wasi_eventtype_t>(uint64_t Eventtype) noexcept {
104
0
  switch (WasiRawTypeT<__wasi_eventtype_t>(Eventtype)) {
105
0
  case __WASI_EVENTTYPE_CLOCK:
106
0
  case __WASI_EVENTTYPE_FD_READ:
107
0
  case __WASI_EVENTTYPE_FD_WRITE:
108
0
    return static_cast<__wasi_eventtype_t>(Eventtype);
109
0
  default:
110
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
111
0
  }
112
0
}
113
114
template <>
115
WASI::WasiExpect<__wasi_signal_t>
116
0
cast<__wasi_signal_t>(uint64_t Signal) noexcept {
117
0
  switch (WasiRawTypeT<__wasi_signal_t>(Signal)) {
118
0
  case __WASI_SIGNAL_NONE:
119
0
  case __WASI_SIGNAL_HUP:
120
0
  case __WASI_SIGNAL_INT:
121
0
  case __WASI_SIGNAL_QUIT:
122
0
  case __WASI_SIGNAL_ILL:
123
0
  case __WASI_SIGNAL_TRAP:
124
0
  case __WASI_SIGNAL_ABRT:
125
0
  case __WASI_SIGNAL_BUS:
126
0
  case __WASI_SIGNAL_FPE:
127
0
  case __WASI_SIGNAL_KILL:
128
0
  case __WASI_SIGNAL_USR1:
129
0
  case __WASI_SIGNAL_SEGV:
130
0
  case __WASI_SIGNAL_USR2:
131
0
  case __WASI_SIGNAL_PIPE:
132
0
  case __WASI_SIGNAL_ALRM:
133
0
  case __WASI_SIGNAL_TERM:
134
0
  case __WASI_SIGNAL_CHLD:
135
0
  case __WASI_SIGNAL_CONT:
136
0
  case __WASI_SIGNAL_STOP:
137
0
  case __WASI_SIGNAL_TSTP:
138
0
  case __WASI_SIGNAL_TTIN:
139
0
  case __WASI_SIGNAL_TTOU:
140
0
  case __WASI_SIGNAL_URG:
141
0
  case __WASI_SIGNAL_XCPU:
142
0
  case __WASI_SIGNAL_XFSZ:
143
0
  case __WASI_SIGNAL_VTALRM:
144
0
  case __WASI_SIGNAL_PROF:
145
0
  case __WASI_SIGNAL_WINCH:
146
0
  case __WASI_SIGNAL_POLL:
147
0
  case __WASI_SIGNAL_PWR:
148
0
  case __WASI_SIGNAL_SYS:
149
0
    return static_cast<__wasi_signal_t>(Signal);
150
0
  default:
151
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
152
0
  }
153
0
}
154
155
template <>
156
WASI::WasiExpect<__wasi_rights_t>
157
0
cast<__wasi_rights_t>(uint64_t Rights) noexcept {
158
0
  const auto Mask =
159
0
      __WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_READ |
160
0
      __WASI_RIGHTS_FD_SEEK | __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS |
161
0
      __WASI_RIGHTS_FD_SYNC | __WASI_RIGHTS_FD_TELL | __WASI_RIGHTS_FD_WRITE |
162
0
      __WASI_RIGHTS_FD_ADVISE | __WASI_RIGHTS_FD_ALLOCATE |
163
0
      __WASI_RIGHTS_PATH_CREATE_DIRECTORY | __WASI_RIGHTS_PATH_CREATE_FILE |
164
0
      __WASI_RIGHTS_PATH_LINK_SOURCE | __WASI_RIGHTS_PATH_LINK_TARGET |
165
0
      __WASI_RIGHTS_PATH_OPEN | __WASI_RIGHTS_FD_READDIR |
166
0
      __WASI_RIGHTS_PATH_READLINK | __WASI_RIGHTS_PATH_RENAME_SOURCE |
167
0
      __WASI_RIGHTS_PATH_RENAME_TARGET | __WASI_RIGHTS_PATH_FILESTAT_GET |
168
0
      __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE |
169
0
      __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES | __WASI_RIGHTS_FD_FILESTAT_GET |
170
0
      __WASI_RIGHTS_FD_FILESTAT_SET_SIZE | __WASI_RIGHTS_FD_FILESTAT_SET_TIMES |
171
0
      __WASI_RIGHTS_PATH_SYMLINK | __WASI_RIGHTS_PATH_REMOVE_DIRECTORY |
172
0
      __WASI_RIGHTS_PATH_UNLINK_FILE | __WASI_RIGHTS_POLL_FD_READWRITE |
173
0
      __WASI_RIGHTS_SOCK_SHUTDOWN | __WASI_RIGHTS_SOCK_OPEN |
174
0
      __WASI_RIGHTS_SOCK_CLOSE | __WASI_RIGHTS_SOCK_BIND |
175
0
      __WASI_RIGHTS_SOCK_RECV | __WASI_RIGHTS_SOCK_RECV_FROM |
176
0
      __WASI_RIGHTS_SOCK_SEND | __WASI_RIGHTS_SOCK_SEND_TO;
177
0
  if ((WasiRawTypeT<__wasi_rights_t>(Rights) & ~Mask) == 0) {
178
0
    return static_cast<__wasi_rights_t>(Rights);
179
0
  }
180
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
181
0
}
182
183
template <>
184
WASI::WasiExpect<__wasi_fdflags_t>
185
0
cast<__wasi_fdflags_t>(uint64_t FdFlags) noexcept {
186
0
  const auto Mask = __WASI_FDFLAGS_APPEND | __WASI_FDFLAGS_DSYNC |
187
0
                    __WASI_FDFLAGS_NONBLOCK | __WASI_FDFLAGS_RSYNC |
188
0
                    __WASI_FDFLAGS_SYNC;
189
0
  if ((WasiRawTypeT<__wasi_fdflags_t>(FdFlags) & ~Mask) == 0) {
190
0
    return static_cast<__wasi_fdflags_t>(FdFlags);
191
0
  }
192
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
193
0
}
194
195
template <>
196
WASI::WasiExpect<__wasi_fstflags_t>
197
0
cast<__wasi_fstflags_t>(uint64_t FdFlags) noexcept {
198
0
  const auto Mask = __WASI_FSTFLAGS_ATIM | __WASI_FSTFLAGS_ATIM_NOW |
199
0
                    __WASI_FSTFLAGS_MTIM | __WASI_FSTFLAGS_MTIM_NOW;
200
0
  if ((WasiRawTypeT<__wasi_fstflags_t>(FdFlags) & ~Mask) == 0) {
201
0
    const auto WasiFstFlags = static_cast<__wasi_fstflags_t>(FdFlags);
202
0
    if ((WasiFstFlags & __WASI_FSTFLAGS_ATIM) &&
203
0
        (WasiFstFlags & __WASI_FSTFLAGS_ATIM_NOW)) {
204
0
      return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
205
0
    }
206
0
    if ((WasiFstFlags & __WASI_FSTFLAGS_MTIM) &&
207
0
        (WasiFstFlags & __WASI_FSTFLAGS_MTIM_NOW)) {
208
0
      return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
209
0
    }
210
0
    return WasiFstFlags;
211
0
  }
212
213
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
214
0
}
215
216
template <>
217
WASI::WasiExpect<__wasi_lookupflags_t>
218
0
cast<__wasi_lookupflags_t>(uint64_t LookupFlags) noexcept {
219
0
  const auto Mask = __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
220
0
  if ((WasiRawTypeT<__wasi_lookupflags_t>(LookupFlags) & ~Mask) == 0) {
221
0
    return static_cast<__wasi_lookupflags_t>(LookupFlags);
222
0
  }
223
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
224
0
}
225
226
template <>
227
WASI::WasiExpect<__wasi_oflags_t>
228
0
cast<__wasi_oflags_t>(uint64_t OFlags) noexcept {
229
0
  const auto Mask = __WASI_OFLAGS_CREAT | __WASI_OFLAGS_DIRECTORY |
230
0
                    __WASI_OFLAGS_EXCL | __WASI_OFLAGS_TRUNC;
231
0
  if ((WasiRawTypeT<__wasi_oflags_t>(OFlags) & ~Mask) == 0) {
232
0
    return static_cast<__wasi_oflags_t>(OFlags);
233
0
  }
234
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
235
0
}
236
237
template <>
238
WASI::WasiExpect<__wasi_subclockflags_t>
239
0
cast<__wasi_subclockflags_t>(uint64_t SubClockFlags) noexcept {
240
0
  const auto Mask = __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME;
241
0
  if ((WasiRawTypeT<__wasi_subclockflags_t>(SubClockFlags) & ~Mask) == 0) {
242
0
    return static_cast<__wasi_subclockflags_t>(SubClockFlags);
243
0
  }
244
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
245
0
}
246
247
template <>
248
WASI::WasiExpect<__wasi_riflags_t>
249
0
cast<__wasi_riflags_t>(uint64_t RiFlags) noexcept {
250
0
  const auto Mask = __WASI_RIFLAGS_RECV_PEEK | __WASI_RIFLAGS_RECV_WAITALL;
251
0
  if ((WasiRawTypeT<__wasi_riflags_t>(RiFlags) & ~Mask) == 0) {
252
0
    return static_cast<__wasi_riflags_t>(RiFlags);
253
0
  }
254
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
255
0
}
256
257
template <>
258
WASI::WasiExpect<__wasi_siflags_t>
259
0
cast<__wasi_siflags_t>(uint64_t SiFlags) noexcept {
260
0
  const auto Mask = 0;
261
0
  if ((WasiRawTypeT<__wasi_siflags_t>(SiFlags) & ~Mask) == 0) {
262
0
    return static_cast<__wasi_siflags_t>(SiFlags);
263
0
  }
264
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
265
0
}
266
267
template <>
268
WASI::WasiExpect<__wasi_sdflags_t>
269
0
cast<__wasi_sdflags_t>(uint64_t SdFlags) noexcept {
270
0
  const auto Mask = __WASI_SDFLAGS_RD | __WASI_SDFLAGS_WR;
271
0
  if ((WasiRawTypeT<__wasi_sdflags_t>(SdFlags) & ~Mask) == 0) {
272
0
    return static_cast<__wasi_sdflags_t>(SdFlags);
273
0
  }
274
0
  return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
275
0
}
276
277
template <>
278
WASI::WasiExpect<__wasi_address_family_t>
279
0
cast<__wasi_address_family_t>(uint64_t Family) noexcept {
280
0
  switch (WasiRawTypeT<__wasi_address_family_t>(Family)) {
281
0
  case __WASI_ADDRESS_FAMILY_INET4:
282
0
  case __WASI_ADDRESS_FAMILY_INET6:
283
0
  case __WASI_ADDRESS_FAMILY_AF_UNIX:
284
0
    return static_cast<__wasi_address_family_t>(Family);
285
0
  default:
286
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
287
0
  }
288
0
}
289
290
template <>
291
WASI::WasiExpect<__wasi_sock_type_t>
292
0
cast<__wasi_sock_type_t>(uint64_t SockType) noexcept {
293
0
  switch (WasiRawTypeT<__wasi_sock_type_t>(SockType)) {
294
0
  case __WASI_SOCK_TYPE_SOCK_DGRAM:
295
0
  case __WASI_SOCK_TYPE_SOCK_STREAM:
296
0
    return static_cast<__wasi_sock_type_t>(SockType);
297
0
  default:
298
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
299
0
  }
300
0
}
301
302
template <>
303
WASI::WasiExpect<__wasi_sock_opt_level_t>
304
0
cast<__wasi_sock_opt_level_t>(uint64_t SockOptLevel) noexcept {
305
0
  switch (WasiRawTypeT<__wasi_sock_opt_level_t>(SockOptLevel)) {
306
0
  case __WASI_SOCK_OPT_LEVEL_SOL_SOCKET:
307
0
    return static_cast<__wasi_sock_opt_level_t>(SockOptLevel);
308
0
  default:
309
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
310
0
  }
311
0
}
312
313
template <>
314
WASI::WasiExpect<__wasi_sock_opt_so_t>
315
0
cast<__wasi_sock_opt_so_t>(uint64_t SockOptName) noexcept {
316
0
  switch (WasiRawTypeT<__wasi_sock_opt_so_t>(SockOptName)) {
317
0
  case __WASI_SOCK_OPT_SO_REUSEADDR:
318
0
  case __WASI_SOCK_OPT_SO_TYPE:
319
0
  case __WASI_SOCK_OPT_SO_ERROR:
320
0
  case __WASI_SOCK_OPT_SO_DONTROUTE:
321
0
  case __WASI_SOCK_OPT_SO_BROADCAST:
322
0
  case __WASI_SOCK_OPT_SO_SNDBUF:
323
0
  case __WASI_SOCK_OPT_SO_RCVBUF:
324
0
  case __WASI_SOCK_OPT_SO_KEEPALIVE:
325
0
  case __WASI_SOCK_OPT_SO_OOBINLINE:
326
0
  case __WASI_SOCK_OPT_SO_LINGER:
327
0
  case __WASI_SOCK_OPT_SO_RCVLOWAT:
328
0
  case __WASI_SOCK_OPT_SO_RCVTIMEO:
329
0
  case __WASI_SOCK_OPT_SO_SNDTIMEO:
330
0
  case __WASI_SOCK_OPT_SO_ACCEPTCONN:
331
0
  case __WASI_SOCK_OPT_SO_BINDTODEVICE:
332
0
    return static_cast<__wasi_sock_opt_so_t>(SockOptName);
333
0
  default:
334
0
    return WASI::WasiUnexpect(__WASI_ERRNO_INVAL);
335
0
  }
336
0
}
337
338
template <typename T, size_t MaxSize> class StaticVector {
339
public:
340
0
  constexpr StaticVector() = default;
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char, 18446744073709551615ul>, 1024ul>::StaticVector()
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char const, 18446744073709551615ul>, 1024ul>::StaticVector()
341
  constexpr const T *data() const noexcept {
342
    return reinterpret_cast<T *>(Storage);
343
  }
344
0
  constexpr T *data() noexcept { return reinterpret_cast<T *>(Storage); }
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char, 18446744073709551615ul>, 1024ul>::data()
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char const, 18446744073709551615ul>, 1024ul>::data()
345
0
  constexpr size_t size() const noexcept { return Size; }
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char, 18446744073709551615ul>, 1024ul>::size() const
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char const, 18446744073709551615ul>, 1024ul>::size() const
346
  template <typename... ArgsT>
347
  void emplace_back_unchecked(ArgsT &&...Args) noexcept(
348
0
      std::is_nothrow_constructible_v<T, ArgsT...>) {
349
0
    assuming(Size < MaxSize);
350
0
    new (data() + Size) T(std::forward<ArgsT>(Args)...);
351
0
    ++Size;
352
0
  }
Unexecuted instantiation: wasifunc.cpp:void WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char, 18446744073709551615ul>, 1024ul>::emplace_back_unchecked<cxx20::span<unsigned char, 18446744073709551615ul> const&>(cxx20::span<unsigned char, 18446744073709551615ul> const&)
Unexecuted instantiation: wasifunc.cpp:void WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char const, 18446744073709551615ul>, 1024ul>::emplace_back_unchecked<cxx20::span<unsigned char const, 18446744073709551615ul> const&>(cxx20::span<unsigned char const, 18446744073709551615ul> const&)
Unexecuted instantiation: wasifunc.cpp:void WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char const, 18446744073709551615ul>, 1024ul>::emplace_back_unchecked<cxx20::span<unsigned char, 18446744073709551615ul> const&>(cxx20::span<unsigned char, 18446744073709551615ul> const&)
353
0
  ~StaticVector() noexcept(std::is_nothrow_destructible_v<T>) {
354
0
    std::destroy_n(data(), Size);
355
0
  }
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char, 18446744073709551615ul>, 1024ul>::~StaticVector()
Unexecuted instantiation: wasifunc.cpp:WasmEdge::Host::(anonymous namespace)::StaticVector<cxx20::span<unsigned char const, 18446744073709551615ul>, 1024ul>::~StaticVector()
356
357
private:
358
  size_t Size = 0;
359
  alignas(alignof(T)) uint8_t Storage[sizeof(T[MaxSize])];
360
};
361
362
bool AllowAFUNIX(const Runtime::CallingFrame &Frame,
363
0
                 __wasi_address_family_t AddressFamily) {
364
0
  if (AddressFamily == __WASI_ADDRESS_FAMILY_AF_UNIX) {
365
0
    return Frame.getExecutor()
366
0
        ->getConfigure()
367
0
        .getRuntimeConfigure()
368
0
        .isAllowAFUNIX();
369
0
  }
370
0
  return true;
371
0
}
372
} // namespace
373
374
Expect<uint32_t> WasiArgsGet::body(const Runtime::CallingFrame &Frame,
375
0
                                   uint32_t ArgvPtr, uint32_t ArgvBufPtr) {
376
  // Check memory instance from module.
377
0
  auto *MemInst = Frame.getMemoryByIndex(0);
378
0
  if (MemInst == nullptr) {
379
0
    return __WASI_ERRNO_FAULT;
380
0
  }
381
382
  // Store **Argv.
383
0
  const auto &Arguments = Env.getArguments();
384
0
  const uint32_t ArgvSize = static_cast<uint32_t>(Arguments.size());
385
0
  const uint32_t ArgvBufSize = calculateBufferSize(Arguments);
386
387
  // Check for invalid address.
388
0
  const auto Argv = MemInst->getSpan<uint8_t_ptr>(ArgvPtr, ArgvSize);
389
0
  if (unlikely(Argv.size() != ArgvSize)) {
390
0
    return __WASI_ERRNO_FAULT;
391
0
  }
392
0
  const auto ArgvBuf = MemInst->getSpan<uint8_t>(ArgvBufPtr, ArgvBufSize);
393
0
  if (unlikely(ArgvBuf.size() != ArgvBufSize)) {
394
0
    return __WASI_ERRNO_FAULT;
395
0
  }
396
397
0
  if (!Argv.empty()) {
398
0
    Argv[0] = ArgvBufPtr;
399
0
  }
400
401
0
  if (auto Res = Env.argsGet(Argv, ArgvBuf); unlikely(!Res)) {
402
0
    return Res.error();
403
0
  }
404
405
0
  return __WASI_ERRNO_SUCCESS;
406
0
}
407
408
Expect<uint32_t> WasiArgsSizesGet::body(const Runtime::CallingFrame &Frame,
409
                                        uint32_t /* Out */ ArgcPtr,
410
0
                                        uint32_t /* Out */ ArgvBufSizePtr) {
411
  // Check memory instance from module.
412
0
  auto *MemInst = Frame.getMemoryByIndex(0);
413
0
  if (MemInst == nullptr) {
414
0
    return __WASI_ERRNO_FAULT;
415
0
  }
416
417
  // Check for invalid address.
418
0
  auto *const __restrict__ Argc = MemInst->getPointer<__wasi_size_t *>(ArgcPtr);
419
0
  if (unlikely(Argc == nullptr)) {
420
0
    return __WASI_ERRNO_FAULT;
421
0
  }
422
0
  auto *const __restrict__ ArgvBufSize =
423
0
      MemInst->getPointer<__wasi_size_t *>(ArgvBufSizePtr);
424
0
  if (unlikely(ArgvBufSize == nullptr)) {
425
0
    return __WASI_ERRNO_FAULT;
426
0
  }
427
428
0
  if (auto Res = Env.argsSizesGet(*Argc, *ArgvBufSize); unlikely(!Res)) {
429
0
    return Res.error();
430
0
  }
431
0
  return __WASI_ERRNO_SUCCESS;
432
0
}
433
434
Expect<uint32_t> WasiEnvironGet::body(const Runtime::CallingFrame &Frame,
435
0
                                      uint32_t EnvPtr, uint32_t EnvBufPtr) {
436
  // Check memory instance from module.
437
0
  auto *MemInst = Frame.getMemoryByIndex(0);
438
0
  if (MemInst == nullptr) {
439
0
    return __WASI_ERRNO_FAULT;
440
0
  }
441
442
  // Store **Env.
443
0
  const auto &EnvironVariables = Env.getEnvironVariables();
444
0
  const uint32_t EnvSize = static_cast<uint32_t>(EnvironVariables.size());
445
0
  const uint32_t EnvBufSize = calculateBufferSize(EnvironVariables);
446
447
  // Check for invalid address.
448
0
  const auto EnvSpan = MemInst->getSpan<uint8_t_ptr>(EnvPtr, EnvSize);
449
0
  if (unlikely(EnvSpan.size() != EnvSize)) {
450
0
    return __WASI_ERRNO_FAULT;
451
0
  }
452
0
  const auto EnvBuf = MemInst->getSpan<uint8_t>(EnvBufPtr, EnvBufSize);
453
0
  if (unlikely(EnvBuf.size() != EnvBufSize)) {
454
0
    return __WASI_ERRNO_FAULT;
455
0
  }
456
457
0
  if (!EnvSpan.empty()) {
458
0
    EnvSpan[0] = EnvBufPtr;
459
0
  }
460
461
0
  if (auto Res = this->Env.environGet(EnvSpan, EnvBuf); unlikely(!Res)) {
462
0
    return Res.error();
463
0
  }
464
465
0
  return __WASI_ERRNO_SUCCESS;
466
0
}
467
468
Expect<uint32_t> WasiEnvironSizesGet::body(const Runtime::CallingFrame &Frame,
469
                                           uint32_t /* Out */ EnvCntPtr,
470
0
                                           uint32_t /* Out */ EnvBufSizePtr) {
471
  // Check memory instance from module.
472
0
  auto *MemInst = Frame.getMemoryByIndex(0);
473
0
  if (MemInst == nullptr) {
474
0
    return __WASI_ERRNO_FAULT;
475
0
  }
476
477
  // Check for invalid address.
478
0
  auto *const __restrict__ Envc =
479
0
      MemInst->getPointer<__wasi_size_t *>(EnvCntPtr);
480
0
  if (unlikely(Envc == nullptr)) {
481
0
    return __WASI_ERRNO_FAULT;
482
0
  }
483
0
  auto *const __restrict__ EnvBufSize =
484
0
      MemInst->getPointer<__wasi_size_t *>(EnvBufSizePtr);
485
0
  if (unlikely(EnvBufSize == nullptr)) {
486
0
    return __WASI_ERRNO_FAULT;
487
0
  }
488
489
0
  if (auto Res = Env.environSizesGet(*Envc, *EnvBufSize); unlikely(!Res)) {
490
0
    return Res.error();
491
0
  }
492
0
  return __WASI_ERRNO_SUCCESS;
493
0
}
494
495
Expect<uint32_t> WasiClockResGet::body(const Runtime::CallingFrame &Frame,
496
                                       uint32_t ClockId,
497
0
                                       uint32_t /* Out */ ResolutionPtr) {
498
  // Check memory instance from module.
499
0
  auto *MemInst = Frame.getMemoryByIndex(0);
500
0
  if (MemInst == nullptr) {
501
0
    return __WASI_ERRNO_FAULT;
502
0
  }
503
504
0
  auto *const Resolution =
505
0
      MemInst->getPointer<__wasi_timestamp_t *>(ResolutionPtr);
506
0
  if (unlikely(Resolution == nullptr)) {
507
0
    return __WASI_ERRNO_FAULT;
508
0
  }
509
510
0
  __wasi_clockid_t WasiClockId;
511
0
  if (auto Res = cast<__wasi_clockid_t>(ClockId); unlikely(!Res)) {
512
0
    return Res.error();
513
0
  } else {
514
0
    WasiClockId = *Res;
515
0
  }
516
517
0
  if (auto Res = Env.clockResGet(WasiClockId, *Resolution); unlikely(!Res)) {
518
0
    return Res.error();
519
0
  }
520
0
  return __WASI_ERRNO_SUCCESS;
521
0
}
522
523
Expect<uint32_t> WasiClockTimeGet::body(const Runtime::CallingFrame &Frame,
524
                                        uint32_t ClockId, uint64_t Precision,
525
0
                                        uint32_t /* Out */ TimePtr) {
526
  // Check memory instance from module.
527
0
  auto *MemInst = Frame.getMemoryByIndex(0);
528
0
  if (MemInst == nullptr) {
529
0
    return __WASI_ERRNO_FAULT;
530
0
  }
531
532
0
  auto *const Time = MemInst->getPointer<__wasi_timestamp_t *>(TimePtr);
533
0
  if (unlikely(Time == nullptr)) {
534
0
    return __WASI_ERRNO_FAULT;
535
0
  }
536
537
0
  __wasi_clockid_t WasiClockId;
538
0
  if (auto Res = cast<__wasi_clockid_t>(ClockId); unlikely(!Res)) {
539
0
    return Res.error();
540
0
  } else {
541
0
    WasiClockId = *Res;
542
0
  }
543
544
0
  const __wasi_timestamp_t WasiPrecision = Precision;
545
546
0
  if (auto Res = Env.clockTimeGet(WasiClockId, WasiPrecision, *Time);
547
0
      unlikely(!Res)) {
548
0
    return Res.error();
549
0
  }
550
0
  return __WASI_ERRNO_SUCCESS;
551
0
}
552
553
Expect<uint32_t> WasiFdAdvise::body(const Runtime::CallingFrame &, int32_t Fd,
554
                                    uint64_t Offset, uint64_t Len,
555
0
                                    uint32_t Advice) {
556
0
  __wasi_advice_t WasiAdvice;
557
0
  if (auto Res = cast<__wasi_advice_t>(Advice); unlikely(!Res)) {
558
0
    return Res.error();
559
0
  } else {
560
0
    WasiAdvice = *Res;
561
0
  }
562
563
0
  const __wasi_fd_t WasiFd = Fd;
564
0
  const __wasi_filesize_t WasiOffset = Offset;
565
0
  const __wasi_filesize_t WasiLen = Len;
566
567
0
  if (auto Res = Env.fdAdvise(WasiFd, WasiOffset, WasiLen, WasiAdvice);
568
0
      unlikely(!Res)) {
569
0
    return Res.error();
570
0
  }
571
0
  return __WASI_ERRNO_SUCCESS;
572
0
}
573
574
Expect<uint32_t> WasiFdAllocate::body(const Runtime::CallingFrame &, int32_t Fd,
575
0
                                      uint64_t Offset, uint64_t Len) {
576
0
  const __wasi_fd_t WasiFd = Fd;
577
0
  const __wasi_filesize_t WasiOffset = Offset;
578
0
  const __wasi_filesize_t WasiLen = Len;
579
580
0
  if (auto Res = Env.fdAllocate(WasiFd, WasiOffset, WasiLen); unlikely(!Res)) {
581
0
    return Res.error();
582
0
  }
583
0
  return __WASI_ERRNO_SUCCESS;
584
0
}
585
586
0
Expect<uint32_t> WasiFdClose::body(const Runtime::CallingFrame &, int32_t Fd) {
587
0
  const __wasi_fd_t WasiFd = Fd;
588
589
0
  if (auto Res = Env.fdClose(WasiFd); unlikely(!Res)) {
590
0
    return Res.error();
591
0
  }
592
0
  return __WASI_ERRNO_SUCCESS;
593
0
}
594
595
Expect<uint32_t> WasiFdDatasync::body(const Runtime::CallingFrame &,
596
0
                                      int32_t Fd) {
597
0
  const __wasi_fd_t WasiFd = Fd;
598
599
0
  if (auto Res = Env.fdDatasync(WasiFd); unlikely(!Res)) {
600
0
    return Res.error();
601
0
  }
602
0
  return __WASI_ERRNO_SUCCESS;
603
0
}
604
605
Expect<uint32_t> WasiFdFdstatGet::body(const Runtime::CallingFrame &Frame,
606
                                       int32_t Fd,
607
0
                                       uint32_t /* Out */ FdStatPtr) {
608
  // Check memory instance from module.
609
0
  auto *MemInst = Frame.getMemoryByIndex(0);
610
0
  if (MemInst == nullptr) {
611
0
    return __WASI_ERRNO_FAULT;
612
0
  }
613
614
0
  auto *const FdStat = MemInst->getPointer<__wasi_fdstat_t *>(FdStatPtr);
615
0
  if (unlikely(FdStat == nullptr)) {
616
0
    return __WASI_ERRNO_FAULT;
617
0
  }
618
619
0
  const __wasi_fd_t WasiFd = Fd;
620
621
0
  if (auto Res = Env.fdFdstatGet(WasiFd, *FdStat); unlikely(!Res)) {
622
0
    return Res.error();
623
0
  }
624
0
  return __WASI_ERRNO_SUCCESS;
625
0
}
626
627
Expect<uint32_t> WasiFdFdstatSetFlags::body(const Runtime::CallingFrame &,
628
0
                                            int32_t Fd, uint32_t FsFlags) {
629
0
  __wasi_fdflags_t WasiFdFlags;
630
0
  if (auto Res = cast<__wasi_fdflags_t>(FsFlags); unlikely(!Res)) {
631
0
    return Res.error();
632
0
  } else {
633
0
    WasiFdFlags = *Res;
634
0
  }
635
636
0
  const __wasi_fd_t WasiFd = Fd;
637
638
0
  if (auto Res = Env.fdFdstatSetFlags(WasiFd, WasiFdFlags); unlikely(!Res)) {
639
0
    return Res.error();
640
0
  }
641
0
  return __WASI_ERRNO_SUCCESS;
642
0
}
643
644
Expect<uint32_t> WasiFdFdstatSetRights::body(const Runtime::CallingFrame &,
645
                                             int32_t Fd, uint64_t FsRightsBase,
646
0
                                             uint64_t FsRightsInheriting) {
647
0
  __wasi_rights_t WasiFsRightsBase;
648
0
  if (auto Res = cast<__wasi_rights_t>(FsRightsBase); unlikely(!Res)) {
649
0
    return Res.error();
650
0
  } else {
651
0
    WasiFsRightsBase = *Res;
652
0
  }
653
654
0
  __wasi_rights_t WasiFsRightsInheriting;
655
0
  if (auto Res = cast<__wasi_rights_t>(FsRightsInheriting); unlikely(!Res)) {
656
0
    return Res.error();
657
0
  } else {
658
0
    WasiFsRightsInheriting = *Res;
659
0
  }
660
661
0
  const __wasi_fd_t WasiFd = Fd;
662
663
0
  if (auto Res = Env.fdFdstatSetRights(WasiFd, WasiFsRightsBase,
664
0
                                       WasiFsRightsInheriting);
665
0
      unlikely(!Res)) {
666
0
    return Res.error();
667
0
  }
668
0
  return __WASI_ERRNO_SUCCESS;
669
0
}
670
671
Expect<uint32_t> WasiFdFilestatGet::body(const Runtime::CallingFrame &Frame,
672
                                         int32_t Fd,
673
0
                                         uint32_t /* Out */ FilestatPtr) {
674
  // Check memory instance from module.
675
0
  auto *MemInst = Frame.getMemoryByIndex(0);
676
0
  if (MemInst == nullptr) {
677
0
    return __WASI_ERRNO_FAULT;
678
0
  }
679
680
0
  auto *const Filestat = MemInst->getPointer<__wasi_filestat_t *>(FilestatPtr);
681
0
  if (unlikely(Filestat == nullptr)) {
682
0
    return __WASI_ERRNO_FAULT;
683
0
  }
684
685
0
  const __wasi_fd_t WasiFd = Fd;
686
687
0
  if (auto Res = Env.fdFilestatGet(WasiFd, *Filestat); unlikely(!Res)) {
688
0
    return Res.error();
689
0
  }
690
0
  return __WASI_ERRNO_SUCCESS;
691
0
}
692
693
Expect<uint32_t> WasiFdFilestatSetSize::body(const Runtime::CallingFrame &,
694
0
                                             int32_t Fd, uint64_t Size) {
695
0
  const __wasi_fd_t WasiFd = Fd;
696
0
  const __wasi_filesize_t WasiSize = Size;
697
698
0
  if (auto Res = Env.fdFilestatSetSize(WasiFd, WasiSize); unlikely(!Res)) {
699
0
    return Res.error();
700
0
  }
701
0
  return __WASI_ERRNO_SUCCESS;
702
0
}
703
704
Expect<uint32_t> WasiFdFilestatSetTimes::body(const Runtime::CallingFrame &,
705
                                              int32_t Fd, uint64_t ATim,
706
                                              uint64_t MTim,
707
0
                                              uint32_t FstFlags) {
708
0
  __wasi_fstflags_t WasiFstFlags;
709
0
  if (auto Res = cast<__wasi_fstflags_t>(FstFlags); unlikely(!Res)) {
710
0
    return Res.error();
711
0
  } else {
712
0
    WasiFstFlags = *Res;
713
0
  }
714
715
0
  const __wasi_fd_t WasiFd = Fd;
716
0
  const __wasi_timestamp_t WasiATim = ATim;
717
0
  const __wasi_timestamp_t WasiMTim = MTim;
718
719
0
  if (auto Res =
720
0
          Env.fdFilestatSetTimes(WasiFd, WasiATim, WasiMTim, WasiFstFlags);
721
0
      unlikely(!Res)) {
722
0
    return Res.error();
723
0
  }
724
0
  return __WASI_ERRNO_SUCCESS;
725
0
}
726
727
Expect<uint32_t> WasiFdPread::body(const Runtime::CallingFrame &Frame,
728
                                   int32_t Fd, uint32_t IOVsPtr,
729
                                   uint32_t IOVsLen, uint64_t Offset,
730
0
                                   uint32_t /* Out */ NReadPtr) {
731
  // Check memory instance from module.
732
0
  auto *MemInst = Frame.getMemoryByIndex(0);
733
0
  if (MemInst == nullptr) {
734
0
    return __WASI_ERRNO_FAULT;
735
0
  }
736
737
0
  const __wasi_size_t WasiIOVsLen = IOVsLen;
738
0
  if (unlikely(WasiIOVsLen > WASI::kIOVMax)) {
739
0
    return __WASI_ERRNO_INVAL;
740
0
  }
741
742
  // Check for invalid address.
743
0
  const auto IOVsArray = MemInst->getSpan<__wasi_iovec_t>(IOVsPtr, WasiIOVsLen);
744
0
  if (unlikely(IOVsArray.size() != WasiIOVsLen)) {
745
0
    return __WASI_ERRNO_FAULT;
746
0
  }
747
748
0
  auto *const NRead = MemInst->getPointer<__wasi_size_t *>(NReadPtr);
749
0
  if (unlikely(NRead == nullptr)) {
750
0
    return __WASI_ERRNO_FAULT;
751
0
  }
752
753
0
  __wasi_size_t TotalSize = 0;
754
0
  StaticVector<Span<uint8_t>, WASI::kIOVMax> WasiIOVs;
755
756
0
  for (auto &IOV : IOVsArray) {
757
    // Capping total size.
758
0
    const __wasi_size_t Space =
759
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
760
0
    const __wasi_size_t BufLen =
761
0
        unlikely(IOV.buf_len > Space) ? Space : IOV.buf_len;
762
0
    TotalSize += BufLen;
763
764
    // Check for invalid address.
765
0
    const auto ReadArr = MemInst->getSpan<uint8_t>(IOV.buf, BufLen);
766
0
    if (unlikely(ReadArr.size() != BufLen)) {
767
0
      return __WASI_ERRNO_FAULT;
768
0
    }
769
0
    WasiIOVs.emplace_back_unchecked(ReadArr);
770
0
  }
771
772
0
  const __wasi_fd_t WasiFd = Fd;
773
0
  const __wasi_filesize_t WasiOffset = Offset;
774
775
0
  if (auto Res = Env.fdPread(WasiFd, WasiIOVs, WasiOffset, *NRead);
776
0
      unlikely(!Res)) {
777
0
    return Res.error();
778
0
  }
779
0
  return __WASI_ERRNO_SUCCESS;
780
0
}
781
782
Expect<uint32_t> WasiFdPrestatDirName::body(const Runtime::CallingFrame &Frame,
783
                                            int32_t Fd, uint32_t PathBufPtr,
784
0
                                            uint32_t PathLen) {
785
  // Check memory instance from module.
786
0
  auto *MemInst = Frame.getMemoryByIndex(0);
787
0
  if (MemInst == nullptr) {
788
0
    return __WASI_ERRNO_FAULT;
789
0
  }
790
791
0
  const auto PathBuf = MemInst->getSpan<uint8_t>(PathBufPtr, PathLen);
792
0
  if (unlikely(PathBuf.size() != PathLen)) {
793
0
    return __WASI_ERRNO_FAULT;
794
0
  }
795
796
0
  const __wasi_fd_t WasiFd = Fd;
797
798
0
  if (auto Res = Env.fdPrestatDirName(WasiFd, PathBuf); unlikely(!Res)) {
799
0
    return Res.error();
800
0
  }
801
0
  return __WASI_ERRNO_SUCCESS;
802
0
}
803
804
Expect<uint32_t> WasiFdPrestatGet::body(const Runtime::CallingFrame &Frame,
805
                                        int32_t Fd,
806
0
                                        uint32_t /* Out */ PreStatPtr) {
807
  // Check memory instance from module.
808
0
  auto *MemInst = Frame.getMemoryByIndex(0);
809
0
  if (MemInst == nullptr) {
810
0
    return __WASI_ERRNO_FAULT;
811
0
  }
812
813
0
  __wasi_prestat_t *const PreStat =
814
0
      MemInst->getPointer<__wasi_prestat_t *>(PreStatPtr);
815
0
  if (unlikely(PreStat == nullptr)) {
816
0
    return __WASI_ERRNO_FAULT;
817
0
  }
818
819
0
  const __wasi_fd_t WasiFd = Fd;
820
821
0
  if (auto Res = Env.fdPrestatGet(WasiFd, *PreStat); unlikely(!Res)) {
822
0
    return Res.error();
823
0
  }
824
0
  return __WASI_ERRNO_SUCCESS;
825
0
}
826
827
Expect<uint32_t> WasiFdPwrite::body(const Runtime::CallingFrame &Frame,
828
                                    int32_t Fd, uint32_t IOVsPtr,
829
                                    uint32_t IOVsLen, uint64_t Offset,
830
0
                                    uint32_t /* Out */ NWrittenPtr) {
831
  // Check memory instance from module.
832
0
  auto *MemInst = Frame.getMemoryByIndex(0);
833
0
  if (MemInst == nullptr) {
834
0
    return __WASI_ERRNO_FAULT;
835
0
  }
836
837
0
  const __wasi_size_t WasiIOVsLen = IOVsLen;
838
0
  if (unlikely(WasiIOVsLen > WASI::kIOVMax)) {
839
0
    return __WASI_ERRNO_INVAL;
840
0
  }
841
842
  // Check for invalid address.
843
0
  const auto IOVsArray =
844
0
      MemInst->getSpan<__wasi_ciovec_t>(IOVsPtr, WasiIOVsLen);
845
0
  if (unlikely(IOVsArray.size() != WasiIOVsLen)) {
846
0
    return __WASI_ERRNO_FAULT;
847
0
  }
848
849
  // Check for invalid address.
850
0
  auto *const NWritten = MemInst->getPointer<__wasi_size_t *>(NWrittenPtr);
851
0
  if (unlikely(NWritten == nullptr)) {
852
0
    return __WASI_ERRNO_FAULT;
853
0
  }
854
855
0
  __wasi_size_t TotalSize = 0;
856
0
  StaticVector<Span<const uint8_t>, WASI::kIOVMax> WasiIOVs;
857
858
0
  for (auto &IOV : IOVsArray) {
859
    // Capping total size.
860
0
    const __wasi_size_t Space =
861
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
862
0
    const __wasi_size_t BufLen =
863
0
        unlikely(IOV.buf_len > Space) ? Space : IOV.buf_len;
864
0
    TotalSize += BufLen;
865
866
    // Check for invalid address.
867
0
    const auto WriteArr = MemInst->getSpan<const uint8_t>(IOV.buf, BufLen);
868
0
    if (unlikely(WriteArr.size() != BufLen)) {
869
0
      return __WASI_ERRNO_FAULT;
870
0
    }
871
0
    WasiIOVs.emplace_back_unchecked(WriteArr);
872
0
  }
873
874
0
  const __wasi_fd_t WasiFd = Fd;
875
0
  const __wasi_filesize_t WasiOffset = Offset;
876
877
0
  if (auto Res = Env.fdPwrite(WasiFd, WasiIOVs, WasiOffset, *NWritten);
878
0
      unlikely(!Res)) {
879
0
    return Res.error();
880
0
  }
881
0
  return __WASI_ERRNO_SUCCESS;
882
0
}
883
884
Expect<uint32_t> WasiFdRead::body(const Runtime::CallingFrame &Frame,
885
                                  int32_t Fd, uint32_t IOVsPtr,
886
                                  uint32_t IOVsLen,
887
0
                                  uint32_t /* Out */ NReadPtr) {
888
  // Check memory instance from module.
889
0
  auto *MemInst = Frame.getMemoryByIndex(0);
890
0
  if (MemInst == nullptr) {
891
0
    return __WASI_ERRNO_FAULT;
892
0
  }
893
894
0
  const __wasi_size_t WasiIOVsLen = IOVsLen;
895
0
  if (unlikely(WasiIOVsLen > WASI::kIOVMax)) {
896
0
    return __WASI_ERRNO_INVAL;
897
0
  }
898
899
  // Check for invalid address.
900
0
  const auto IOVsArray = MemInst->getSpan<__wasi_iovec_t>(IOVsPtr, WasiIOVsLen);
901
0
  if (unlikely(IOVsArray.size() != WasiIOVsLen)) {
902
0
    return __WASI_ERRNO_FAULT;
903
0
  }
904
905
0
  auto *const NRead = MemInst->getPointer<__wasi_size_t *>(NReadPtr);
906
0
  if (unlikely(NRead == nullptr)) {
907
0
    return __WASI_ERRNO_FAULT;
908
0
  }
909
910
0
  __wasi_size_t TotalSize = 0;
911
0
  StaticVector<Span<uint8_t>, WASI::kIOVMax> WasiIOVs;
912
913
0
  for (auto &IOV : IOVsArray) {
914
    // Capping total size.
915
0
    const __wasi_size_t Space =
916
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
917
0
    const __wasi_size_t BufLen =
918
0
        unlikely(IOV.buf_len > Space) ? Space : IOV.buf_len;
919
0
    TotalSize += BufLen;
920
921
    // Check for invalid address.
922
0
    const auto ReadArr = MemInst->getSpan<uint8_t>(IOV.buf, BufLen);
923
0
    if (unlikely(ReadArr.size() != BufLen)) {
924
0
      return __WASI_ERRNO_FAULT;
925
0
    }
926
0
    WasiIOVs.emplace_back_unchecked(ReadArr);
927
0
  }
928
929
0
  const __wasi_fd_t WasiFd = Fd;
930
931
0
  if (auto Res = Env.fdRead(WasiFd, WasiIOVs, *NRead); unlikely(!Res)) {
932
0
    return Res.error();
933
0
  }
934
0
  return __WASI_ERRNO_SUCCESS;
935
0
}
936
937
Expect<uint32_t> WasiFdReadDir::body(const Runtime::CallingFrame &Frame,
938
                                     int32_t Fd, uint32_t BufPtr,
939
                                     uint32_t BufLen, uint64_t Cookie,
940
0
                                     uint32_t /* Out */ NReadPtr) {
941
  // Check memory instance from module.
942
0
  auto *MemInst = Frame.getMemoryByIndex(0);
943
0
  if (MemInst == nullptr) {
944
0
    return __WASI_ERRNO_FAULT;
945
0
  }
946
947
0
  const __wasi_size_t WasiBufLen = BufLen;
948
949
  // Check for invalid address.
950
0
  const auto Buf = MemInst->getSpan<uint8_t>(BufPtr, WasiBufLen);
951
0
  if (unlikely(Buf.size() != WasiBufLen)) {
952
0
    return __WASI_ERRNO_FAULT;
953
0
  }
954
955
0
  auto *const NRead = MemInst->getPointer<__wasi_size_t *>(NReadPtr);
956
0
  if (unlikely(NRead == nullptr)) {
957
0
    return __WASI_ERRNO_FAULT;
958
0
  }
959
960
0
  const __wasi_fd_t WasiFd = Fd;
961
0
  const __wasi_dircookie_t WasiCookie = Cookie;
962
963
0
  if (auto Res = Env.fdReaddir(WasiFd, Buf, WasiCookie, *NRead);
964
0
      unlikely(!Res)) {
965
0
    return Res.error();
966
0
  }
967
0
  return __WASI_ERRNO_SUCCESS;
968
0
}
969
970
Expect<uint32_t> WasiFdRenumber::body(const Runtime::CallingFrame &, int32_t Fd,
971
0
                                      int32_t ToFd) {
972
0
  const __wasi_fd_t WasiFd = Fd;
973
0
  const __wasi_fd_t WasiToFd = ToFd;
974
975
0
  if (auto Res = Env.fdRenumber(WasiFd, WasiToFd); unlikely(!Res)) {
976
0
    return Res.error();
977
0
  }
978
0
  return __WASI_ERRNO_SUCCESS;
979
0
}
980
981
Expect<int32_t> WasiFdSeek::body(const Runtime::CallingFrame &Frame, int32_t Fd,
982
                                 int64_t Offset, uint32_t Whence,
983
0
                                 uint32_t /* Out */ NewOffsetPtr) {
984
  // Check memory instance from module.
985
0
  auto *MemInst = Frame.getMemoryByIndex(0);
986
0
  if (MemInst == nullptr) {
987
0
    return __WASI_ERRNO_FAULT;
988
0
  }
989
990
0
  __wasi_whence_t WasiWhence;
991
0
  if (auto Res = cast<__wasi_whence_t>(Whence); unlikely(!Res)) {
992
0
    return Res.error();
993
0
  } else {
994
0
    WasiWhence = *Res;
995
0
  }
996
997
  // Check for invalid address.
998
0
  auto *NewOffset = MemInst->getPointer<__wasi_filesize_t *>(NewOffsetPtr);
999
0
  if (unlikely(NewOffset == nullptr)) {
1000
0
    return __WASI_ERRNO_FAULT;
1001
0
  }
1002
1003
0
  const __wasi_fd_t WasiFd = Fd;
1004
0
  const __wasi_filedelta_t WasiOffset = Offset;
1005
1006
0
  if (auto Res = Env.fdSeek(WasiFd, WasiOffset, WasiWhence, *NewOffset);
1007
0
      unlikely(!Res)) {
1008
0
    return Res.error();
1009
0
  }
1010
0
  return __WASI_ERRNO_SUCCESS;
1011
0
}
1012
1013
0
Expect<uint32_t> WasiFdSync::body(const Runtime::CallingFrame &, int32_t Fd) {
1014
0
  const __wasi_fd_t WasiFd = Fd;
1015
1016
0
  if (auto Res = Env.fdSync(WasiFd); unlikely(!Res)) {
1017
0
    return Res.error();
1018
0
  }
1019
0
  return __WASI_ERRNO_SUCCESS;
1020
0
}
1021
1022
Expect<uint32_t> WasiFdTell::body(const Runtime::CallingFrame &Frame,
1023
0
                                  int32_t Fd, uint32_t /* Out */ OffsetPtr) {
1024
  // Check memory instance from module.
1025
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1026
0
  if (MemInst == nullptr) {
1027
0
    return __WASI_ERRNO_FAULT;
1028
0
  }
1029
1030
  // Check for invalid address.
1031
0
  __wasi_filesize_t *Offset =
1032
0
      MemInst->getPointer<__wasi_filesize_t *>(OffsetPtr);
1033
0
  if (unlikely(Offset == nullptr)) {
1034
0
    return __WASI_ERRNO_FAULT;
1035
0
  }
1036
1037
0
  const __wasi_fd_t WasiFd = Fd;
1038
1039
0
  if (auto Res = Env.fdTell(WasiFd, *Offset); unlikely(!Res)) {
1040
0
    return Res.error();
1041
0
  }
1042
0
  return __WASI_ERRNO_SUCCESS;
1043
0
}
1044
1045
Expect<uint32_t> WasiFdWrite::body(const Runtime::CallingFrame &Frame,
1046
                                   int32_t Fd, uint32_t IOVsPtr,
1047
                                   uint32_t IOVsLen,
1048
0
                                   uint32_t /* Out */ NWrittenPtr) {
1049
  // Check memory instance from module.
1050
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1051
0
  if (MemInst == nullptr) {
1052
0
    return __WASI_ERRNO_FAULT;
1053
0
  }
1054
1055
0
  const __wasi_size_t WasiIOVsLen = IOVsLen;
1056
0
  if (unlikely(WasiIOVsLen > WASI::kIOVMax)) {
1057
0
    return __WASI_ERRNO_INVAL;
1058
0
  }
1059
1060
  // Check for invalid address.
1061
0
  const auto IOVsArray =
1062
0
      MemInst->getSpan<__wasi_ciovec_t>(IOVsPtr, WasiIOVsLen);
1063
0
  if (unlikely(IOVsArray.size() != WasiIOVsLen)) {
1064
0
    return __WASI_ERRNO_FAULT;
1065
0
  }
1066
1067
  // Check for invalid address.
1068
0
  auto *const NWritten = MemInst->getPointer<__wasi_size_t *>(NWrittenPtr);
1069
0
  if (unlikely(NWritten == nullptr)) {
1070
0
    return __WASI_ERRNO_FAULT;
1071
0
  }
1072
1073
0
  __wasi_size_t TotalSize = 0;
1074
0
  StaticVector<Span<const uint8_t>, WASI::kIOVMax> WasiIOVs;
1075
1076
0
  for (auto &IOV : IOVsArray) {
1077
    // Capping total size.
1078
0
    const __wasi_size_t Space =
1079
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
1080
0
    const __wasi_size_t BufLen =
1081
0
        unlikely(IOV.buf_len > Space) ? Space : IOV.buf_len;
1082
0
    TotalSize += BufLen;
1083
1084
    // Check for invalid address.
1085
0
    const auto WriteArr = MemInst->getSpan<const uint8_t>(IOV.buf, BufLen);
1086
0
    if (unlikely(WriteArr.size() != BufLen)) {
1087
0
      return __WASI_ERRNO_FAULT;
1088
0
    }
1089
0
    WasiIOVs.emplace_back_unchecked(WriteArr);
1090
0
  }
1091
1092
0
  const __wasi_fd_t WasiFd = Fd;
1093
1094
0
  if (auto Res = Env.fdWrite(WasiFd, WasiIOVs, *NWritten); unlikely(!Res)) {
1095
0
    return Res.error();
1096
0
  }
1097
0
  return __WASI_ERRNO_SUCCESS;
1098
0
}
1099
1100
Expect<uint32_t>
1101
WasiPathCreateDirectory::body(const Runtime::CallingFrame &Frame, int32_t Fd,
1102
0
                              uint32_t PathPtr, uint32_t PathLen) {
1103
  // Check memory instance from module.
1104
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1105
0
  if (MemInst == nullptr) {
1106
0
    return __WASI_ERRNO_FAULT;
1107
0
  }
1108
1109
0
  const __wasi_size_t WasiPathLen = PathLen;
1110
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1111
0
  if (unlikely(Path.size() != WasiPathLen)) {
1112
0
    return __WASI_ERRNO_FAULT;
1113
0
  }
1114
1115
0
  const __wasi_fd_t WasiFd = Fd;
1116
1117
0
  if (auto Res = Env.pathCreateDirectory(WasiFd, Path); unlikely(!Res)) {
1118
0
    return Res.error();
1119
0
  }
1120
0
  return __WASI_ERRNO_SUCCESS;
1121
0
}
1122
1123
Expect<uint32_t> WasiPathFilestatGet::body(const Runtime::CallingFrame &Frame,
1124
                                           int32_t Fd, uint32_t Flags,
1125
                                           uint32_t PathPtr, uint32_t PathLen,
1126
0
                                           uint32_t /* Out */ FilestatPtr) {
1127
  // Check memory instance from module.
1128
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1129
0
  if (MemInst == nullptr) {
1130
0
    return __WASI_ERRNO_FAULT;
1131
0
  }
1132
1133
0
  __wasi_lookupflags_t WasiFlags;
1134
0
  if (auto Res = cast<__wasi_lookupflags_t>(Flags); unlikely(!Res)) {
1135
0
    return Res.error();
1136
0
  } else {
1137
0
    WasiFlags = *Res;
1138
0
  }
1139
1140
0
  auto *const Filestat = MemInst->getPointer<__wasi_filestat_t *>(FilestatPtr);
1141
0
  if (unlikely(Filestat == nullptr)) {
1142
0
    return __WASI_ERRNO_FAULT;
1143
0
  }
1144
1145
0
  const __wasi_size_t WasiPathLen = PathLen;
1146
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1147
0
  if (unlikely(Path.size() != WasiPathLen)) {
1148
0
    return __WASI_ERRNO_FAULT;
1149
0
  }
1150
1151
0
  const __wasi_fd_t WasiFd = Fd;
1152
1153
0
  if (auto Res = Env.pathFilestatGet(WasiFd, Path, WasiFlags, *Filestat);
1154
0
      unlikely(!Res)) {
1155
0
    return Res.error();
1156
0
  }
1157
0
  return __WASI_ERRNO_SUCCESS;
1158
0
}
1159
1160
Expect<uint32_t>
1161
WasiPathFilestatSetTimes::body(const Runtime::CallingFrame &Frame, int32_t Fd,
1162
                               uint32_t Flags, uint32_t PathPtr,
1163
                               uint32_t PathLen, uint64_t ATim, uint64_t MTim,
1164
0
                               uint32_t FstFlags) {
1165
  // Check memory instance from module.
1166
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1167
0
  if (MemInst == nullptr) {
1168
0
    return __WASI_ERRNO_FAULT;
1169
0
  }
1170
1171
0
  __wasi_lookupflags_t WasiFlags;
1172
0
  if (auto Res = cast<__wasi_lookupflags_t>(Flags); unlikely(!Res)) {
1173
0
    return Res.error();
1174
0
  } else {
1175
0
    WasiFlags = *Res;
1176
0
  }
1177
1178
0
  __wasi_fstflags_t WasiFstFlags;
1179
0
  if (auto Res = cast<__wasi_fstflags_t>(FstFlags); unlikely(!Res)) {
1180
0
    return Res.error();
1181
0
  } else {
1182
0
    WasiFstFlags = *Res;
1183
0
  }
1184
1185
0
  const __wasi_size_t WasiPathLen = PathLen;
1186
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1187
0
  if (unlikely(Path.size() != WasiPathLen)) {
1188
0
    return __WASI_ERRNO_FAULT;
1189
0
  }
1190
1191
0
  const __wasi_fd_t WasiFd = Fd;
1192
0
  const __wasi_timestamp_t WasiATim = ATim;
1193
0
  const __wasi_timestamp_t WasiMTim = MTim;
1194
1195
0
  if (auto Res = Env.pathFilestatSetTimes(WasiFd, Path, WasiFlags, WasiATim,
1196
0
                                          WasiMTim, WasiFstFlags);
1197
0
      unlikely(!Res)) {
1198
0
    return Res.error();
1199
0
  }
1200
0
  return __WASI_ERRNO_SUCCESS;
1201
0
}
1202
1203
Expect<uint32_t> WasiPathLink::body(const Runtime::CallingFrame &Frame,
1204
                                    int32_t OldFd, uint32_t OldFlags,
1205
                                    uint32_t OldPathPtr, uint32_t OldPathLen,
1206
                                    int32_t NewFd, uint32_t NewPathPtr,
1207
0
                                    uint32_t NewPathLen) {
1208
  // Check memory instance from module.
1209
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1210
0
  if (MemInst == nullptr) {
1211
0
    return __WASI_ERRNO_FAULT;
1212
0
  }
1213
1214
0
  __wasi_lookupflags_t WasiOldFlags;
1215
0
  if (auto Res = cast<__wasi_lookupflags_t>(OldFlags); unlikely(!Res)) {
1216
0
    return Res.error();
1217
0
  } else {
1218
0
    WasiOldFlags = *Res;
1219
0
  }
1220
1221
0
  const __wasi_size_t WasiOldPathLen = OldPathLen;
1222
0
  const auto OldPath = MemInst->getStringView(OldPathPtr, WasiOldPathLen);
1223
0
  if (unlikely(OldPath.size() != WasiOldPathLen)) {
1224
0
    return __WASI_ERRNO_FAULT;
1225
0
  }
1226
1227
0
  const __wasi_size_t WasiNewPathLen = NewPathLen;
1228
0
  const auto NewPath = MemInst->getStringView(NewPathPtr, WasiNewPathLen);
1229
0
  if (unlikely(NewPath.size() != WasiNewPathLen)) {
1230
0
    return __WASI_ERRNO_FAULT;
1231
0
  }
1232
1233
0
  const __wasi_fd_t WasiOldFd = OldFd;
1234
0
  const __wasi_fd_t WasinewFd = NewFd;
1235
1236
0
  if (auto Res =
1237
0
          Env.pathLink(WasiOldFd, OldPath, WasinewFd, NewPath, WasiOldFlags);
1238
0
      unlikely(!Res)) {
1239
0
    return Res.error();
1240
0
  }
1241
0
  return __WASI_ERRNO_SUCCESS;
1242
0
}
1243
1244
Expect<uint32_t> WasiPathOpen::body(
1245
    const Runtime::CallingFrame &Frame, int32_t DirFd, uint32_t DirFlags,
1246
    uint32_t PathPtr, uint32_t PathLen, uint32_t OFlags, uint64_t FsRightsBase,
1247
0
    uint64_t FsRightsInheriting, uint32_t FsFlags, uint32_t /* Out */ FdPtr) {
1248
  // Check memory instance from module.
1249
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1250
0
  if (MemInst == nullptr) {
1251
0
    return __WASI_ERRNO_FAULT;
1252
0
  }
1253
1254
0
  __wasi_lookupflags_t WasiDirFlags;
1255
0
  if (auto Res = cast<__wasi_lookupflags_t>(DirFlags); unlikely(!Res)) {
1256
0
    return Res.error();
1257
0
  } else {
1258
0
    WasiDirFlags = *Res;
1259
0
  }
1260
1261
0
  __wasi_oflags_t WasiOFlags;
1262
0
  if (auto Res = cast<__wasi_oflags_t>(OFlags); unlikely(!Res)) {
1263
0
    return Res.error();
1264
0
  } else {
1265
0
    WasiOFlags = *Res;
1266
0
  }
1267
1268
0
  __wasi_rights_t WasiFsRightsBase;
1269
0
  if (auto Res = cast<__wasi_rights_t>(FsRightsBase); unlikely(!Res)) {
1270
0
    return Res.error();
1271
0
  } else {
1272
0
    WasiFsRightsBase = *Res;
1273
0
  }
1274
1275
0
  __wasi_rights_t WasiFsRightsInheriting;
1276
0
  if (auto Res = cast<__wasi_rights_t>(FsRightsInheriting); unlikely(!Res)) {
1277
0
    return Res.error();
1278
0
  } else {
1279
0
    WasiFsRightsInheriting = *Res;
1280
0
  }
1281
1282
0
  __wasi_fdflags_t WasiFsFlags;
1283
0
  if (auto Res = cast<__wasi_fdflags_t>(FsFlags); unlikely(!Res)) {
1284
0
    return Res.error();
1285
0
  } else {
1286
0
    WasiFsFlags = *Res;
1287
0
  }
1288
1289
0
  const __wasi_size_t WasiPathLen = PathLen;
1290
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1291
0
  if (unlikely(Path.size() != WasiPathLen)) {
1292
0
    return __WASI_ERRNO_FAULT;
1293
0
  }
1294
1295
0
  auto *const Fd = MemInst->getPointer<__wasi_fd_t *>(FdPtr);
1296
0
  if (unlikely(Fd == nullptr)) {
1297
0
    return __WASI_ERRNO_FAULT;
1298
0
  }
1299
1300
  // Open directory and read/write rights should fail with isdir
1301
0
  if ((WasiOFlags & __WASI_OFLAGS_DIRECTORY) &&
1302
0
      (WasiFsRightsBase & __WASI_RIGHTS_FD_READ) &&
1303
0
      (WasiFsRightsBase & __WASI_RIGHTS_FD_WRITE)) {
1304
0
    return __WASI_ERRNO_ISDIR;
1305
0
  }
1306
1307
0
  const __wasi_fd_t WasiDirFd = DirFd;
1308
1309
0
  if (auto Res =
1310
0
          Env.pathOpen(WasiDirFd, Path, WasiDirFlags, WasiOFlags,
1311
0
                       WasiFsRightsBase, WasiFsRightsInheriting, WasiFsFlags);
1312
0
      unlikely(!Res)) {
1313
0
    return Res.error();
1314
0
  } else {
1315
0
    *Fd = *Res;
1316
0
  }
1317
0
  return __WASI_ERRNO_SUCCESS;
1318
0
}
1319
1320
Expect<uint32_t> WasiPathReadLink::body(const Runtime::CallingFrame &Frame,
1321
                                        int32_t Fd, uint32_t PathPtr,
1322
                                        uint32_t PathLen, uint32_t BufPtr,
1323
                                        uint32_t BufLen,
1324
0
                                        uint32_t /* Out */ NReadPtr) {
1325
  // Check memory instance from module.
1326
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1327
0
  if (MemInst == nullptr) {
1328
0
    return __WASI_ERRNO_FAULT;
1329
0
  }
1330
1331
0
  const __wasi_size_t WasiPathLen = PathLen;
1332
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1333
0
  if (unlikely(Path.size() != WasiPathLen)) {
1334
0
    return __WASI_ERRNO_FAULT;
1335
0
  }
1336
1337
0
  const __wasi_size_t WasiBufLen = BufLen;
1338
1339
0
  const auto Buf = MemInst->getSpan<char>(BufPtr, WasiBufLen);
1340
0
  if (unlikely(Buf.size() != WasiBufLen)) {
1341
0
    return __WASI_ERRNO_FAULT;
1342
0
  }
1343
1344
0
  auto *const NRead = MemInst->getPointer<__wasi_size_t *>(NReadPtr);
1345
0
  if (unlikely(NRead == nullptr)) {
1346
0
    return __WASI_ERRNO_FAULT;
1347
0
  }
1348
1349
0
  const __wasi_fd_t WasiFd = Fd;
1350
1351
0
  if (auto Res = Env.pathReadlink(WasiFd, Path, Buf, *NRead); unlikely(!Res)) {
1352
0
    return Res.error();
1353
0
  }
1354
0
  return __WASI_ERRNO_SUCCESS;
1355
0
}
1356
1357
Expect<uint32_t>
1358
WasiPathRemoveDirectory::body(const Runtime::CallingFrame &Frame, int32_t Fd,
1359
0
                              uint32_t PathPtr, uint32_t PathLen) {
1360
  // Check memory instance from module.
1361
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1362
0
  if (MemInst == nullptr) {
1363
0
    return __WASI_ERRNO_FAULT;
1364
0
  }
1365
1366
0
  const __wasi_size_t WasiPathLen = PathLen;
1367
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1368
0
  if (unlikely(Path.size() != WasiPathLen)) {
1369
0
    return __WASI_ERRNO_FAULT;
1370
0
  }
1371
1372
0
  const __wasi_fd_t WasiFd = Fd;
1373
1374
0
  if (auto Res = Env.pathRemoveDirectory(WasiFd, Path); unlikely(!Res)) {
1375
0
    return Res.error();
1376
0
  }
1377
0
  return __WASI_ERRNO_SUCCESS;
1378
0
}
1379
1380
Expect<uint32_t> WasiPathRename::body(const Runtime::CallingFrame &Frame,
1381
                                      int32_t Fd, uint32_t OldPathPtr,
1382
                                      uint32_t OldPathLen, int32_t NewFd,
1383
                                      uint32_t NewPathPtr,
1384
0
                                      uint32_t NewPathLen) {
1385
  // Check memory instance from module.
1386
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1387
0
  if (MemInst == nullptr) {
1388
0
    return __WASI_ERRNO_FAULT;
1389
0
  }
1390
1391
0
  const __wasi_size_t WasiOldPathLen = OldPathLen;
1392
0
  const auto OldPath = MemInst->getStringView(OldPathPtr, WasiOldPathLen);
1393
0
  if (unlikely(OldPath.size() != WasiOldPathLen)) {
1394
0
    return __WASI_ERRNO_FAULT;
1395
0
  }
1396
1397
0
  const __wasi_size_t WasiNewPathLen = NewPathLen;
1398
0
  const auto NewPath = MemInst->getStringView(NewPathPtr, WasiNewPathLen);
1399
0
  if (unlikely(NewPath.size() != WasiNewPathLen)) {
1400
0
    return __WASI_ERRNO_FAULT;
1401
0
  }
1402
1403
0
  const __wasi_fd_t WasiFd = Fd;
1404
0
  const __wasi_fd_t WasiNewFd = NewFd;
1405
1406
0
  if (auto Res = Env.pathRename(WasiFd, OldPath, WasiNewFd, NewPath);
1407
0
      unlikely(!Res)) {
1408
0
    return Res.error();
1409
0
  }
1410
0
  return __WASI_ERRNO_SUCCESS;
1411
0
}
1412
1413
Expect<uint32_t> WasiPathSymlink::body(const Runtime::CallingFrame &Frame,
1414
                                       uint32_t OldPathPtr, uint32_t OldPathLen,
1415
                                       int32_t Fd, uint32_t NewPathPtr,
1416
0
                                       uint32_t NewPathLen) {
1417
  // Check memory instance from module.
1418
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1419
0
  if (MemInst == nullptr) {
1420
0
    return __WASI_ERRNO_FAULT;
1421
0
  }
1422
1423
0
  const __wasi_size_t WasiOldPathLen = OldPathLen;
1424
0
  const auto OldPath = MemInst->getStringView(OldPathPtr, WasiOldPathLen);
1425
0
  if (unlikely(OldPath.size() != WasiOldPathLen)) {
1426
0
    return __WASI_ERRNO_FAULT;
1427
0
  }
1428
1429
0
  const __wasi_size_t WasiNewPathLen = NewPathLen;
1430
0
  const auto NewPath = MemInst->getStringView(NewPathPtr, WasiNewPathLen);
1431
0
  if (unlikely(NewPath.size() != WasiNewPathLen)) {
1432
0
    return __WASI_ERRNO_FAULT;
1433
0
  }
1434
1435
0
  if (OldPath.empty() || NewPath.empty()) {
1436
0
    return __WASI_ERRNO_NOENT;
1437
0
  }
1438
1439
0
  const __wasi_fd_t WasiFd = Fd;
1440
1441
0
  if (auto Res = Env.pathSymlink(OldPath, WasiFd, NewPath); unlikely(!Res)) {
1442
0
    return Res.error();
1443
0
  }
1444
0
  return __WASI_ERRNO_SUCCESS;
1445
0
}
1446
1447
Expect<uint32_t> WasiPathUnlinkFile::body(const Runtime::CallingFrame &Frame,
1448
                                          int32_t Fd, uint32_t PathPtr,
1449
0
                                          uint32_t PathLen) {
1450
  // Check memory instance from module.
1451
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1452
0
  if (MemInst == nullptr) {
1453
0
    return __WASI_ERRNO_FAULT;
1454
0
  }
1455
1456
0
  const __wasi_size_t WasiPathLen = PathLen;
1457
0
  const auto Path = MemInst->getStringView(PathPtr, WasiPathLen);
1458
0
  if (unlikely(Path.size() != WasiPathLen)) {
1459
0
    return __WASI_ERRNO_FAULT;
1460
0
  }
1461
1462
0
  const __wasi_fd_t WasiFd = Fd;
1463
1464
0
  if (auto Res = Env.pathUnlinkFile(WasiFd, Path); unlikely(!Res)) {
1465
0
    return Res.error();
1466
0
  }
1467
0
  return __WASI_ERRNO_SUCCESS;
1468
0
}
1469
template <WASI::TriggerType Trigger>
1470
Expect<uint32_t> WasiPollOneoff<Trigger>::body(
1471
    const Runtime::CallingFrame &Frame, uint32_t InPtr, uint32_t OutPtr,
1472
0
    uint32_t NSubscriptions, uint32_t /* Out */ NEventsPtr) {
1473
  // Check memory instance from module.
1474
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1475
0
  if (MemInst == nullptr) {
1476
0
    return __WASI_ERRNO_FAULT;
1477
0
  }
1478
1479
0
  const __wasi_size_t WasiNSub = NSubscriptions;
1480
1481
0
  const auto Subs =
1482
0
      MemInst->getSpan<const __wasi_subscription_t>(InPtr, WasiNSub);
1483
0
  if (unlikely(Subs.size() != WasiNSub)) {
1484
0
    return __WASI_ERRNO_FAULT;
1485
0
  }
1486
1487
0
  const auto Events = MemInst->getSpan<__wasi_event_t>(OutPtr, WasiNSub);
1488
0
  if (unlikely(Events.size() != WasiNSub)) {
1489
0
    return __WASI_ERRNO_FAULT;
1490
0
  }
1491
1492
0
  auto *const NEvents = MemInst->getPointer<__wasi_size_t *>(NEventsPtr);
1493
0
  if (unlikely(NEvents == nullptr)) {
1494
0
    return __WASI_ERRNO_FAULT;
1495
0
  }
1496
1497
  // Validate contents
1498
0
  if (auto Poll = this->Env.acquirePoller(Events); unlikely(!Poll)) {
1499
0
    for (__wasi_size_t I = 0; I < WasiNSub; ++I) {
1500
0
      Events[I].userdata = Subs[I].userdata;
1501
0
      Events[I].error = Poll.error();
1502
0
      Events[I].type = Subs[I].u.tag;
1503
0
    }
1504
0
    *NEvents = WasiNSub;
1505
0
    return Poll.error();
1506
0
  } else {
1507
0
    auto &Poller = *Poll;
1508
0
    for (auto &Sub : Subs) {
1509
0
      const __wasi_userdata_t WasiUserData = Sub.userdata;
1510
1511
0
      __wasi_eventtype_t Type;
1512
0
      if (auto Res = cast<__wasi_eventtype_t>(Sub.u.tag); unlikely(!Res)) {
1513
0
        Poller.error(WasiUserData, Res.error(), Sub.u.tag);
1514
0
        continue;
1515
0
      } else {
1516
0
        Type = *Res;
1517
0
      }
1518
1519
0
      switch (Type) {
1520
0
      case __WASI_EVENTTYPE_CLOCK: {
1521
0
        __wasi_clockid_t WasiClockId;
1522
0
        if (auto Res = cast<__wasi_clockid_t>(Sub.u.u.clock.id);
1523
0
            unlikely(!Res)) {
1524
0
          Poller.error(WasiUserData, Res.error(), Type);
1525
0
          continue;
1526
0
        } else {
1527
0
          WasiClockId = *Res;
1528
0
        }
1529
1530
0
        __wasi_subclockflags_t WasiFlags;
1531
0
        if (auto Res = cast<__wasi_subclockflags_t>(Sub.u.u.clock.flags);
1532
0
            unlikely(!Res)) {
1533
0
          Poller.error(WasiUserData, Res.error(), Type);
1534
0
          continue;
1535
0
        } else {
1536
0
          WasiFlags = *Res;
1537
0
        }
1538
1539
0
        const __wasi_timestamp_t WasiTimeout = Sub.u.u.clock.timeout;
1540
0
        const __wasi_timestamp_t WasiPrecision = Sub.u.u.clock.precision;
1541
1542
0
        Poller.clock(WasiClockId, WasiTimeout, WasiPrecision, WasiFlags,
1543
0
                     WasiUserData);
1544
0
        continue;
1545
0
      }
1546
0
      case __WASI_EVENTTYPE_FD_READ: {
1547
0
        const __wasi_fd_t WasiFd = Sub.u.u.fd_read.file_descriptor;
1548
0
        Poller.read(WasiFd, Trigger, WasiUserData);
1549
0
        continue;
1550
0
      }
1551
0
      case __WASI_EVENTTYPE_FD_WRITE: {
1552
0
        const __wasi_fd_t WasiFd = Sub.u.u.fd_write.file_descriptor;
1553
0
        Poller.write(WasiFd, Trigger, WasiUserData);
1554
0
        continue;
1555
0
      }
1556
0
      default:
1557
0
        assumingUnreachable();
1558
0
      }
1559
0
    }
1560
0
    Poller.wait();
1561
0
    *NEvents = Poller.result();
1562
0
    Poller.reset();
1563
0
    this->Env.releasePoller(std::move(Poller));
1564
0
  }
1565
1566
0
  return __WASI_ERRNO_SUCCESS;
1567
0
}
Unexecuted instantiation: WasmEdge::Host::WasiPollOneoff<(WasmEdge::Host::WASI::TriggerType)0>::body(WasmEdge::Runtime::CallingFrame const&, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: WasmEdge::Host::WasiPollOneoff<(WasmEdge::Host::WASI::TriggerType)1>::body(WasmEdge::Runtime::CallingFrame const&, unsigned int, unsigned int, unsigned int, unsigned int)
1568
1569
template class WasiPollOneoff<WASI::TriggerType::Level>;
1570
template class WasiPollOneoff<WASI::TriggerType::Edge>;
1571
1572
Expect<void> WasiProcExit::body(const Runtime::CallingFrame &,
1573
0
                                uint32_t ExitCode) {
1574
0
  Env.procExit(ExitCode);
1575
0
  return Unexpect(ErrCode::Value::Terminated);
1576
0
}
1577
1578
Expect<uint32_t> WasiProcRaise::body(const Runtime::CallingFrame &,
1579
0
                                     uint32_t Signal) {
1580
0
  __wasi_signal_t WasiSignal;
1581
0
  if (auto Res = cast<__wasi_signal_t>(Signal); unlikely(!Res)) {
1582
0
    return Res.error();
1583
0
  } else {
1584
0
    WasiSignal = *Res;
1585
0
  }
1586
1587
0
  if (auto Res = Env.procRaise(WasiSignal); unlikely(!Res)) {
1588
0
    return Res.error();
1589
0
  }
1590
0
  return __WASI_ERRNO_SUCCESS;
1591
0
}
1592
1593
0
Expect<uint32_t> WasiSchedYield::body(const Runtime::CallingFrame &) {
1594
0
  if (auto Res = Env.schedYield(); unlikely(!Res)) {
1595
0
    return Res.error();
1596
0
  }
1597
0
  return __WASI_ERRNO_SUCCESS;
1598
0
}
1599
1600
Expect<uint32_t> WasiRandomGet::body(const Runtime::CallingFrame &Frame,
1601
0
                                     uint32_t BufPtr, uint32_t BufLen) {
1602
  // Check memory instance from module.
1603
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1604
0
  if (MemInst == nullptr) {
1605
0
    return __WASI_ERRNO_FAULT;
1606
0
  }
1607
1608
0
  const __wasi_size_t WasiBufLen = BufLen;
1609
1610
0
  const auto Buf = MemInst->getSpan<uint8_t>(BufPtr, WasiBufLen);
1611
0
  if (unlikely(Buf.size() != WasiBufLen)) {
1612
0
    return __WASI_ERRNO_FAULT;
1613
0
  }
1614
1615
0
  if (auto Res = Env.randomGet(Buf); unlikely(!Res)) {
1616
0
    return Res.error();
1617
0
  }
1618
0
  return __WASI_ERRNO_SUCCESS;
1619
0
}
1620
1621
Expect<uint32_t> WasiSockOpenV1::body(const Runtime::CallingFrame &Frame,
1622
                                      uint32_t AddressFamily, uint32_t SockType,
1623
0
                                      uint32_t /* Out */ RoFdPtr) {
1624
  // Check memory instance from module.
1625
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1626
0
  if (MemInst == nullptr) {
1627
0
    return __WASI_ERRNO_FAULT;
1628
0
  }
1629
1630
0
  __wasi_fd_t *const RoFd = MemInst->getPointer<__wasi_fd_t *>(RoFdPtr);
1631
0
  if (RoFd == nullptr) {
1632
0
    return __WASI_ERRNO_FAULT;
1633
0
  }
1634
1635
0
  __wasi_address_family_t WasiAddressFamily;
1636
0
  if (auto Res = cast<__wasi_address_family_t>(AddressFamily); unlikely(!Res)) {
1637
0
    return Res.error();
1638
0
  } else {
1639
0
    WasiAddressFamily = *Res;
1640
0
  }
1641
1642
0
  if (!AllowAFUNIX(Frame, WasiAddressFamily)) {
1643
0
    return __WASI_ERRNO_NOSYS;
1644
0
  }
1645
1646
0
  __wasi_sock_type_t WasiSockType;
1647
0
  if (auto Res = cast<__wasi_sock_type_t>(SockType); unlikely(!Res)) {
1648
0
    return Res.error();
1649
0
  } else {
1650
0
    WasiSockType = *Res;
1651
0
  }
1652
1653
0
  if (auto Res = Env.sockOpen(WasiAddressFamily, WasiSockType);
1654
0
      unlikely(!Res)) {
1655
0
    return Res.error();
1656
0
  } else {
1657
0
    *RoFd = *Res;
1658
0
  }
1659
1660
0
  return __WASI_ERRNO_SUCCESS;
1661
0
}
1662
1663
Expect<uint32_t> WasiSockBindV1::body(const Runtime::CallingFrame &Frame,
1664
                                      int32_t Fd, uint32_t AddressPtr,
1665
0
                                      uint32_t Port) {
1666
  // Check memory instance from module.
1667
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1668
0
  if (MemInst == nullptr) {
1669
0
    return __WASI_ERRNO_FAULT;
1670
0
  }
1671
0
  __wasi_address_t *InnerAddress =
1672
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
1673
0
  if (InnerAddress == nullptr) {
1674
0
    return __WASI_ERRNO_FAULT;
1675
0
  }
1676
1677
0
  const auto Address =
1678
0
      MemInst->getSpan<const uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
1679
0
  if (Address.size() != InnerAddress->buf_len) {
1680
0
    return __WASI_ERRNO_FAULT;
1681
0
  }
1682
1683
0
  __wasi_address_family_t WasiAddressFamily;
1684
0
  switch (Address.size()) {
1685
0
  case 4:
1686
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET4;
1687
0
    break;
1688
0
  case 16:
1689
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET6;
1690
0
    break;
1691
0
  default:
1692
0
    return __WASI_ERRNO_INVAL;
1693
0
  }
1694
1695
0
  const __wasi_fd_t WasiFd = Fd;
1696
1697
0
  if (auto Res = Env.sockBind(WasiFd, WasiAddressFamily, Address,
1698
0
                              static_cast<uint16_t>(Port));
1699
0
      unlikely(!Res)) {
1700
0
    return Res.error();
1701
0
  }
1702
0
  return __WASI_ERRNO_SUCCESS;
1703
0
}
1704
1705
Expect<uint32_t> WasiSockListenV1::body(const Runtime::CallingFrame &,
1706
0
                                        int32_t Fd, int32_t Backlog) {
1707
0
  const __wasi_fd_t WasiFd = Fd;
1708
0
  if (auto Res = Env.sockListen(WasiFd, Backlog); unlikely(!Res)) {
1709
0
    return Res.error();
1710
0
  }
1711
0
  return __WASI_ERRNO_SUCCESS;
1712
0
}
1713
1714
Expect<uint32_t> WasiSockAcceptV1::body(const Runtime::CallingFrame &Frame,
1715
                                        int32_t Fd,
1716
0
                                        uint32_t /* Out */ RoFdPtr) {
1717
  // Check memory instance from module.
1718
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1719
0
  if (MemInst == nullptr) {
1720
0
    return __WASI_ERRNO_FAULT;
1721
0
  }
1722
0
  __wasi_fd_t *const RoFd = MemInst->getPointer<__wasi_fd_t *>(RoFdPtr);
1723
0
  if (RoFd == nullptr) {
1724
0
    return __WASI_ERRNO_FAULT;
1725
0
  }
1726
0
  const __wasi_fd_t WasiFd = Fd;
1727
0
  const __wasi_fdflags_t WasiFdFlags = static_cast<__wasi_fdflags_t>(0);
1728
0
  if (auto Res = Env.sockAccept(WasiFd, WasiFdFlags); unlikely(!Res)) {
1729
0
    return Res.error();
1730
0
  } else {
1731
0
    *RoFd = *Res;
1732
0
  }
1733
1734
0
  return __WASI_ERRNO_SUCCESS;
1735
0
}
1736
1737
Expect<uint32_t> WasiSockAcceptV2::body(const Runtime::CallingFrame &Frame,
1738
                                        int32_t Fd, uint32_t FsFlags,
1739
0
                                        uint32_t /* Out */ RoFdPtr) {
1740
  // Check memory instance from module.
1741
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1742
0
  if (MemInst == nullptr) {
1743
0
    return __WASI_ERRNO_FAULT;
1744
0
  }
1745
0
  __wasi_fd_t *const RoFd = MemInst->getPointer<__wasi_fd_t *>(RoFdPtr);
1746
0
  if (RoFd == nullptr) {
1747
0
    return __WASI_ERRNO_FAULT;
1748
0
  }
1749
0
  const __wasi_fd_t WasiFd = Fd;
1750
1751
0
  __wasi_fdflags_t WasiFdFlags;
1752
0
  if (auto Res = cast<__wasi_fdflags_t>(FsFlags); unlikely(!Res)) {
1753
0
    return Res.error();
1754
0
  } else {
1755
0
    WasiFdFlags = *Res;
1756
0
  }
1757
1758
0
  if (auto Res = Env.sockAccept(WasiFd, WasiFdFlags); unlikely(!Res)) {
1759
0
    return Res.error();
1760
0
  } else {
1761
0
    *RoFd = *Res;
1762
0
  }
1763
1764
0
  return __WASI_ERRNO_SUCCESS;
1765
0
}
1766
1767
Expect<uint32_t> WasiSockConnectV1::body(const Runtime::CallingFrame &Frame,
1768
                                         int32_t Fd, uint32_t AddressPtr,
1769
0
                                         uint32_t Port) {
1770
  // Check memory instance from module.
1771
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1772
0
  if (MemInst == nullptr) {
1773
0
    return __WASI_ERRNO_FAULT;
1774
0
  }
1775
0
  __wasi_address_t *InnerAddress =
1776
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
1777
0
  if (InnerAddress == nullptr) {
1778
0
    return __WASI_ERRNO_FAULT;
1779
0
  }
1780
1781
0
  const auto Address =
1782
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
1783
0
  if (Address.size() != InnerAddress->buf_len) {
1784
0
    return __WASI_ERRNO_FAULT;
1785
0
  }
1786
1787
0
  __wasi_address_family_t WasiAddressFamily;
1788
0
  switch (Address.size()) {
1789
0
  case 4:
1790
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET4;
1791
0
    break;
1792
0
  case 16:
1793
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET6;
1794
0
    break;
1795
0
  default:
1796
0
    return __WASI_ERRNO_INVAL;
1797
0
  }
1798
1799
0
  const __wasi_fd_t WasiFd = Fd;
1800
0
  if (auto Res = Env.sockConnect(WasiFd, WasiAddressFamily, Address,
1801
0
                                 static_cast<uint16_t>(Port));
1802
0
      unlikely(!Res)) {
1803
0
    return Res.error();
1804
0
  }
1805
1806
0
  return __WASI_ERRNO_SUCCESS;
1807
0
}
1808
1809
Expect<uint32_t> WasiSockRecvV1::body(const Runtime::CallingFrame &Frame,
1810
                                      int32_t Fd, uint32_t RiDataPtr,
1811
                                      uint32_t RiDataLen, uint32_t RiFlags,
1812
                                      uint32_t /* Out */ RoDataLenPtr,
1813
0
                                      uint32_t /* Out */ RoFlagsPtr) {
1814
  // Check memory instance from module.
1815
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1816
0
  if (MemInst == nullptr) {
1817
0
    return __WASI_ERRNO_FAULT;
1818
0
  }
1819
1820
0
  __wasi_riflags_t WasiRiFlags;
1821
0
  if (auto Res = cast<__wasi_riflags_t>(RiFlags); unlikely(!Res)) {
1822
0
    return Res.error();
1823
0
  } else {
1824
0
    WasiRiFlags = *Res;
1825
0
  }
1826
1827
0
  const __wasi_size_t WasiRiDataLen = RiDataLen;
1828
0
  if (unlikely(WasiRiDataLen > WASI::kIOVMax)) {
1829
0
    return __WASI_ERRNO_INVAL;
1830
0
  }
1831
1832
  // Check for invalid address.
1833
0
  const auto RiDataArray =
1834
0
      MemInst->getSpan<__wasi_iovec_t>(RiDataPtr, WasiRiDataLen);
1835
0
  if (unlikely(RiDataArray.size() != WasiRiDataLen)) {
1836
0
    return __WASI_ERRNO_FAULT;
1837
0
  }
1838
1839
0
  auto *const RoDataLen = MemInst->getPointer<__wasi_size_t *>(RoDataLenPtr);
1840
0
  if (unlikely(RoDataLen == nullptr)) {
1841
0
    return __WASI_ERRNO_FAULT;
1842
0
  }
1843
1844
0
  auto *const RoFlags = MemInst->getPointer<__wasi_roflags_t *>(RoFlagsPtr);
1845
0
  if (unlikely(RoFlags == nullptr)) {
1846
0
    return __WASI_ERRNO_FAULT;
1847
0
  }
1848
0
  __wasi_size_t TotalSize = 0;
1849
0
  StaticVector<Span<uint8_t>, WASI::kIOVMax> WasiRiData;
1850
1851
0
  for (auto &RiData : RiDataArray) {
1852
    // Capping total size.
1853
0
    const __wasi_size_t Space =
1854
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
1855
0
    const __wasi_size_t BufLen =
1856
0
        unlikely(RiData.buf_len > Space) ? Space : RiData.buf_len;
1857
0
    TotalSize += BufLen;
1858
1859
    // Check for invalid address.
1860
0
    const auto RiDataArr = MemInst->getSpan<uint8_t>(RiData.buf, BufLen);
1861
    // Check for invalid address.
1862
0
    if (unlikely(RiDataArr.size() != BufLen)) {
1863
0
      return __WASI_ERRNO_FAULT;
1864
0
    }
1865
0
    WasiRiData.emplace_back_unchecked(RiDataArr);
1866
0
  }
1867
1868
0
  const __wasi_fd_t WasiFd = Fd;
1869
1870
0
  if (auto Res =
1871
0
          Env.sockRecv(WasiFd, WasiRiData, WasiRiFlags, *RoDataLen, *RoFlags);
1872
0
      unlikely(!Res)) {
1873
0
    return Res.error();
1874
0
  }
1875
1876
0
  return __WASI_ERRNO_SUCCESS;
1877
0
}
1878
1879
Expect<uint32_t> WasiSockRecvFromV1::body(const Runtime::CallingFrame &Frame,
1880
                                          int32_t Fd, uint32_t RiDataPtr,
1881
                                          uint32_t RiDataLen,
1882
                                          uint32_t AddressPtr, uint32_t RiFlags,
1883
                                          uint32_t /* Out */ RoDataLenPtr,
1884
0
                                          uint32_t /* Out */ RoFlagsPtr) {
1885
  // Check memory instance from module.
1886
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1887
0
  if (MemInst == nullptr) {
1888
0
    return __WASI_ERRNO_FAULT;
1889
0
  }
1890
1891
0
  __wasi_address_t *InnerAddress =
1892
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
1893
0
  if (InnerAddress == nullptr) {
1894
0
    return __WASI_ERRNO_FAULT;
1895
0
  }
1896
1897
0
  const auto Address =
1898
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
1899
0
  if (Address.size() != InnerAddress->buf_len) {
1900
0
    return __WASI_ERRNO_FAULT;
1901
0
  }
1902
1903
0
  __wasi_riflags_t WasiRiFlags;
1904
0
  if (auto Res = cast<__wasi_riflags_t>(RiFlags); unlikely(!Res)) {
1905
0
    return Res.error();
1906
0
  } else {
1907
0
    WasiRiFlags = *Res;
1908
0
  }
1909
1910
0
  const __wasi_size_t WasiRiDataLen = RiDataLen;
1911
0
  if (unlikely(WasiRiDataLen > WASI::kIOVMax)) {
1912
0
    return __WASI_ERRNO_INVAL;
1913
0
  }
1914
1915
0
  const auto RiDataArray =
1916
0
      MemInst->getSpan<__wasi_iovec_t>(RiDataPtr, WasiRiDataLen);
1917
0
  if (unlikely(RiDataArray.size() != WasiRiDataLen)) {
1918
0
    return __WASI_ERRNO_FAULT;
1919
0
  }
1920
1921
0
  auto *const RoDataLen = MemInst->getPointer<__wasi_size_t *>(RoDataLenPtr);
1922
0
  if (unlikely(RoDataLen == nullptr)) {
1923
0
    return __WASI_ERRNO_FAULT;
1924
0
  }
1925
1926
0
  auto *const RoFlags = MemInst->getPointer<__wasi_roflags_t *>(RoFlagsPtr);
1927
0
  if (unlikely(RoFlags == nullptr)) {
1928
0
    return __WASI_ERRNO_FAULT;
1929
0
  }
1930
0
  __wasi_size_t TotalSize = 0;
1931
0
  StaticVector<Span<uint8_t>, WASI::kIOVMax> WasiRiData;
1932
1933
0
  for (auto &RiData : RiDataArray) {
1934
    // Capping total size.
1935
0
    const __wasi_size_t Space =
1936
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
1937
0
    const __wasi_size_t BufLen =
1938
0
        unlikely(RiData.buf_len > Space) ? Space : RiData.buf_len;
1939
0
    TotalSize += BufLen;
1940
1941
    // Check for invalid address.
1942
0
    const auto RiDataArr = MemInst->getSpan<uint8_t>(RiData.buf, BufLen);
1943
    // Check for invalid address.
1944
0
    if (unlikely(RiDataArr.size() != BufLen)) {
1945
0
      return __WASI_ERRNO_FAULT;
1946
0
    }
1947
0
    WasiRiData.emplace_back_unchecked(RiDataArr);
1948
0
  }
1949
1950
0
  const __wasi_fd_t WasiFd = Fd;
1951
1952
0
  if (auto Res = Env.sockRecvFrom(WasiFd, WasiRiData, WasiRiFlags, nullptr,
1953
0
                                  Address, nullptr, *RoDataLen, *RoFlags);
1954
0
      unlikely(!Res)) {
1955
0
    return Res.error();
1956
0
  }
1957
1958
0
  return __WASI_ERRNO_SUCCESS;
1959
0
}
1960
1961
Expect<uint32_t> WasiSockSendV1::body(const Runtime::CallingFrame &Frame,
1962
                                      int32_t Fd, uint32_t SiDataPtr,
1963
                                      uint32_t SiDataLen, uint32_t SiFlags,
1964
0
                                      uint32_t /* Out */ SoDataLenPtr) {
1965
  // Check memory instance from module.
1966
0
  auto *MemInst = Frame.getMemoryByIndex(0);
1967
0
  if (MemInst == nullptr) {
1968
0
    return __WASI_ERRNO_FAULT;
1969
0
  }
1970
1971
0
  __wasi_siflags_t WasiSiFlags;
1972
0
  if (auto Res = cast<__wasi_siflags_t>(SiFlags); unlikely(!Res)) {
1973
0
    return Res.error();
1974
0
  } else {
1975
0
    WasiSiFlags = *Res;
1976
0
  }
1977
1978
0
  const __wasi_size_t WasiSiDataLen = SiDataLen;
1979
0
  if (unlikely(WasiSiDataLen > WASI::kIOVMax)) {
1980
0
    return __WASI_ERRNO_INVAL;
1981
0
  }
1982
1983
  // Check for invalid address.
1984
0
  const auto SiDataArray =
1985
0
      MemInst->getSpan<__wasi_ciovec_t>(SiDataPtr, WasiSiDataLen);
1986
0
  if (unlikely(SiDataArray.size() != WasiSiDataLen)) {
1987
0
    return __WASI_ERRNO_FAULT;
1988
0
  }
1989
1990
0
  auto *const SoDataLen = MemInst->getPointer<__wasi_size_t *>(SoDataLenPtr);
1991
0
  if (unlikely(SoDataLen == nullptr)) {
1992
0
    return __WASI_ERRNO_FAULT;
1993
0
  }
1994
1995
0
  __wasi_size_t TotalSize = 0;
1996
0
  StaticVector<Span<const uint8_t>, WASI::kIOVMax> WasiSiData;
1997
1998
0
  for (auto &SiData : SiDataArray) {
1999
    // Capping total size.
2000
0
    const __wasi_size_t Space =
2001
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
2002
0
    const __wasi_size_t BufLen =
2003
0
        unlikely(SiData.buf_len > Space) ? Space : SiData.buf_len;
2004
0
    TotalSize += BufLen;
2005
2006
    // Check for invalid address.
2007
0
    const auto SiDataArr = MemInst->getSpan<uint8_t>(SiData.buf, BufLen);
2008
0
    if (unlikely(SiDataArr.size() != BufLen)) {
2009
0
      return __WASI_ERRNO_FAULT;
2010
0
    }
2011
0
    WasiSiData.emplace_back_unchecked(SiDataArr);
2012
0
  }
2013
2014
0
  const __wasi_fd_t WasiFd = Fd;
2015
2016
0
  if (auto Res = Env.sockSend(WasiFd, WasiSiData, WasiSiFlags, *SoDataLen);
2017
0
      unlikely(!Res)) {
2018
0
    return Res.error();
2019
0
  }
2020
0
  return __WASI_ERRNO_SUCCESS;
2021
0
}
2022
2023
Expect<uint32_t> WasiSockSendToV1::body(const Runtime::CallingFrame &Frame,
2024
                                        int32_t Fd, uint32_t SiDataPtr,
2025
                                        uint32_t SiDataLen, uint32_t AddressPtr,
2026
                                        int32_t Port, uint32_t SiFlags,
2027
0
                                        uint32_t /* Out */ SoDataLenPtr) {
2028
  // Check memory instance from module.
2029
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2030
0
  if (MemInst == nullptr) {
2031
0
    return __WASI_ERRNO_FAULT;
2032
0
  }
2033
2034
0
  __wasi_address_t *InnerAddress =
2035
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2036
0
  if (InnerAddress == nullptr) {
2037
0
    return __WASI_ERRNO_FAULT;
2038
0
  }
2039
2040
0
  const auto Address =
2041
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2042
0
  if (Address.size() != InnerAddress->buf_len) {
2043
0
    return __WASI_ERRNO_FAULT;
2044
0
  }
2045
2046
0
  __wasi_address_family_t WasiAddressFamily;
2047
0
  switch (Address.size()) {
2048
0
  case 4:
2049
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET4;
2050
0
    break;
2051
0
  case 16:
2052
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET6;
2053
0
    break;
2054
0
  default:
2055
0
    return __WASI_ERRNO_INVAL;
2056
0
  }
2057
2058
0
  __wasi_siflags_t WasiSiFlags;
2059
0
  if (auto Res = cast<__wasi_siflags_t>(SiFlags); unlikely(!Res)) {
2060
0
    return Res.error();
2061
0
  } else {
2062
0
    WasiSiFlags = *Res;
2063
0
  }
2064
2065
0
  const __wasi_size_t WasiSiDataLen = SiDataLen;
2066
0
  if (unlikely(WasiSiDataLen > WASI::kIOVMax)) {
2067
0
    return __WASI_ERRNO_INVAL;
2068
0
  }
2069
2070
  // Check for invalid address.
2071
0
  const auto SiDataArray =
2072
0
      MemInst->getSpan<__wasi_ciovec_t>(SiDataPtr, WasiSiDataLen);
2073
0
  if (unlikely(SiDataArray.size() != WasiSiDataLen)) {
2074
0
    return __WASI_ERRNO_FAULT;
2075
0
  }
2076
2077
0
  auto *const SoDataLen = MemInst->getPointer<__wasi_size_t *>(SoDataLenPtr);
2078
0
  if (unlikely(SoDataLen == nullptr)) {
2079
0
    return __WASI_ERRNO_FAULT;
2080
0
  }
2081
2082
0
  __wasi_size_t TotalSize = 0;
2083
0
  StaticVector<Span<const uint8_t>, WASI::kIOVMax> WasiSiData;
2084
2085
0
  for (auto &SiData : SiDataArray) {
2086
    // Capping total size.
2087
0
    const __wasi_size_t Space =
2088
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
2089
0
    const __wasi_size_t BufLen =
2090
0
        unlikely(SiData.buf_len > Space) ? Space : SiData.buf_len;
2091
0
    TotalSize += BufLen;
2092
2093
    // Check for invalid address.
2094
0
    const auto SiDataArr = MemInst->getSpan<uint8_t>(SiData.buf, BufLen);
2095
0
    if (unlikely(SiDataArr.size() != BufLen)) {
2096
0
      return __WASI_ERRNO_FAULT;
2097
0
    }
2098
0
    WasiSiData.emplace_back_unchecked(SiDataArr);
2099
0
  }
2100
2101
0
  const __wasi_fd_t WasiFd = Fd;
2102
2103
0
  if (auto Res =
2104
0
          Env.sockSendTo(WasiFd, WasiSiData, WasiSiFlags, WasiAddressFamily,
2105
0
                         Address, static_cast<uint16_t>(Port), *SoDataLen);
2106
0
      unlikely(!Res)) {
2107
0
    return Res.error();
2108
0
  }
2109
2110
0
  return __WASI_ERRNO_SUCCESS;
2111
0
}
2112
2113
Expect<uint32_t> WasiSockShutdown::body(const Runtime::CallingFrame &,
2114
0
                                        int32_t Fd, uint32_t SdFlags) {
2115
0
  __wasi_sdflags_t WasiSdFlags;
2116
0
  if (auto Res = cast<__wasi_sdflags_t>(SdFlags); unlikely(!Res)) {
2117
0
    return Res.error();
2118
0
  } else {
2119
0
    WasiSdFlags = *Res;
2120
0
  }
2121
2122
0
  const __wasi_fd_t WasiFd = Fd;
2123
2124
0
  if (auto Res = Env.sockShutdown(WasiFd, WasiSdFlags); unlikely(!Res)) {
2125
0
    return Res.error();
2126
0
  }
2127
0
  return __WASI_ERRNO_SUCCESS;
2128
0
}
2129
2130
Expect<uint32_t> WasiSockSetOpt::body(const Runtime::CallingFrame &Frame,
2131
                                      int32_t Fd, uint32_t SockOptLevel,
2132
                                      uint32_t SockOptName, uint32_t FlagPtr,
2133
0
                                      uint32_t FlagSize) {
2134
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2135
0
  if (MemInst == nullptr) {
2136
0
    return __WASI_ERRNO_FAULT;
2137
0
  }
2138
2139
0
  __wasi_sock_opt_level_t WasiSockOptLevel;
2140
0
  if (auto Res = cast<__wasi_sock_opt_level_t>(SockOptLevel); unlikely(!Res)) {
2141
0
    return Res.error();
2142
0
  } else {
2143
0
    WasiSockOptLevel = *Res;
2144
0
  }
2145
2146
0
  __wasi_sock_opt_so_t WasiSockOptName;
2147
0
  if (auto Res = cast<__wasi_sock_opt_so_t>(SockOptName); unlikely(!Res)) {
2148
0
    return Res.error();
2149
0
  } else {
2150
0
    WasiSockOptName = *Res;
2151
0
  }
2152
2153
0
  const auto Flag = MemInst->getSpan<uint8_t>(FlagPtr, FlagSize);
2154
0
  if (Flag.size() != FlagSize) {
2155
0
    return __WASI_ERRNO_FAULT;
2156
0
  }
2157
2158
0
  const __wasi_fd_t WasiFd = Fd;
2159
2160
0
  if (auto Res =
2161
0
          Env.sockSetOpt(WasiFd, WasiSockOptLevel, WasiSockOptName, Flag);
2162
0
      unlikely(!Res)) {
2163
0
    return Res.error();
2164
0
  }
2165
2166
0
  return __WASI_ERRNO_SUCCESS;
2167
0
}
2168
2169
Expect<uint32_t> WasiSockGetAddrinfo::body(
2170
    const Runtime::CallingFrame &Frame, uint32_t NodePtr, uint32_t NodeLen,
2171
    uint32_t ServicePtr, uint32_t ServiceLen, uint32_t HintsPtr,
2172
0
    uint32_t ResPtr, uint32_t MaxResLength, uint32_t ResLengthPtr) {
2173
  // Check memory instance from module.
2174
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2175
0
  if (MemInst == nullptr) {
2176
0
    return __WASI_ERRNO_FAULT;
2177
0
  }
2178
2179
0
  const auto Node = MemInst->getStringView(NodePtr, NodeLen);
2180
0
  if (Node.size() != NodeLen) {
2181
0
    return __WASI_ERRNO_FAULT;
2182
0
  }
2183
2184
0
  const auto Service = MemInst->getStringView(ServicePtr, ServiceLen);
2185
0
  if (Service.size() != ServiceLen) {
2186
0
    return __WASI_ERRNO_FAULT;
2187
0
  }
2188
2189
0
  auto *Hint = MemInst->getPointer<const __wasi_addrinfo_t *>(HintsPtr);
2190
0
  if (Hint == nullptr) {
2191
0
    return __WASI_ERRNO_FAULT;
2192
0
  }
2193
2194
0
  auto *const ResBuf = MemInst->getPointer<const uint8_t_ptr *>(ResPtr);
2195
0
  if (ResBuf == nullptr) {
2196
0
    return __WASI_ERRNO_FAULT;
2197
0
  }
2198
2199
0
  auto *const ResLength = MemInst->getPointer<__wasi_size_t *>(ResLengthPtr);
2200
0
  if (ResLength == nullptr) {
2201
0
    return __WASI_ERRNO_FAULT;
2202
0
  }
2203
2204
  // service and node can not be empty at the same time
2205
0
  if (Service.empty() && Node.empty()) {
2206
0
    return __WASI_ERRNO_AINONAME;
2207
0
  }
2208
2209
0
  if (MaxResLength < 1) {
2210
0
    return __WASI_ERRNO_AIMEMORY;
2211
0
  }
2212
2213
0
  if (Hint->ai_flags &
2214
0
      ~(__WASI_AIFLAGS_AI_PASSIVE | __WASI_AIFLAGS_AI_CANONNAME |
2215
0
        __WASI_AIFLAGS_AI_NUMERICHOST | __WASI_AIFLAGS_AI_NUMERICSERV |
2216
0
        __WASI_AIFLAGS_AI_ADDRCONFIG | __WASI_AIFLAGS_AI_V4MAPPED |
2217
0
        __WASI_AIFLAGS_AI_ALL)) {
2218
0
    return __WASI_ERRNO_AIBADFLAG;
2219
0
  }
2220
0
  if (Hint->ai_flags & __WASI_AIFLAGS_AI_CANONNAME && Node.empty()) {
2221
0
    return __WASI_ERRNO_AIBADFLAG;
2222
0
  }
2223
0
  switch (Hint->ai_family) {
2224
0
  case __WASI_ADDRESS_FAMILY_UNSPEC:
2225
0
  case __WASI_ADDRESS_FAMILY_INET4:
2226
0
  case __WASI_ADDRESS_FAMILY_INET6:
2227
0
    break;
2228
0
  default:
2229
0
    return __WASI_ERRNO_AIFAMILY;
2230
0
  }
2231
0
  switch (Hint->ai_protocol) {
2232
0
  case __WASI_PROTOCOL_IPPROTO_IP:
2233
0
  case __WASI_PROTOCOL_IPPROTO_TCP:
2234
0
  case __WASI_PROTOCOL_IPPROTO_UDP:
2235
0
    break;
2236
0
  default:
2237
0
    return __WASI_ERRNO_NOSYS;
2238
0
  }
2239
0
  switch (Hint->ai_socktype) {
2240
0
  case __WASI_SOCK_TYPE_SOCK_ANY:
2241
0
  case __WASI_SOCK_TYPE_SOCK_DGRAM:
2242
0
  case __WASI_SOCK_TYPE_SOCK_STREAM:
2243
0
    break;
2244
0
  default:
2245
0
    return __WASI_ERRNO_NOSYS;
2246
0
  }
2247
2248
0
  auto Body = [&]() -> WASI::WasiExpect<void> {
2249
0
    auto initWasiAddrinfoArray =
2250
0
        [&MemInst](uint8_t_ptr Base, uint32_t Length,
2251
0
                   Span<__wasi_addrinfo_t *> WasiAddrinfoArray) noexcept
2252
0
        -> WASI::WasiExpect<void> {
2253
0
      for (uint32_t Item = 0; Item < Length; Item++) {
2254
0
        auto *const TmpAddrinfo =
2255
0
            MemInst->getPointer<__wasi_addrinfo_t *>(Base);
2256
0
        if (TmpAddrinfo == nullptr) {
2257
0
          return WASI::WasiUnexpect(__WASI_ERRNO_FAULT);
2258
0
        }
2259
0
        WasiAddrinfoArray[Item] = TmpAddrinfo;
2260
0
        Base = TmpAddrinfo->ai_next;
2261
0
      }
2262
0
      return {};
2263
0
    };
2264
2265
0
    auto initAiAddrArray =
2266
0
        [&MemInst](Span<__wasi_addrinfo_t *> WasiAddrinfoArray,
2267
0
                   Span<__wasi_sockaddr_t *> WasiSockAddrArray) noexcept
2268
0
        -> WASI::WasiExpect<void> {
2269
0
      for (uint32_t Item = 0; Item < WasiAddrinfoArray.size(); Item++) {
2270
0
        auto *const Addr = MemInst->getPointer<__wasi_sockaddr_t *>(
2271
0
            WasiAddrinfoArray[Item]->ai_addr);
2272
0
        if (Addr == nullptr) {
2273
0
          return WASI::WasiUnexpect(__WASI_ERRNO_FAULT);
2274
0
        }
2275
0
        WasiSockAddrArray[Item] = Addr;
2276
0
      }
2277
0
      return {};
2278
0
    };
2279
2280
0
    auto initAiAddrSaDataArray =
2281
0
        [&MemInst](Span<__wasi_sockaddr_t *> WasiSockAddrArray,
2282
0
                   Span<char *> AiSockAddrSaDataArray) noexcept
2283
0
        -> WASI::WasiExpect<void> {
2284
0
      for (uint32_t Item = 0; Item < WasiSockAddrArray.size(); Item++) {
2285
0
        const auto WasiSockAddr =
2286
0
            MemInst->getSpan<char>(WasiSockAddrArray[Item]->sa_data,
2287
0
                                   WasiSockAddrArray[Item]->sa_data_len);
2288
0
        if (WasiSockAddr.size() != WasiSockAddrArray[Item]->sa_data_len) {
2289
0
          return WASI::WasiUnexpect(__WASI_ERRNO_FAULT);
2290
0
        }
2291
0
        AiSockAddrSaDataArray[Item] = WasiSockAddr.data();
2292
0
      }
2293
0
      return {};
2294
0
    };
2295
2296
0
    auto initAiCanonnameArray =
2297
0
        [&MemInst](Span<__wasi_addrinfo_t *> WasiAddrinfoArray,
2298
0
                   Span<char *> WasiAddrinfoCanonnameArray) noexcept
2299
0
        -> WASI::WasiExpect<void> {
2300
0
      for (uint32_t Item = 0; Item < WasiAddrinfoArray.size(); Item++) {
2301
0
        const auto CanonName =
2302
0
            MemInst->getSpan<char>(WasiAddrinfoArray[Item]->ai_canonname,
2303
0
                                   WasiAddrinfoArray[Item]->ai_canonname_len);
2304
0
        if (CanonName.size() != WasiAddrinfoArray[Item]->ai_canonname_len) {
2305
0
          return WASI::WasiUnexpect(__WASI_ERRNO_FAULT);
2306
0
        }
2307
0
        WasiAddrinfoCanonnameArray[Item] = CanonName.data();
2308
0
      }
2309
0
      return {};
2310
0
    };
2311
2312
0
    std::vector<__wasi_addrinfo_t *> WasiAddrinfoArray(MaxResLength, nullptr);
2313
0
    std::vector<__wasi_sockaddr_t *> WasiSockAddrArray(MaxResLength, nullptr);
2314
0
    std::vector<char *> AiAddrSaDataArray(MaxResLength, nullptr);
2315
0
    std::vector<char *> AiCanonnameArray(MaxResLength, nullptr);
2316
2317
0
    EXPECTED_TRY(
2318
0
        initWasiAddrinfoArray(*ResBuf, MaxResLength, WasiAddrinfoArray));
2319
0
    EXPECTED_TRY(initAiAddrArray(WasiAddrinfoArray, WasiSockAddrArray));
2320
0
    EXPECTED_TRY(initAiAddrSaDataArray(WasiSockAddrArray, AiAddrSaDataArray));
2321
0
    EXPECTED_TRY(initAiCanonnameArray(WasiAddrinfoArray, AiCanonnameArray));
2322
2323
0
    EXPECTED_TRY(Env.getAddrInfo(
2324
0
        Node, Service, *Hint, MaxResLength, WasiAddrinfoArray,
2325
0
        WasiSockAddrArray, AiAddrSaDataArray, AiCanonnameArray, *ResLength));
2326
0
    return {};
2327
0
  };
2328
0
  if (auto Res = Body(); unlikely(!Res)) {
2329
0
    return Res.error();
2330
0
  }
2331
2332
0
  return __WASI_ERRNO_SUCCESS;
2333
0
}
2334
2335
Expect<uint32_t>
2336
WasiSockGetLocalAddrV1::body(const Runtime::CallingFrame &Frame, int32_t Fd,
2337
                             uint32_t AddressPtr, uint32_t AddressTypePtr,
2338
0
                             uint32_t PortPtr) {
2339
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2340
0
  if (MemInst == nullptr) {
2341
0
    return __WASI_ERRNO_FAULT;
2342
0
  }
2343
0
  __wasi_address_t *InnerAddress =
2344
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2345
0
  if (InnerAddress == nullptr) {
2346
0
    return __WASI_ERRNO_FAULT;
2347
0
  }
2348
2349
0
  const auto Address =
2350
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2351
0
  if (Address.size() != InnerAddress->buf_len) {
2352
0
    return __WASI_ERRNO_FAULT;
2353
0
  }
2354
2355
0
  switch (Address.size()) {
2356
0
  case 4:
2357
0
    break;
2358
0
  case 16:
2359
0
    break;
2360
0
  default:
2361
0
    return __WASI_ERRNO_INVAL;
2362
0
  }
2363
2364
0
  uint32_t *const RoAddressType =
2365
0
      MemInst->getPointer<uint32_t *>(AddressTypePtr);
2366
0
  if (RoAddressType == nullptr) {
2367
0
    return __WASI_ERRNO_FAULT;
2368
0
  }
2369
0
  __wasi_address_family_t AddressType;
2370
2371
0
  uint32_t *const RoPort = MemInst->getPointer<uint32_t *>(PortPtr);
2372
0
  if (RoPort == nullptr) {
2373
0
    return __WASI_ERRNO_FAULT;
2374
0
  }
2375
2376
0
  uint16_t Port;
2377
0
  const __wasi_fd_t WasiFd = Fd;
2378
2379
0
  if (auto Res = Env.sockGetLocalAddr(WasiFd, &AddressType, Address, &Port);
2380
0
      unlikely(!Res)) {
2381
0
    return Res.error();
2382
0
  }
2383
0
  *RoPort = Port;
2384
  // XXX: This is a workaround
2385
  // The correct one should be `*RoAddressType = AddressType;`
2386
  // However, due to this bugfix will break the existing applications.
2387
  // So we changed back to the old way.
2388
0
  switch (AddressType) {
2389
0
  case __WASI_ADDRESS_FAMILY_INET4:
2390
0
    *RoAddressType = 4;
2391
0
    break;
2392
0
  case __WASI_ADDRESS_FAMILY_INET6:
2393
0
    *RoAddressType = 6;
2394
0
    break;
2395
0
  default:
2396
0
    assumingUnreachable();
2397
0
  }
2398
0
  return __WASI_ERRNO_SUCCESS;
2399
0
}
2400
2401
Expect<uint32_t> WasiSockGetPeerAddrV1::body(const Runtime::CallingFrame &Frame,
2402
                                             int32_t Fd, uint32_t AddressPtr,
2403
                                             uint32_t AddressTypePtr,
2404
0
                                             uint32_t PortPtr) {
2405
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2406
0
  if (MemInst == nullptr) {
2407
0
    return __WASI_ERRNO_FAULT;
2408
0
  }
2409
0
  __wasi_address_t *InnerAddress =
2410
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2411
0
  if (InnerAddress == nullptr) {
2412
0
    return __WASI_ERRNO_FAULT;
2413
0
  }
2414
2415
0
  const auto Address =
2416
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2417
0
  if (Address.size() != InnerAddress->buf_len) {
2418
0
    return __WASI_ERRNO_FAULT;
2419
0
  }
2420
2421
0
  switch (Address.size()) {
2422
0
  case 4:
2423
0
    break;
2424
0
  case 16:
2425
0
    break;
2426
0
  default:
2427
0
    return __WASI_ERRNO_INVAL;
2428
0
  }
2429
2430
0
  uint32_t *const RoAddressType =
2431
0
      MemInst->getPointer<uint32_t *>(AddressTypePtr);
2432
0
  if (RoAddressType == nullptr) {
2433
0
    return __WASI_ERRNO_FAULT;
2434
0
  }
2435
0
  __wasi_address_family_t AddressType;
2436
2437
0
  uint32_t *const RoPort = MemInst->getPointer<uint32_t *>(PortPtr);
2438
0
  if (RoPort == nullptr) {
2439
0
    return __WASI_ERRNO_FAULT;
2440
0
  }
2441
0
  uint16_t Port;
2442
2443
0
  const __wasi_fd_t WasiFd = Fd;
2444
2445
0
  if (auto Res = Env.sockGetPeerAddr(WasiFd, &AddressType, Address, &Port);
2446
0
      unlikely(!Res)) {
2447
0
    return Res.error();
2448
0
  }
2449
0
  *RoPort = Port;
2450
  // XXX: This is a workaround
2451
  // The correct one should be `*RoAddressType = AddressType;`
2452
  // However, due to this bugfix will break the existing applications.
2453
  // So we changed back to the old way.
2454
0
  switch (AddressType) {
2455
0
  case __WASI_ADDRESS_FAMILY_INET4:
2456
0
    *RoAddressType = 4;
2457
0
    break;
2458
0
  case __WASI_ADDRESS_FAMILY_INET6:
2459
0
    *RoAddressType = 6;
2460
0
    break;
2461
0
  default:
2462
0
    assumingUnreachable();
2463
0
  }
2464
0
  return __WASI_ERRNO_SUCCESS;
2465
0
}
2466
2467
Expect<uint32_t> WasiSockOpenV2::body(const Runtime::CallingFrame &Frame,
2468
                                      uint32_t AddressFamily, uint32_t SockType,
2469
0
                                      uint32_t /* Out */ RoFdPtr) {
2470
  // Check memory instance from module.
2471
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2472
0
  if (MemInst == nullptr) {
2473
0
    return __WASI_ERRNO_FAULT;
2474
0
  }
2475
2476
0
  __wasi_fd_t *const RoFd = MemInst->getPointer<__wasi_fd_t *>(RoFdPtr);
2477
0
  if (RoFd == nullptr) {
2478
0
    return __WASI_ERRNO_FAULT;
2479
0
  }
2480
2481
0
  __wasi_address_family_t WasiAddressFamily;
2482
0
  if (auto Res = cast<__wasi_address_family_t>(AddressFamily); unlikely(!Res)) {
2483
0
    return Res.error();
2484
0
  } else {
2485
0
    WasiAddressFamily = *Res;
2486
0
  }
2487
2488
0
  if (!AllowAFUNIX(Frame, WasiAddressFamily)) {
2489
0
    return __WASI_ERRNO_NOSYS;
2490
0
  }
2491
2492
0
  __wasi_sock_type_t WasiSockType;
2493
0
  if (auto Res = cast<__wasi_sock_type_t>(SockType); unlikely(!Res)) {
2494
0
    return Res.error();
2495
0
  } else {
2496
0
    WasiSockType = *Res;
2497
0
  }
2498
2499
0
  if (auto Res = Env.sockOpen(WasiAddressFamily, WasiSockType);
2500
0
      unlikely(!Res)) {
2501
0
    return Res.error();
2502
0
  } else {
2503
0
    *RoFd = *Res;
2504
0
  }
2505
2506
0
  return __WASI_ERRNO_SUCCESS;
2507
0
}
2508
2509
Expect<uint32_t> WasiSockBindV2::body(const Runtime::CallingFrame &Frame,
2510
                                      int32_t Fd, uint32_t AddressPtr,
2511
0
                                      uint32_t Port) {
2512
  // Check memory instance from module.
2513
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2514
0
  if (MemInst == nullptr) {
2515
0
    return __WASI_ERRNO_FAULT;
2516
0
  }
2517
0
  auto *const InnerAddress =
2518
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2519
0
  if (InnerAddress == nullptr) {
2520
0
    return __WASI_ERRNO_FAULT;
2521
0
  }
2522
2523
0
  auto Address =
2524
0
      MemInst->getSpan<const uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2525
0
  if (Address.size() != InnerAddress->buf_len) {
2526
0
    return __WASI_ERRNO_FAULT;
2527
0
  }
2528
2529
0
  __wasi_address_family_t WasiAddressFamily;
2530
0
  switch (Address.size()) {
2531
0
  case 4:
2532
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET4;
2533
0
    break;
2534
0
  case 16:
2535
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET6;
2536
0
    break;
2537
0
  case 128: {
2538
0
    auto &Storage =
2539
0
        *reinterpret_cast<const WASI::WasiAddrStorage *>(Address.data());
2540
0
    WasiAddressFamily = Storage.getAddressFamily();
2541
0
    Address = Storage.getAddress();
2542
0
    break;
2543
0
  }
2544
0
  default:
2545
0
    return __WASI_ERRNO_INVAL;
2546
0
  }
2547
2548
0
  const __wasi_fd_t WasiFd = Fd;
2549
2550
0
  if (auto Res = Env.sockBind(WasiFd, WasiAddressFamily, Address,
2551
0
                              static_cast<uint16_t>(Port));
2552
0
      unlikely(!Res)) {
2553
0
    return Res.error();
2554
0
  }
2555
0
  return __WASI_ERRNO_SUCCESS;
2556
0
}
2557
2558
Expect<uint32_t> WasiSockListenV2::body(const Runtime::CallingFrame &,
2559
0
                                        int32_t Fd, int32_t Backlog) {
2560
0
  const __wasi_fd_t WasiFd = Fd;
2561
0
  if (auto Res = Env.sockListen(WasiFd, Backlog); unlikely(!Res)) {
2562
0
    return Res.error();
2563
0
  }
2564
0
  return __WASI_ERRNO_SUCCESS;
2565
0
}
2566
2567
Expect<uint32_t> WasiSockConnectV2::body(const Runtime::CallingFrame &Frame,
2568
                                         int32_t Fd, uint32_t AddressPtr,
2569
0
                                         uint32_t Port) {
2570
  // Check memory instance from module.
2571
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2572
0
  if (MemInst == nullptr) {
2573
0
    return __WASI_ERRNO_FAULT;
2574
0
  }
2575
0
  __wasi_address_t *InnerAddress =
2576
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2577
0
  if (InnerAddress == nullptr) {
2578
0
    return __WASI_ERRNO_FAULT;
2579
0
  }
2580
2581
0
  auto Address =
2582
0
      MemInst->getSpan<const uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2583
0
  if (Address.size() != InnerAddress->buf_len) {
2584
0
    return __WASI_ERRNO_FAULT;
2585
0
  }
2586
2587
0
  __wasi_address_family_t WasiAddressFamily;
2588
0
  switch (Address.size()) {
2589
0
  case 4:
2590
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET4;
2591
0
    break;
2592
0
  case 16:
2593
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET6;
2594
0
    break;
2595
0
  case 128: {
2596
0
    auto &Storage =
2597
0
        *reinterpret_cast<const WASI::WasiAddrStorage *>(Address.data());
2598
0
    WasiAddressFamily = Storage.getAddressFamily();
2599
0
    Address = Storage.getAddress();
2600
0
    break;
2601
0
  }
2602
0
  default:
2603
0
    return __WASI_ERRNO_INVAL;
2604
0
  }
2605
2606
0
  const __wasi_fd_t WasiFd = Fd;
2607
0
  if (auto Res = Env.sockConnect(WasiFd, WasiAddressFamily, Address,
2608
0
                                 static_cast<uint16_t>(Port));
2609
0
      unlikely(!Res)) {
2610
0
    return Res.error();
2611
0
  }
2612
2613
0
  return __WASI_ERRNO_SUCCESS;
2614
0
}
2615
2616
Expect<uint32_t> WasiSockRecvV2::body(const Runtime::CallingFrame &Frame,
2617
                                      int32_t Fd, uint32_t RiDataPtr,
2618
                                      uint32_t RiDataLen, uint32_t RiFlags,
2619
                                      uint32_t /* Out */ RoDataLenPtr,
2620
0
                                      uint32_t /* Out */ RoFlagsPtr) {
2621
  // Check memory instance from module.
2622
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2623
0
  if (MemInst == nullptr) {
2624
0
    return __WASI_ERRNO_FAULT;
2625
0
  }
2626
2627
0
  __wasi_riflags_t WasiRiFlags;
2628
0
  if (auto Res = cast<__wasi_riflags_t>(RiFlags); unlikely(!Res)) {
2629
0
    return Res.error();
2630
0
  } else {
2631
0
    WasiRiFlags = *Res;
2632
0
  }
2633
2634
0
  const __wasi_size_t WasiRiDataLen = RiDataLen;
2635
0
  if (unlikely(WasiRiDataLen > WASI::kIOVMax)) {
2636
0
    return __WASI_ERRNO_INVAL;
2637
0
  }
2638
2639
  // Check for invalid address.
2640
0
  const auto RiDataArray =
2641
0
      MemInst->getSpan<__wasi_iovec_t>(RiDataPtr, WasiRiDataLen);
2642
0
  if (unlikely(RiDataArray.size() != WasiRiDataLen)) {
2643
0
    return __WASI_ERRNO_FAULT;
2644
0
  }
2645
2646
0
  auto *const RoDataLen = MemInst->getPointer<__wasi_size_t *>(RoDataLenPtr);
2647
0
  if (unlikely(RoDataLen == nullptr)) {
2648
0
    return __WASI_ERRNO_FAULT;
2649
0
  }
2650
2651
0
  auto *const RoFlags = MemInst->getPointer<__wasi_roflags_t *>(RoFlagsPtr);
2652
0
  if (unlikely(RoFlags == nullptr)) {
2653
0
    return __WASI_ERRNO_FAULT;
2654
0
  }
2655
0
  __wasi_size_t TotalSize = 0;
2656
0
  StaticVector<Span<uint8_t>, WASI::kIOVMax> WasiRiData;
2657
2658
0
  for (auto &RiData : RiDataArray) {
2659
    // Capping total size.
2660
0
    const __wasi_size_t Space =
2661
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
2662
0
    const __wasi_size_t BufLen =
2663
0
        unlikely(RiData.buf_len > Space) ? Space : RiData.buf_len;
2664
0
    TotalSize += BufLen;
2665
2666
    // Check for invalid address.
2667
0
    const auto RiDataArr = MemInst->getSpan<uint8_t>(RiData.buf, BufLen);
2668
0
    if (unlikely(RiDataArr.size() != BufLen)) {
2669
0
      return __WASI_ERRNO_FAULT;
2670
0
    }
2671
0
    WasiRiData.emplace_back_unchecked(RiDataArr);
2672
0
  }
2673
2674
0
  const __wasi_fd_t WasiFd = Fd;
2675
2676
0
  if (auto Res =
2677
0
          Env.sockRecv(WasiFd, WasiRiData, WasiRiFlags, *RoDataLen, *RoFlags);
2678
0
      unlikely(!Res)) {
2679
0
    return Res.error();
2680
0
  }
2681
2682
0
  return __WASI_ERRNO_SUCCESS;
2683
0
}
2684
2685
Expect<uint32_t> WasiSockRecvFromV2::body(const Runtime::CallingFrame &Frame,
2686
                                          int32_t Fd, uint32_t RiDataPtr,
2687
                                          uint32_t RiDataLen,
2688
                                          uint32_t AddressPtr, uint32_t RiFlags,
2689
                                          uint32_t /* Out */ PortPtr,
2690
                                          uint32_t /* Out */ RoDataLenPtr,
2691
0
                                          uint32_t /* Out */ RoFlagsPtr) {
2692
  // Check memory instance from module.
2693
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2694
0
  if (MemInst == nullptr) {
2695
0
    return __WASI_ERRNO_FAULT;
2696
0
  }
2697
2698
0
  __wasi_address_t *InnerAddress =
2699
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2700
0
  if (InnerAddress == nullptr) {
2701
0
    return __WASI_ERRNO_FAULT;
2702
0
  }
2703
2704
0
  auto Address =
2705
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2706
0
  if (Address.size() != InnerAddress->buf_len) {
2707
0
    return __WASI_ERRNO_FAULT;
2708
0
  }
2709
2710
0
  __wasi_address_family_t WasiAddressFamily;
2711
0
  WASI::WasiAddrStorage *Storage = nullptr;
2712
0
  switch (Address.size()) {
2713
0
  case 4:
2714
0
  case 16:
2715
0
    break;
2716
0
  case 128:
2717
0
    Storage = reinterpret_cast<WASI::WasiAddrStorage *>(Address.data());
2718
0
    Address = Storage->getAddress();
2719
0
    break;
2720
0
  default:
2721
0
    return __WASI_ERRNO_INVAL;
2722
0
  }
2723
2724
0
  __wasi_riflags_t WasiRiFlags;
2725
0
  if (auto Res = cast<__wasi_riflags_t>(RiFlags); unlikely(!Res)) {
2726
0
    return Res.error();
2727
0
  } else {
2728
0
    WasiRiFlags = *Res;
2729
0
  }
2730
2731
0
  const __wasi_size_t WasiRiDataLen = RiDataLen;
2732
0
  if (unlikely(WasiRiDataLen > WASI::kIOVMax)) {
2733
0
    return __WASI_ERRNO_INVAL;
2734
0
  }
2735
2736
  // Check for invalid address.
2737
0
  uint16_t *const RoPort = MemInst->getPointer<uint16_t *>(PortPtr);
2738
0
  if (RoPort == nullptr) {
2739
0
    return __WASI_ERRNO_FAULT;
2740
0
  }
2741
2742
0
  const auto RiDataArray =
2743
0
      MemInst->getSpan<__wasi_iovec_t>(RiDataPtr, WasiRiDataLen);
2744
0
  if (unlikely(RiDataArray.size() != WasiRiDataLen)) {
2745
0
    return __WASI_ERRNO_FAULT;
2746
0
  }
2747
2748
0
  auto *const RoDataLen = MemInst->getPointer<__wasi_size_t *>(RoDataLenPtr);
2749
0
  if (unlikely(RoDataLen == nullptr)) {
2750
0
    return __WASI_ERRNO_FAULT;
2751
0
  }
2752
2753
0
  auto *const RoFlags = MemInst->getPointer<__wasi_roflags_t *>(RoFlagsPtr);
2754
0
  if (unlikely(RoFlags == nullptr)) {
2755
0
    return __WASI_ERRNO_FAULT;
2756
0
  }
2757
0
  __wasi_size_t TotalSize = 0;
2758
0
  StaticVector<Span<uint8_t>, WASI::kIOVMax> WasiRiData;
2759
2760
0
  for (auto &RiData : RiDataArray) {
2761
    // Capping total size.
2762
0
    const __wasi_size_t Space =
2763
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
2764
0
    const __wasi_size_t BufLen =
2765
0
        unlikely(RiData.buf_len > Space) ? Space : RiData.buf_len;
2766
0
    TotalSize += BufLen;
2767
2768
    // Check for invalid address.
2769
0
    const auto RiDataArr = MemInst->getSpan<uint8_t>(RiData.buf, BufLen);
2770
0
    if (unlikely(RiDataArr.size() != BufLen)) {
2771
0
      return __WASI_ERRNO_FAULT;
2772
0
    }
2773
0
    WasiRiData.emplace_back_unchecked(RiDataArr);
2774
0
  }
2775
2776
0
  const __wasi_fd_t WasiFd = Fd;
2777
2778
0
  if (auto Res =
2779
0
          Env.sockRecvFrom(WasiFd, WasiRiData, WasiRiFlags, &WasiAddressFamily,
2780
0
                           Address, RoPort, *RoDataLen, *RoFlags);
2781
0
      unlikely(!Res)) {
2782
0
    return Res.error();
2783
0
  }
2784
0
  if (Storage) {
2785
0
    Storage->setAddressFamily(WasiAddressFamily);
2786
0
  }
2787
0
  return __WASI_ERRNO_SUCCESS;
2788
0
}
2789
2790
Expect<uint32_t> WasiSockSendV2::body(const Runtime::CallingFrame &Frame,
2791
                                      int32_t Fd, uint32_t SiDataPtr,
2792
                                      uint32_t SiDataLen, uint32_t SiFlags,
2793
0
                                      uint32_t /* Out */ SoDataLenPtr) {
2794
  // Check memory instance from module.
2795
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2796
0
  if (MemInst == nullptr) {
2797
0
    return __WASI_ERRNO_FAULT;
2798
0
  }
2799
2800
0
  __wasi_siflags_t WasiSiFlags;
2801
0
  if (auto Res = cast<__wasi_siflags_t>(SiFlags); unlikely(!Res)) {
2802
0
    return Res.error();
2803
0
  } else {
2804
0
    WasiSiFlags = *Res;
2805
0
  }
2806
2807
0
  const __wasi_size_t WasiSiDataLen = SiDataLen;
2808
0
  if (unlikely(WasiSiDataLen > WASI::kIOVMax)) {
2809
0
    return __WASI_ERRNO_INVAL;
2810
0
  }
2811
2812
  // Check for invalid address.
2813
0
  const auto SiDataArray =
2814
0
      MemInst->getSpan<__wasi_ciovec_t>(SiDataPtr, WasiSiDataLen);
2815
0
  if (unlikely(SiDataArray.size() != WasiSiDataLen)) {
2816
0
    return __WASI_ERRNO_FAULT;
2817
0
  }
2818
2819
0
  auto *const SoDataLen = MemInst->getPointer<__wasi_size_t *>(SoDataLenPtr);
2820
0
  if (unlikely(SoDataLen == nullptr)) {
2821
0
    return __WASI_ERRNO_FAULT;
2822
0
  }
2823
2824
0
  __wasi_size_t TotalSize = 0;
2825
0
  StaticVector<Span<const uint8_t>, WASI::kIOVMax> WasiSiData;
2826
2827
0
  for (auto &SiData : SiDataArray) {
2828
    // Capping total size.
2829
0
    const __wasi_size_t Space =
2830
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
2831
0
    const __wasi_size_t BufLen =
2832
0
        unlikely(SiData.buf_len > Space) ? Space : SiData.buf_len;
2833
0
    TotalSize += BufLen;
2834
2835
    // Check for invalid address.
2836
0
    const auto SiDataArr = MemInst->getSpan<uint8_t>(SiData.buf, BufLen);
2837
0
    if (unlikely(SiDataArr.size() != BufLen)) {
2838
0
      return __WASI_ERRNO_FAULT;
2839
0
    }
2840
0
    WasiSiData.emplace_back_unchecked(SiDataArr);
2841
0
  }
2842
2843
0
  const __wasi_fd_t WasiFd = Fd;
2844
2845
0
  if (auto Res = Env.sockSend(WasiFd, WasiSiData, WasiSiFlags, *SoDataLen);
2846
0
      unlikely(!Res)) {
2847
0
    return Res.error();
2848
0
  }
2849
0
  return __WASI_ERRNO_SUCCESS;
2850
0
}
2851
2852
Expect<uint32_t> WasiSockSendToV2::body(const Runtime::CallingFrame &Frame,
2853
                                        int32_t Fd, uint32_t SiDataPtr,
2854
                                        uint32_t SiDataLen, uint32_t AddressPtr,
2855
                                        int32_t Port, uint32_t SiFlags,
2856
0
                                        uint32_t /* Out */ SoDataLenPtr) {
2857
  // Check memory instance from module.
2858
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2859
0
  if (MemInst == nullptr) {
2860
0
    return __WASI_ERRNO_FAULT;
2861
0
  }
2862
2863
0
  __wasi_address_t *InnerAddress =
2864
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
2865
0
  if (InnerAddress == nullptr) {
2866
0
    return __WASI_ERRNO_FAULT;
2867
0
  }
2868
2869
0
  auto Address =
2870
0
      MemInst->getSpan<const uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
2871
0
  if (Address.size() != InnerAddress->buf_len) {
2872
0
    return __WASI_ERRNO_FAULT;
2873
0
  }
2874
2875
0
  __wasi_address_family_t WasiAddressFamily;
2876
0
  switch (Address.size()) {
2877
0
  case 4:
2878
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET4;
2879
0
    break;
2880
0
  case 16:
2881
0
    WasiAddressFamily = __WASI_ADDRESS_FAMILY_INET6;
2882
0
    break;
2883
0
  case 128: {
2884
0
    auto &Storage =
2885
0
        *reinterpret_cast<const WASI::WasiAddrStorage *>(Address.data());
2886
0
    WasiAddressFamily = Storage.getAddressFamily();
2887
0
    Address = Storage.getAddress();
2888
0
    break;
2889
0
  }
2890
0
  default:
2891
0
    return __WASI_ERRNO_INVAL;
2892
0
  }
2893
2894
0
  __wasi_siflags_t WasiSiFlags;
2895
0
  if (auto Res = cast<__wasi_siflags_t>(SiFlags); unlikely(!Res)) {
2896
0
    return Res.error();
2897
0
  } else {
2898
0
    WasiSiFlags = *Res;
2899
0
  }
2900
2901
0
  const __wasi_size_t WasiSiDataLen = SiDataLen;
2902
0
  if (unlikely(WasiSiDataLen > WASI::kIOVMax)) {
2903
0
    return __WASI_ERRNO_INVAL;
2904
0
  }
2905
2906
  // Check for invalid address.
2907
0
  const auto SiDataArray =
2908
0
      MemInst->getSpan<__wasi_ciovec_t>(SiDataPtr, WasiSiDataLen);
2909
0
  if (unlikely(SiDataArray.size() != WasiSiDataLen)) {
2910
0
    return __WASI_ERRNO_FAULT;
2911
0
  }
2912
2913
0
  auto *const SoDataLen = MemInst->getPointer<__wasi_size_t *>(SoDataLenPtr);
2914
0
  if (unlikely(SoDataLen == nullptr)) {
2915
0
    return __WASI_ERRNO_FAULT;
2916
0
  }
2917
2918
0
  __wasi_size_t TotalSize = 0;
2919
0
  StaticVector<Span<const uint8_t>, WASI::kIOVMax> WasiSiData;
2920
2921
0
  for (auto &SiData : SiDataArray) {
2922
    // Capping total size.
2923
0
    const __wasi_size_t Space =
2924
0
        std::numeric_limits<__wasi_size_t>::max() - TotalSize;
2925
0
    const __wasi_size_t BufLen =
2926
0
        unlikely(SiData.buf_len > Space) ? Space : SiData.buf_len;
2927
0
    TotalSize += BufLen;
2928
2929
    // Check for invalid address.
2930
0
    const auto SiDataArr = MemInst->getSpan<uint8_t>(SiData.buf, BufLen);
2931
0
    if (unlikely(SiDataArr.size() != BufLen)) {
2932
0
      return __WASI_ERRNO_FAULT;
2933
0
    }
2934
0
    WasiSiData.emplace_back_unchecked(SiDataArr);
2935
0
  }
2936
2937
0
  const __wasi_fd_t WasiFd = Fd;
2938
2939
0
  if (auto Res =
2940
0
          Env.sockSendTo(WasiFd, WasiSiData, WasiSiFlags, WasiAddressFamily,
2941
0
                         Address, static_cast<uint16_t>(Port), *SoDataLen);
2942
0
      unlikely(!Res)) {
2943
0
    return Res.error();
2944
0
  }
2945
2946
0
  return __WASI_ERRNO_SUCCESS;
2947
0
}
2948
2949
Expect<uint32_t> WasiSockGetOpt::body(const Runtime::CallingFrame &Frame,
2950
                                      int32_t Fd, uint32_t SockOptLevel,
2951
                                      uint32_t SockOptName, uint32_t FlagPtr,
2952
0
                                      uint32_t FlagSizePtr) {
2953
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2954
0
  if (MemInst == nullptr) {
2955
0
    return __WASI_ERRNO_FAULT;
2956
0
  }
2957
2958
0
  __wasi_sock_opt_level_t WasiSockOptLevel;
2959
0
  if (auto Res = cast<__wasi_sock_opt_level_t>(SockOptLevel); unlikely(!Res)) {
2960
0
    return Res.error();
2961
0
  } else {
2962
0
    WasiSockOptLevel = *Res;
2963
0
  }
2964
2965
0
  __wasi_sock_opt_so_t WasiSockOptName;
2966
0
  if (auto Res = cast<__wasi_sock_opt_so_t>(SockOptName); unlikely(!Res)) {
2967
0
    return Res.error();
2968
0
  } else {
2969
0
    WasiSockOptName = *Res;
2970
0
  }
2971
2972
0
  auto *const SysFlagSizePtr = MemInst->getPointer<uint32_t *>(FlagSizePtr);
2973
0
  if (SysFlagSizePtr == nullptr) {
2974
0
    return __WASI_ERRNO_FAULT;
2975
0
  }
2976
2977
0
  auto Flag = MemInst->getSpan<uint8_t>(FlagPtr, *SysFlagSizePtr);
2978
0
  if (Flag.size() != *SysFlagSizePtr) {
2979
0
    return __WASI_ERRNO_FAULT;
2980
0
  }
2981
2982
0
  const __wasi_fd_t WasiFd = Fd;
2983
2984
0
  if (auto Res =
2985
0
          Env.sockGetOpt(WasiFd, WasiSockOptLevel, WasiSockOptName, Flag);
2986
0
      unlikely(!Res)) {
2987
0
    return Res.error();
2988
0
  }
2989
2990
0
  *SysFlagSizePtr = static_cast<uint32_t>(Flag.size());
2991
0
  return __WASI_ERRNO_SUCCESS;
2992
0
}
2993
2994
Expect<uint32_t>
2995
WasiSockGetLocalAddrV2::body(const Runtime::CallingFrame &Frame, int32_t Fd,
2996
0
                             uint32_t AddressPtr, uint32_t PortPtr) {
2997
0
  auto *MemInst = Frame.getMemoryByIndex(0);
2998
0
  if (MemInst == nullptr) {
2999
0
    return __WASI_ERRNO_FAULT;
3000
0
  }
3001
0
  __wasi_address_t *InnerAddress =
3002
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
3003
0
  if (InnerAddress == nullptr) {
3004
0
    return __WASI_ERRNO_FAULT;
3005
0
  }
3006
3007
0
  auto Address =
3008
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
3009
0
  if (Address.size() != InnerAddress->buf_len) {
3010
0
    return __WASI_ERRNO_FAULT;
3011
0
  }
3012
3013
0
  uint32_t *const RoPort = MemInst->getPointer<uint32_t *>(PortPtr);
3014
0
  if (RoPort == nullptr) {
3015
0
    return __WASI_ERRNO_FAULT;
3016
0
  }
3017
3018
0
  if (Address.size() != 128) {
3019
0
    return __WASI_ERRNO_INVAL;
3020
0
  }
3021
3022
0
  const __wasi_fd_t WasiFd = Fd;
3023
0
  WASI::WasiAddrStorage &Storage =
3024
0
      *reinterpret_cast<WASI::WasiAddrStorage *>(Address.data());
3025
0
  Address = Storage.getAddress();
3026
0
  __wasi_address_family_t WasiAddressFamily;
3027
0
  uint16_t Port;
3028
3029
0
  if (auto Res =
3030
0
          Env.sockGetLocalAddr(WasiFd, &WasiAddressFamily, Address, &Port);
3031
0
      unlikely(!Res)) {
3032
0
    return Res.error();
3033
0
  }
3034
3035
0
  Storage.setAddressFamily(WasiAddressFamily);
3036
0
  *RoPort = Port;
3037
0
  return __WASI_ERRNO_SUCCESS;
3038
0
}
3039
3040
Expect<uint32_t> WasiSockGetPeerAddrV2::body(const Runtime::CallingFrame &Frame,
3041
                                             int32_t Fd, uint32_t AddressPtr,
3042
0
                                             uint32_t PortPtr) {
3043
0
  auto *MemInst = Frame.getMemoryByIndex(0);
3044
0
  if (MemInst == nullptr) {
3045
0
    return __WASI_ERRNO_FAULT;
3046
0
  }
3047
0
  __wasi_address_t *InnerAddress =
3048
0
      MemInst->getPointer<__wasi_address_t *>(AddressPtr);
3049
0
  if (InnerAddress == nullptr) {
3050
0
    return __WASI_ERRNO_FAULT;
3051
0
  }
3052
3053
0
  auto Address =
3054
0
      MemInst->getSpan<uint8_t>(InnerAddress->buf, InnerAddress->buf_len);
3055
0
  if (Address.size() != InnerAddress->buf_len) {
3056
0
    return __WASI_ERRNO_FAULT;
3057
0
  }
3058
3059
0
  uint32_t *const RoPort = MemInst->getPointer<uint32_t *>(PortPtr);
3060
0
  if (RoPort == nullptr) {
3061
0
    return __WASI_ERRNO_FAULT;
3062
0
  }
3063
3064
0
  if (Address.size() != 128) {
3065
0
    return __WASI_ERRNO_INVAL;
3066
0
  }
3067
3068
0
  const __wasi_fd_t WasiFd = Fd;
3069
0
  WASI::WasiAddrStorage &Storage =
3070
0
      *reinterpret_cast<WASI::WasiAddrStorage *>(Address.data());
3071
0
  Address = Storage.getAddress();
3072
0
  __wasi_address_family_t WasiAddressFamily;
3073
0
  uint16_t Port;
3074
3075
0
  if (auto Res =
3076
0
          Env.sockGetPeerAddr(WasiFd, &WasiAddressFamily, Address, &Port);
3077
0
      unlikely(!Res)) {
3078
0
    return Res.error();
3079
0
  }
3080
0
  Storage.setAddressFamily(WasiAddressFamily);
3081
0
  *RoPort = Port;
3082
0
  return __WASI_ERRNO_SUCCESS;
3083
0
}
3084
} // namespace Host
3085
} // namespace WasmEdge