libc_uvwasi_wrapper.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "uvwasi.h"
  6. #include "bh_platform.h"
  7. #include "wasm_export.h"
  8. /* clang-format off */
  9. #define get_module_inst(exec_env) \
  10. wasm_runtime_get_module_inst(exec_env)
  11. #define validate_app_addr(offset, size) \
  12. wasm_runtime_validate_app_addr(module_inst, offset, size)
  13. #define validate_native_addr(addr, size) \
  14. wasm_runtime_validate_native_addr(module_inst, addr, size)
  15. #define addr_app_to_native(offset) \
  16. wasm_runtime_addr_app_to_native(module_inst, offset)
  17. #define addr_native_to_app(ptr) \
  18. wasm_runtime_addr_native_to_app(module_inst, ptr)
  19. #define module_malloc(size, p_native_addr) \
  20. wasm_runtime_module_malloc(module_inst, size, p_native_addr)
  21. #define module_free(offset) \
  22. wasm_runtime_module_free(module_inst, offset)
  23. /* clang-format on */
  24. // uvwasi_errno_t is typedef'd to uint16 which is correct according to the ABI
  25. // specification. However, in WASM, the smallest integer type is int32. If we
  26. // return uint16, we would rely on language SDKs to implement the correct
  27. // behaviour of casting to uint16 before checking the value or using it any way.
  28. // Failure to do so can cause tricky bugs as the upper 16 bits of the error
  29. // result are not guaranteed to be zero'ed by us so the result essentially
  30. // contains garbage from the WASM app perspective. To prevent this, we return
  31. // uint32 directly instead so as not to be reliant on the correct behaviour of
  32. // any current/future SDK implementations.
  33. #define wasi_errno_t uint32_t
  34. #define wasi_fd_t uvwasi_fd_t
  35. #define wasi_clockid_t uvwasi_clockid_t
  36. #define wasi_timestamp_t uvwasi_timestamp_t
  37. #define wasi_filesize_t uvwasi_filesize_t
  38. #define wasi_prestat_app_t uvwasi_prestat_app_t
  39. #define wasi_filedelta_t uvwasi_filedelta_t
  40. #define wasi_whence_t uvwasi_whence_t
  41. #define wasi_fdflags_t uvwasi_fdflags_t
  42. #define wasi_rights_t uvwasi_rights_t
  43. #define wasi_advice_t uvwasi_advice_t
  44. #define wasi_lookupflags_t uvwasi_lookupflags_t
  45. #define wasi_preopentype_t uvwasi_preopentype_t
  46. #define wasi_fdstat_t uvwasi_fdstat_t
  47. #define wasi_oflags_t uvwasi_oflags_t
  48. #define wasi_dircookie_t uvwasi_dircookie_t
  49. #define wasi_filestat_t uvwasi_filestat_t
  50. #define wasi_fstflags_t uvwasi_fstflags_t
  51. #define wasi_subscription_t uvwasi_subscription_t
  52. #define wasi_event_t uvwasi_event_t
  53. #define wasi_exitcode_t uvwasi_exitcode_t
  54. #define wasi_signal_t uvwasi_signal_t
  55. #define wasi_riflags_t uvwasi_riflags_t
  56. #define wasi_roflags_t uvwasi_roflags_t
  57. #define wasi_siflags_t uvwasi_siflags_t
  58. #define wasi_sdflags_t uvwasi_sdflags_t
  59. #define wasi_iovec_t uvwasi_iovec_t
  60. #define wasi_ciovec_t uvwasi_ciovec_t
  61. typedef struct wasi_prestat_app {
  62. wasi_preopentype_t pr_type;
  63. uint32 pr_name_len;
  64. } wasi_prestat_app_t;
  65. typedef struct iovec_app {
  66. uint32 buf_offset;
  67. uint32 buf_len;
  68. } iovec_app_t;
  69. typedef struct WASIContext {
  70. uvwasi_t uvwasi;
  71. uint32_t exit_code;
  72. } WASIContext;
  73. void *
  74. wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
  75. static uvwasi_t *
  76. get_wasi_ctx(wasm_module_inst_t module_inst)
  77. {
  78. WASIContext *ctx = wasm_runtime_get_wasi_ctx(module_inst);
  79. if (ctx == NULL) {
  80. return NULL;
  81. }
  82. return &ctx->uvwasi;
  83. }
  84. static wasi_errno_t
  85. wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
  86. {
  87. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  88. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  89. uvwasi_size_t argc, argv_buf_size, i;
  90. char **argv;
  91. uint64 total_size;
  92. wasi_errno_t err;
  93. if (!uvwasi)
  94. return (wasi_errno_t)-1;
  95. err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size);
  96. if (err)
  97. return err;
  98. total_size = sizeof(int32) * ((uint64)argc + 1);
  99. if (total_size >= UINT32_MAX
  100. || !validate_native_addr(argv_offsets, total_size)
  101. || argv_buf_size >= UINT32_MAX
  102. || !validate_native_addr(argv_buf, (uint64)argv_buf_size))
  103. return (wasi_errno_t)-1;
  104. total_size = sizeof(char *) * ((uint64)argc + 1);
  105. if (total_size >= UINT32_MAX
  106. || !(argv = wasm_runtime_malloc((uint32)total_size)))
  107. return (wasi_errno_t)-1;
  108. err = uvwasi_args_get(uvwasi, argv, argv_buf);
  109. if (err) {
  110. wasm_runtime_free(argv);
  111. return err;
  112. }
  113. for (i = 0; i < argc; i++)
  114. argv_offsets[i] = (uint32)addr_native_to_app(argv[i]);
  115. wasm_runtime_free(argv);
  116. return 0;
  117. }
  118. static wasi_errno_t
  119. wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
  120. uint32 *argv_buf_size_app)
  121. {
  122. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  123. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  124. uvwasi_size_t argc, argv_buf_size;
  125. wasi_errno_t err;
  126. if (!uvwasi)
  127. return (wasi_errno_t)-1;
  128. if (!validate_native_addr(argc_app, (uint64)sizeof(uint32))
  129. || !validate_native_addr(argv_buf_size_app, (uint64)sizeof(uint32)))
  130. return (wasi_errno_t)-1;
  131. err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size);
  132. if (err)
  133. return err;
  134. *argc_app = (uint32)argc;
  135. *argv_buf_size_app = (uint32)argv_buf_size;
  136. return 0;
  137. }
  138. static wasi_errno_t
  139. wasi_clock_res_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
  140. wasi_timestamp_t *resolution)
  141. {
  142. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  143. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  144. if (!validate_native_addr(resolution, (uint64)sizeof(wasi_timestamp_t)))
  145. return (wasi_errno_t)-1;
  146. return uvwasi_clock_res_get(uvwasi, clock_id, resolution);
  147. }
  148. static wasi_errno_t
  149. wasi_clock_time_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
  150. wasi_timestamp_t precision, wasi_timestamp_t *time)
  151. {
  152. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  153. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  154. if (!validate_native_addr(time, (uint64)sizeof(wasi_timestamp_t)))
  155. return (wasi_errno_t)-1;
  156. return uvwasi_clock_time_get(uvwasi, clock_id, precision, time);
  157. }
  158. static wasi_errno_t
  159. wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
  160. char *environ_buf)
  161. {
  162. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  163. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  164. uvwasi_size_t environ_count, environ_buf_size, i;
  165. uint64 total_size;
  166. char **environs;
  167. wasi_errno_t err;
  168. if (!uvwasi)
  169. return (wasi_errno_t)-1;
  170. err = uvwasi_environ_sizes_get(uvwasi, &environ_count, &environ_buf_size);
  171. if (err)
  172. return err;
  173. if (environ_count == 0)
  174. return 0;
  175. total_size = sizeof(int32) * ((uint64)environ_count + 1);
  176. if (total_size >= UINT32_MAX
  177. || !validate_native_addr(environ_offsets, total_size)
  178. || environ_buf_size >= UINT32_MAX
  179. || !validate_native_addr(environ_buf, (uint64)environ_buf_size))
  180. return (wasi_errno_t)-1;
  181. total_size = sizeof(char *) * (((uint64)environ_count + 1));
  182. if (total_size >= UINT32_MAX
  183. || !(environs = wasm_runtime_malloc((uint32)total_size)))
  184. return (wasi_errno_t)-1;
  185. err = uvwasi_environ_get(uvwasi, environs, environ_buf);
  186. if (err) {
  187. wasm_runtime_free(environs);
  188. return err;
  189. }
  190. for (i = 0; i < environ_count; i++)
  191. environ_offsets[i] = (uint32)addr_native_to_app(environs[i]);
  192. wasm_runtime_free(environs);
  193. return 0;
  194. }
  195. static wasi_errno_t
  196. wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
  197. uint32 *environ_buf_size_app)
  198. {
  199. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  200. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  201. uvwasi_size_t environ_count, environ_buf_size;
  202. wasi_errno_t err;
  203. if (!uvwasi)
  204. return (wasi_errno_t)-1;
  205. if (!validate_native_addr(environ_count_app, (uint64)sizeof(uint32))
  206. || !validate_native_addr(environ_buf_size_app, (uint64)sizeof(uint32)))
  207. return (wasi_errno_t)-1;
  208. err = uvwasi_environ_sizes_get(uvwasi, &environ_count, &environ_buf_size);
  209. if (err)
  210. return err;
  211. *environ_count_app = (uint32)environ_count;
  212. *environ_buf_size_app = (uint32)environ_buf_size;
  213. return 0;
  214. }
  215. static wasi_errno_t
  216. wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  217. wasi_prestat_app_t *prestat_app)
  218. {
  219. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  220. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  221. uvwasi_prestat_t prestat;
  222. wasi_errno_t err;
  223. if (!uvwasi)
  224. return (wasi_errno_t)-1;
  225. if (!validate_native_addr(prestat_app, (uint64)sizeof(wasi_prestat_app_t)))
  226. return (wasi_errno_t)-1;
  227. err = uvwasi_fd_prestat_get(uvwasi, fd, &prestat);
  228. if (err)
  229. return err;
  230. prestat_app->pr_type = prestat.pr_type;
  231. prestat_app->pr_name_len = (uint32)prestat.u.dir.pr_name_len;
  232. return 0;
  233. }
  234. static wasi_errno_t
  235. wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
  236. uint32 path_len)
  237. {
  238. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  239. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  240. if (!uvwasi)
  241. return (wasi_errno_t)-1;
  242. return uvwasi_fd_prestat_dir_name(uvwasi, fd, path, path_len);
  243. }
  244. static wasi_errno_t
  245. wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
  246. {
  247. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  248. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  249. if (!uvwasi)
  250. return (wasi_errno_t)-1;
  251. return uvwasi_fd_close(uvwasi, fd);
  252. }
  253. static wasi_errno_t
  254. wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
  255. {
  256. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  257. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  258. if (!uvwasi)
  259. return (wasi_errno_t)-1;
  260. return uvwasi_fd_datasync(uvwasi, fd);
  261. }
  262. static wasi_errno_t
  263. wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
  264. uint32 iovs_len, wasi_filesize_t offset, uint32 *nread_app)
  265. {
  266. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  267. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  268. wasi_iovec_t *iovec, *iovec_begin;
  269. uint64 total_size;
  270. uvwasi_size_t nread;
  271. uint32 i;
  272. wasi_errno_t err;
  273. if (!uvwasi)
  274. return (wasi_errno_t)-1;
  275. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  276. if (!validate_native_addr(nread_app, (uint64)sizeof(uint32))
  277. || total_size >= UINT32_MAX
  278. || !validate_native_addr(iovec_app, total_size))
  279. return (wasi_errno_t)-1;
  280. total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
  281. if (total_size >= UINT32_MAX
  282. || !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
  283. return (wasi_errno_t)-1;
  284. iovec = iovec_begin;
  285. for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) {
  286. if (!validate_app_addr((uint64)iovec_app->buf_offset,
  287. (uint64)iovec_app->buf_len)) {
  288. err = (wasi_errno_t)-1;
  289. goto fail;
  290. }
  291. iovec->buf = (void *)addr_app_to_native((uint64)iovec_app->buf_offset);
  292. iovec->buf_len = iovec_app->buf_len;
  293. }
  294. err = uvwasi_fd_pread(uvwasi, fd, iovec_begin, iovs_len, offset, &nread);
  295. if (err)
  296. goto fail;
  297. *nread_app = (uint32)nread;
  298. /* success */
  299. err = 0;
  300. fail:
  301. wasm_runtime_free(iovec_begin);
  302. return err;
  303. }
  304. static wasi_errno_t
  305. wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
  306. const iovec_app_t *iovec_app, uint32 iovs_len,
  307. wasi_filesize_t offset, uint32 *nwritten_app)
  308. {
  309. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  310. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  311. wasi_ciovec_t *ciovec, *ciovec_begin;
  312. uint64 total_size;
  313. uvwasi_size_t nwritten;
  314. uint32 i;
  315. wasi_errno_t err;
  316. if (!uvwasi)
  317. return (wasi_errno_t)-1;
  318. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  319. if (!validate_native_addr(nwritten_app, (uint64)sizeof(uint32))
  320. || total_size >= UINT32_MAX
  321. || !validate_native_addr((void *)iovec_app, total_size))
  322. return (wasi_errno_t)-1;
  323. total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
  324. if (total_size >= UINT32_MAX
  325. || !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
  326. return (wasi_errno_t)-1;
  327. ciovec = ciovec_begin;
  328. for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) {
  329. if (!validate_app_addr((uint64)iovec_app->buf_offset,
  330. (uint64)iovec_app->buf_len)) {
  331. err = (wasi_errno_t)-1;
  332. goto fail;
  333. }
  334. ciovec->buf = (char *)addr_app_to_native((uint64)iovec_app->buf_offset);
  335. ciovec->buf_len = iovec_app->buf_len;
  336. }
  337. err =
  338. uvwasi_fd_pwrite(uvwasi, fd, ciovec_begin, iovs_len, offset, &nwritten);
  339. if (err)
  340. goto fail;
  341. *nwritten_app = (uint32)nwritten;
  342. /* success */
  343. err = 0;
  344. fail:
  345. wasm_runtime_free(ciovec_begin);
  346. return err;
  347. }
  348. static wasi_errno_t
  349. wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
  350. const iovec_app_t *iovec_app, uint32 iovs_len, uint32 *nread_app)
  351. {
  352. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  353. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  354. wasi_iovec_t *iovec, *iovec_begin;
  355. uint64 total_size;
  356. uvwasi_size_t nread;
  357. uint32 i;
  358. wasi_errno_t err;
  359. if (!uvwasi)
  360. return (wasi_errno_t)-1;
  361. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  362. if (!validate_native_addr(nread_app, (uint64)sizeof(uint32))
  363. || total_size >= UINT32_MAX
  364. || !validate_native_addr((void *)iovec_app, total_size))
  365. return (wasi_errno_t)-1;
  366. total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
  367. if (total_size >= UINT32_MAX
  368. || !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
  369. return (wasi_errno_t)-1;
  370. iovec = iovec_begin;
  371. for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) {
  372. if (!validate_app_addr((uint64)iovec_app->buf_offset,
  373. (uint64)iovec_app->buf_len)) {
  374. err = (wasi_errno_t)-1;
  375. goto fail;
  376. }
  377. iovec->buf = (void *)addr_app_to_native((uint64)iovec_app->buf_offset);
  378. iovec->buf_len = iovec_app->buf_len;
  379. }
  380. err = uvwasi_fd_read(uvwasi, fd, iovec_begin, iovs_len, &nread);
  381. if (err)
  382. goto fail;
  383. *nread_app = (uint32)nread;
  384. /* success */
  385. err = 0;
  386. fail:
  387. wasm_runtime_free(iovec_begin);
  388. return err;
  389. }
  390. static wasi_errno_t
  391. wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
  392. {
  393. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  394. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  395. if (!uvwasi)
  396. return (wasi_errno_t)-1;
  397. return uvwasi_fd_renumber(uvwasi, from, to);
  398. }
  399. static wasi_errno_t
  400. wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
  401. wasi_whence_t whence, wasi_filesize_t *newoffset)
  402. {
  403. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  404. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  405. if (!uvwasi)
  406. return (wasi_errno_t)-1;
  407. if (!validate_native_addr(newoffset, (uint64)sizeof(wasi_filesize_t)))
  408. return (wasi_errno_t)-1;
  409. return uvwasi_fd_seek(uvwasi, fd, offset, whence, newoffset);
  410. }
  411. static wasi_errno_t
  412. wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
  413. {
  414. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  415. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  416. if (!uvwasi)
  417. return (wasi_errno_t)-1;
  418. if (!validate_native_addr(newoffset, (uint64)sizeof(wasi_filesize_t)))
  419. return (wasi_errno_t)-1;
  420. return uvwasi_fd_tell(uvwasi, fd, newoffset);
  421. }
  422. static wasi_errno_t
  423. wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  424. wasi_fdstat_t *fdstat_app)
  425. {
  426. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  427. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  428. wasi_fdstat_t fdstat;
  429. wasi_errno_t err;
  430. if (!uvwasi)
  431. return (wasi_errno_t)-1;
  432. if (!validate_native_addr(fdstat_app, (uint64)sizeof(wasi_fdstat_t)))
  433. return (wasi_errno_t)-1;
  434. err = uvwasi_fd_fdstat_get(uvwasi, fd, &fdstat);
  435. if (err)
  436. return err;
  437. memcpy(fdstat_app, &fdstat, sizeof(wasi_fdstat_t));
  438. return 0;
  439. }
  440. static wasi_errno_t
  441. wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
  442. wasi_fdflags_t flags)
  443. {
  444. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  445. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  446. if (!uvwasi)
  447. return (wasi_errno_t)-1;
  448. return uvwasi_fd_fdstat_set_flags(uvwasi, fd, flags);
  449. }
  450. static wasi_errno_t
  451. wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
  452. wasi_rights_t fs_rights_base,
  453. wasi_rights_t fs_rights_inheriting)
  454. {
  455. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  456. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  457. if (!uvwasi)
  458. return (wasi_errno_t)-1;
  459. return uvwasi_fd_fdstat_set_rights(uvwasi, fd, fs_rights_base,
  460. fs_rights_inheriting);
  461. }
  462. static wasi_errno_t
  463. wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd)
  464. {
  465. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  466. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  467. if (!uvwasi)
  468. return (wasi_errno_t)-1;
  469. return uvwasi_fd_sync(uvwasi, fd);
  470. }
  471. static wasi_errno_t
  472. wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
  473. const iovec_app_t *iovec_app, uint32 iovs_len,
  474. uint32 *nwritten_app)
  475. {
  476. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  477. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  478. wasi_ciovec_t *ciovec, *ciovec_begin;
  479. uint64 total_size;
  480. uvwasi_size_t nwritten;
  481. uint32 i;
  482. wasi_errno_t err;
  483. if (!uvwasi)
  484. return (wasi_errno_t)-1;
  485. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  486. if (!validate_native_addr(nwritten_app, (uint64)sizeof(uint32))
  487. || total_size >= UINT32_MAX
  488. || !validate_native_addr((void *)iovec_app, total_size))
  489. return (wasi_errno_t)-1;
  490. total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
  491. if (total_size >= UINT32_MAX
  492. || !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
  493. return (wasi_errno_t)-1;
  494. ciovec = ciovec_begin;
  495. for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) {
  496. if (!validate_app_addr((uint64)iovec_app->buf_offset,
  497. (uint64)iovec_app->buf_len)) {
  498. err = (wasi_errno_t)-1;
  499. goto fail;
  500. }
  501. ciovec->buf = (char *)addr_app_to_native((uint64)iovec_app->buf_offset);
  502. ciovec->buf_len = iovec_app->buf_len;
  503. }
  504. #ifndef BH_VPRINTF
  505. err = uvwasi_fd_write(uvwasi, fd, ciovec_begin, iovs_len, &nwritten);
  506. #else
  507. /* redirect stdout/stderr output to BH_VPRINTF function */
  508. if (fd == 1 || fd == 2) {
  509. int i;
  510. const struct iovec *iov1 = (const struct iovec *)ciovec_begin;
  511. nwritten = 0;
  512. for (i = 0; i < (int)iovs_len; i++, iov1++) {
  513. if (iov1->iov_len > 0 && iov1->iov_base) {
  514. char format[16];
  515. /* make up format string "%.ns" */
  516. snprintf(format, sizeof(format), "%%.%ds", (int)iov1->iov_len);
  517. nwritten += (uvwasi_size_t)os_printf(format, iov1->iov_base);
  518. }
  519. }
  520. err = 0;
  521. }
  522. else {
  523. err = uvwasi_fd_write(uvwasi, fd, ciovec_begin, iovs_len, &nwritten);
  524. }
  525. #endif /* end of BH_VPRINTF */
  526. if (err)
  527. goto fail;
  528. *nwritten_app = (uint32)nwritten;
  529. /* success */
  530. err = 0;
  531. fail:
  532. wasm_runtime_free(ciovec_begin);
  533. return err;
  534. }
  535. static wasi_errno_t
  536. wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
  537. wasi_filesize_t len, wasi_advice_t advice)
  538. {
  539. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  540. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  541. if (!uvwasi)
  542. return (wasi_errno_t)-1;
  543. return uvwasi_fd_advise(uvwasi, fd, offset, len, advice);
  544. }
  545. static wasi_errno_t
  546. wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
  547. wasi_filesize_t len)
  548. {
  549. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  550. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  551. if (!uvwasi)
  552. return (wasi_errno_t)-1;
  553. return uvwasi_fd_allocate(uvwasi, fd, offset, len);
  554. }
  555. static wasi_errno_t
  556. wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
  557. const char *path, uint32 path_len)
  558. {
  559. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  560. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  561. if (!uvwasi)
  562. return (wasi_errno_t)-1;
  563. return uvwasi_path_create_directory(uvwasi, fd, path, path_len);
  564. }
  565. static wasi_errno_t
  566. wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
  567. wasi_lookupflags_t old_flags, const char *old_path,
  568. uint32 old_path_len, wasi_fd_t new_fd, const char *new_path,
  569. uint32 new_path_len)
  570. {
  571. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  572. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  573. if (!uvwasi)
  574. return (wasi_errno_t)-1;
  575. return uvwasi_path_link(uvwasi, old_fd, old_flags, old_path, old_path_len,
  576. new_fd, new_path, new_path_len);
  577. }
  578. static wasi_errno_t
  579. wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
  580. wasi_lookupflags_t dirflags, const char *path, uint32 path_len,
  581. wasi_oflags_t oflags, wasi_rights_t fs_rights_base,
  582. wasi_rights_t fs_rights_inheriting, wasi_fdflags_t fs_flags,
  583. wasi_fd_t *fd_app)
  584. {
  585. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  586. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  587. wasi_fd_t fd = (wasi_fd_t)-1; /* set fd_app -1 if path open failed */
  588. wasi_errno_t err;
  589. if (!uvwasi)
  590. return (wasi_errno_t)-1;
  591. if (!validate_native_addr(fd_app, (uint64)sizeof(wasi_fd_t)))
  592. return (wasi_errno_t)-1;
  593. err = uvwasi_path_open(uvwasi, dirfd, dirflags, path, path_len, oflags,
  594. fs_rights_base, fs_rights_inheriting, fs_flags, &fd);
  595. *fd_app = fd;
  596. return err;
  597. }
  598. static wasi_errno_t
  599. wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
  600. uint32 buf_len, wasi_dircookie_t cookie, uint32 *bufused_app)
  601. {
  602. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  603. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  604. uvwasi_size_t bufused;
  605. wasi_errno_t err;
  606. if (!uvwasi)
  607. return (wasi_errno_t)-1;
  608. if (!validate_native_addr(bufused_app, (uint64)sizeof(uint32)))
  609. return (wasi_errno_t)-1;
  610. err = uvwasi_fd_readdir(uvwasi, fd, buf, buf_len, cookie, &bufused);
  611. if (err)
  612. return err;
  613. *bufused_app = (uint32)bufused;
  614. return 0;
  615. }
  616. static wasi_errno_t
  617. wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
  618. uint32 path_len, char *buf, uint32 buf_len,
  619. uint32 *bufused_app)
  620. {
  621. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  622. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  623. uvwasi_size_t bufused;
  624. wasi_errno_t err;
  625. if (!uvwasi)
  626. return (wasi_errno_t)-1;
  627. if (!validate_native_addr(bufused_app, (uint64)sizeof(uint32)))
  628. return (wasi_errno_t)-1;
  629. err = uvwasi_path_readlink(uvwasi, fd, path, path_len, buf, buf_len,
  630. &bufused);
  631. if (err)
  632. return err;
  633. *bufused_app = (uint32)bufused;
  634. return 0;
  635. }
  636. static wasi_errno_t
  637. wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
  638. const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
  639. const char *new_path, uint32 new_path_len)
  640. {
  641. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  642. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  643. if (!uvwasi)
  644. return (wasi_errno_t)-1;
  645. return uvwasi_path_rename(uvwasi, old_fd, old_path, old_path_len, new_fd,
  646. new_path, new_path_len);
  647. }
  648. static wasi_errno_t
  649. wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  650. wasi_filestat_t *filestat)
  651. {
  652. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  653. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  654. if (!uvwasi)
  655. return (wasi_errno_t)-1;
  656. if (!validate_native_addr(filestat, (uint64)sizeof(wasi_filestat_t)))
  657. return (wasi_errno_t)-1;
  658. return uvwasi_fd_filestat_get(uvwasi, fd, filestat);
  659. }
  660. static wasi_errno_t
  661. wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
  662. wasi_timestamp_t st_atim, wasi_timestamp_t st_mtim,
  663. wasi_fstflags_t fstflags)
  664. {
  665. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  666. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  667. if (!uvwasi)
  668. return (wasi_errno_t)-1;
  669. return uvwasi_fd_filestat_set_times(uvwasi, fd, st_atim, st_mtim, fstflags);
  670. }
  671. static wasi_errno_t
  672. wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
  673. wasi_filesize_t st_size)
  674. {
  675. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  676. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  677. if (!uvwasi)
  678. return (wasi_errno_t)-1;
  679. return uvwasi_fd_filestat_set_size(uvwasi, fd, st_size);
  680. }
  681. static wasi_errno_t
  682. wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  683. wasi_lookupflags_t flags, const char *path,
  684. uint32 path_len, wasi_filestat_t *filestat)
  685. {
  686. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  687. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  688. if (!uvwasi)
  689. return (wasi_errno_t)-1;
  690. if (!validate_native_addr(filestat, (uint64)sizeof(wasi_filestat_t)))
  691. return (wasi_errno_t)-1;
  692. return uvwasi_path_filestat_get(uvwasi, fd, flags, path, path_len,
  693. filestat);
  694. }
  695. static wasi_errno_t
  696. wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
  697. wasi_lookupflags_t flags, const char *path,
  698. uint32 path_len, wasi_timestamp_t st_atim,
  699. wasi_timestamp_t st_mtim, wasi_fstflags_t fstflags)
  700. {
  701. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  702. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  703. if (!uvwasi)
  704. return (wasi_errno_t)-1;
  705. return uvwasi_path_filestat_set_times(uvwasi, fd, flags, path, path_len,
  706. st_atim, st_mtim, fstflags);
  707. }
  708. static wasi_errno_t
  709. wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
  710. uint32 old_path_len, wasi_fd_t fd, const char *new_path,
  711. uint32 new_path_len)
  712. {
  713. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  714. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  715. if (!uvwasi)
  716. return (wasi_errno_t)-1;
  717. return uvwasi_path_symlink(uvwasi, old_path, old_path_len, fd, new_path,
  718. new_path_len);
  719. }
  720. static wasi_errno_t
  721. wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
  722. uint32 path_len)
  723. {
  724. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  725. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  726. if (!uvwasi)
  727. return (wasi_errno_t)-1;
  728. return uvwasi_path_unlink_file(uvwasi, fd, path, path_len);
  729. }
  730. static wasi_errno_t
  731. wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
  732. const char *path, uint32 path_len)
  733. {
  734. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  735. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  736. if (!uvwasi)
  737. return (wasi_errno_t)-1;
  738. return uvwasi_path_remove_directory(uvwasi, fd, path, path_len);
  739. }
  740. static wasi_errno_t
  741. wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
  742. wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
  743. {
  744. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  745. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  746. uvwasi_size_t nevents;
  747. wasi_errno_t err;
  748. if (!uvwasi)
  749. return (wasi_errno_t)-1;
  750. if (!validate_native_addr((void *)in, (uint64)sizeof(wasi_subscription_t))
  751. || !validate_native_addr(out, (uint64)sizeof(wasi_event_t))
  752. || !validate_native_addr(nevents_app, (uint64)sizeof(uint32)))
  753. return (wasi_errno_t)-1;
  754. err = uvwasi_poll_oneoff(uvwasi, in, out, nsubscriptions, &nevents);
  755. if (err)
  756. return err;
  757. *nevents_app = (uint32)nevents;
  758. return 0;
  759. }
  760. static void
  761. wasi_proc_exit(wasm_exec_env_t exec_env, wasi_exitcode_t rval)
  762. {
  763. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  764. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  765. /* Here throwing exception is just to let wasm app exit,
  766. the upper layer should clear the exception and return
  767. as normal */
  768. wasm_runtime_set_exception(module_inst, "wasi proc exit");
  769. wasi_ctx->exit_code = rval;
  770. }
  771. static wasi_errno_t
  772. wasi_proc_raise(wasm_exec_env_t exec_env, wasi_signal_t sig)
  773. {
  774. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  775. char buf[32];
  776. snprintf(buf, sizeof(buf), "%s%d", "wasi proc raise ", sig);
  777. wasm_runtime_set_exception(module_inst, buf);
  778. return 0;
  779. }
  780. static wasi_errno_t
  781. wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
  782. {
  783. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  784. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  785. return uvwasi_random_get(uvwasi, buf, buf_len);
  786. }
  787. static wasi_errno_t
  788. wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
  789. uint32 ri_data_len, wasi_riflags_t ri_flags,
  790. uint32 *ro_datalen_app, wasi_roflags_t *ro_flags)
  791. {
  792. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  793. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  794. wasi_iovec_t *iovec, *iovec_begin;
  795. uint64 total_size;
  796. uvwasi_size_t ro_datalen;
  797. uint32 i;
  798. wasi_errno_t err;
  799. if (!uvwasi)
  800. return (wasi_errno_t)-1;
  801. total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
  802. if (!validate_native_addr(ro_datalen_app, (uint32)sizeof(uint32))
  803. || !validate_native_addr(ro_flags, (uint32)sizeof(wasi_roflags_t))
  804. || total_size >= UINT32_MAX
  805. || !validate_native_addr(ri_data, (uint32)total_size))
  806. return (wasi_errno_t)-1;
  807. total_size = sizeof(wasi_iovec_t) * (uint64)ri_data_len;
  808. if (total_size >= UINT32_MAX
  809. || !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
  810. return (wasi_errno_t)-1;
  811. iovec = iovec_begin;
  812. for (i = 0; i < ri_data_len; i++, ri_data++, iovec++) {
  813. if (!validate_app_addr((uint64)ri_data->buf_offset,
  814. (uint64)ri_data->buf_len)) {
  815. err = (wasi_errno_t)-1;
  816. goto fail;
  817. }
  818. iovec->buf = (void *)addr_app_to_native((uint64)ri_data->buf_offset);
  819. iovec->buf_len = ri_data->buf_len;
  820. }
  821. err = uvwasi_sock_recv(uvwasi, sock, iovec_begin, ri_data_len, ri_flags,
  822. &ro_datalen, ro_flags);
  823. if (err)
  824. goto fail;
  825. *(uint32 *)ro_datalen_app = (uint32)ro_datalen;
  826. /* success */
  827. err = 0;
  828. fail:
  829. wasm_runtime_free(iovec_begin);
  830. return err;
  831. }
  832. static wasi_errno_t
  833. wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
  834. const iovec_app_t *si_data, uint32 si_data_len,
  835. wasi_siflags_t si_flags, uint32 *so_datalen_app)
  836. {
  837. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  838. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  839. wasi_ciovec_t *ciovec, *ciovec_begin;
  840. uint64 total_size;
  841. uvwasi_size_t so_datalen;
  842. uint32 i;
  843. wasi_errno_t err;
  844. if (!uvwasi)
  845. return (wasi_errno_t)-1;
  846. total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
  847. if (!validate_native_addr(so_datalen_app, (uint64)sizeof(uint32))
  848. || total_size >= UINT32_MAX
  849. || !validate_native_addr((void *)si_data, total_size))
  850. return (wasi_errno_t)-1;
  851. total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len;
  852. if (total_size >= UINT32_MAX
  853. || !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
  854. return (wasi_errno_t)-1;
  855. ciovec = ciovec_begin;
  856. for (i = 0; i < si_data_len; i++, si_data++, ciovec++) {
  857. if (!validate_app_addr((uint64)si_data->buf_offset,
  858. (uint64)si_data->buf_len)) {
  859. err = (wasi_errno_t)-1;
  860. goto fail;
  861. }
  862. ciovec->buf = (char *)addr_app_to_native((uint64)si_data->buf_offset);
  863. ciovec->buf_len = si_data->buf_len;
  864. }
  865. err = uvwasi_sock_send(uvwasi, sock, ciovec_begin, si_data_len, si_flags,
  866. &so_datalen);
  867. if (err)
  868. goto fail;
  869. *so_datalen_app = (uint32)so_datalen;
  870. /* success */
  871. err = 0;
  872. fail:
  873. wasm_runtime_free(ciovec_begin);
  874. return err;
  875. }
  876. static wasi_errno_t
  877. wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
  878. {
  879. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  880. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  881. if (!uvwasi)
  882. return (wasi_errno_t)-1;
  883. return uvwasi_sock_shutdown(uvwasi, sock, how);
  884. }
  885. static wasi_errno_t
  886. wasi_sched_yield(wasm_exec_env_t exec_env)
  887. {
  888. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  889. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  890. return uvwasi_sched_yield(uvwasi);
  891. }
  892. /* clang-format off */
  893. #define REG_NATIVE_FUNC(func_name, signature) \
  894. { #func_name, wasi_##func_name, signature, NULL }
  895. /* clang-format on */
  896. static NativeSymbol native_symbols_libc_wasi[] = {
  897. REG_NATIVE_FUNC(args_get, "(**)i"),
  898. REG_NATIVE_FUNC(args_sizes_get, "(**)i"),
  899. REG_NATIVE_FUNC(clock_res_get, "(i*)i"),
  900. REG_NATIVE_FUNC(clock_time_get, "(iI*)i"),
  901. REG_NATIVE_FUNC(environ_get, "(**)i"),
  902. REG_NATIVE_FUNC(environ_sizes_get, "(**)i"),
  903. REG_NATIVE_FUNC(fd_prestat_get, "(i*)i"),
  904. REG_NATIVE_FUNC(fd_prestat_dir_name, "(i*~)i"),
  905. REG_NATIVE_FUNC(fd_close, "(i)i"),
  906. REG_NATIVE_FUNC(fd_datasync, "(i)i"),
  907. REG_NATIVE_FUNC(fd_pread, "(i*iI*)i"),
  908. REG_NATIVE_FUNC(fd_pwrite, "(i*iI*)i"),
  909. REG_NATIVE_FUNC(fd_read, "(i*i*)i"),
  910. REG_NATIVE_FUNC(fd_renumber, "(ii)i"),
  911. REG_NATIVE_FUNC(fd_seek, "(iIi*)i"),
  912. REG_NATIVE_FUNC(fd_tell, "(i*)i"),
  913. REG_NATIVE_FUNC(fd_fdstat_get, "(i*)i"),
  914. REG_NATIVE_FUNC(fd_fdstat_set_flags, "(ii)i"),
  915. REG_NATIVE_FUNC(fd_fdstat_set_rights, "(iII)i"),
  916. REG_NATIVE_FUNC(fd_sync, "(i)i"),
  917. REG_NATIVE_FUNC(fd_write, "(i*i*)i"),
  918. REG_NATIVE_FUNC(fd_advise, "(iIIi)i"),
  919. REG_NATIVE_FUNC(fd_allocate, "(iII)i"),
  920. REG_NATIVE_FUNC(path_create_directory, "(i*~)i"),
  921. REG_NATIVE_FUNC(path_link, "(ii*~i*~)i"),
  922. REG_NATIVE_FUNC(path_open, "(ii*~iIIi*)i"),
  923. REG_NATIVE_FUNC(fd_readdir, "(i*~I*)i"),
  924. REG_NATIVE_FUNC(path_readlink, "(i*~*~*)i"),
  925. REG_NATIVE_FUNC(path_rename, "(i*~i*~)i"),
  926. REG_NATIVE_FUNC(fd_filestat_get, "(i*)i"),
  927. REG_NATIVE_FUNC(fd_filestat_set_times, "(iIIi)i"),
  928. REG_NATIVE_FUNC(fd_filestat_set_size, "(iI)i"),
  929. REG_NATIVE_FUNC(path_filestat_get, "(ii*~*)i"),
  930. REG_NATIVE_FUNC(path_filestat_set_times, "(ii*~IIi)i"),
  931. REG_NATIVE_FUNC(path_symlink, "(*~i*~)i"),
  932. REG_NATIVE_FUNC(path_unlink_file, "(i*~)i"),
  933. REG_NATIVE_FUNC(path_remove_directory, "(i*~)i"),
  934. REG_NATIVE_FUNC(poll_oneoff, "(**i*)i"),
  935. REG_NATIVE_FUNC(proc_exit, "(i)"),
  936. REG_NATIVE_FUNC(proc_raise, "(i)i"),
  937. REG_NATIVE_FUNC(random_get, "(*~)i"),
  938. REG_NATIVE_FUNC(sock_recv, "(i*ii**)i"),
  939. REG_NATIVE_FUNC(sock_send, "(i*ii*)i"),
  940. REG_NATIVE_FUNC(sock_shutdown, "(ii)i"),
  941. REG_NATIVE_FUNC(sched_yield, "()i"),
  942. };
  943. uint32
  944. get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis)
  945. {
  946. *p_libc_wasi_apis = native_symbols_libc_wasi;
  947. return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol);
  948. }