libc_wrapper.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_native.h"
  6. #include "wasm_export.h"
  7. #include "wasm_log.h"
  8. #include "wasm_platform_log.h"
  9. #include "bh_common.h"
  10. #if WASM_ENABLE_WASI != 0
  11. #include "wasi_wrapper.h"
  12. #endif
  13. void
  14. wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
  15. uint32
  16. wasm_runtime_get_temp_ret(wasm_module_inst_t module);
  17. void
  18. wasm_runtime_set_temp_ret(wasm_module_inst_t module, uint32 temp_ret);
  19. uint32
  20. wasm_runtime_get_llvm_stack(wasm_module_inst_t module);
  21. void
  22. wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack);
  23. #define validate_app_addr(offset, size) \
  24. wasm_runtime_validate_app_addr(module_inst, offset, size)
  25. #define validate_app_str_addr(offset) \
  26. wasm_runtime_validate_app_str_addr(module_inst, offset)
  27. #define addr_app_to_native(offset) \
  28. wasm_runtime_addr_app_to_native(module_inst, offset)
  29. #define addr_native_to_app(ptr) \
  30. wasm_runtime_addr_native_to_app(module_inst, ptr)
  31. #define module_malloc(size) \
  32. wasm_runtime_module_malloc(module_inst, size)
  33. #define module_free(offset) \
  34. wasm_runtime_module_free(module_inst, offset)
  35. typedef int (*out_func_t)(int c, void *ctx);
  36. enum pad_type {
  37. PAD_NONE,
  38. PAD_ZERO_BEFORE,
  39. PAD_SPACE_BEFORE,
  40. PAD_SPACE_AFTER,
  41. };
  42. typedef char *_va_list;
  43. #define _INTSIZEOF(n) \
  44. (((uint32)sizeof(n) + 3) & (uint32)~3)
  45. #define _va_arg(ap, t) \
  46. (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
  47. #define CHECK_VA_ARG(ap, t) do { \
  48. if ((uint8*)ap + _INTSIZEOF(t) > native_end_addr) \
  49. goto fail; \
  50. } while (0)
  51. /**
  52. * @brief Output an unsigned int in hex format
  53. *
  54. * Output an unsigned int on output installed by platform at init time. Should
  55. * be able to handle an unsigned int of any size, 32 or 64 bit.
  56. * @param num Number to output
  57. *
  58. * @return N/A
  59. */
  60. static void
  61. _printf_hex_uint(out_func_t out, void *ctx,
  62. const uint64 num, bool is_u64,
  63. enum pad_type padding,
  64. int min_width)
  65. {
  66. int size = sizeof(num) * (is_u64 ? 2 : 1);
  67. int found_largest_digit = 0;
  68. int remaining = 8; /* 8 digits max */
  69. int digits = 0;
  70. for (; size; size--) {
  71. char nibble = (num >> ((size - 1) << 2) & 0xf);
  72. if (nibble || found_largest_digit || size == 1) {
  73. found_largest_digit = 1;
  74. nibble = (char)(nibble + (nibble > 9 ? 87 : 48));
  75. out((int) nibble, ctx);
  76. digits++;
  77. continue;
  78. }
  79. if (remaining-- <= min_width) {
  80. if (padding == PAD_ZERO_BEFORE) {
  81. out('0', ctx);
  82. } else if (padding == PAD_SPACE_BEFORE) {
  83. out(' ', ctx);
  84. }
  85. }
  86. }
  87. if (padding == PAD_SPACE_AFTER) {
  88. remaining = min_width * 2 - digits;
  89. while (remaining-- > 0) {
  90. out(' ', ctx);
  91. }
  92. }
  93. }
  94. /**
  95. * @brief Output an unsigned int in decimal format
  96. *
  97. * Output an unsigned int on output installed by platform at init time. Only
  98. * works with 32-bit values.
  99. * @param num Number to output
  100. *
  101. * @return N/A
  102. */
  103. static void
  104. _printf_dec_uint(out_func_t out, void *ctx,
  105. const uint32 num,
  106. enum pad_type padding,
  107. int min_width)
  108. {
  109. uint32 pos = 999999999;
  110. uint32 remainder = num;
  111. int found_largest_digit = 0;
  112. int remaining = 10; /* 10 digits max */
  113. int digits = 1;
  114. /* make sure we don't skip if value is zero */
  115. if (min_width <= 0) {
  116. min_width = 1;
  117. }
  118. while (pos >= 9) {
  119. if (found_largest_digit || remainder > pos) {
  120. found_largest_digit = 1;
  121. out((int) ((remainder / (pos + 1)) + 48), ctx);
  122. digits++;
  123. } else if (remaining <= min_width && padding < PAD_SPACE_AFTER) {
  124. out((int) (padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx);
  125. digits++;
  126. }
  127. remaining--;
  128. remainder %= (pos + 1);
  129. pos /= 10;
  130. }
  131. out((int) (remainder + 48), ctx);
  132. if (padding == PAD_SPACE_AFTER) {
  133. remaining = min_width - digits;
  134. while (remaining-- > 0) {
  135. out(' ', ctx);
  136. }
  137. }
  138. }
  139. static void
  140. print_err(out_func_t out, void *ctx)
  141. {
  142. out('E', ctx);
  143. out('R', ctx);
  144. out('R', ctx);
  145. }
  146. static bool
  147. _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
  148. wasm_module_inst_t module_inst)
  149. {
  150. int might_format = 0; /* 1 if encountered a '%' */
  151. enum pad_type padding = PAD_NONE;
  152. int min_width = -1;
  153. int long_ctr = 0;
  154. uint8 *native_end_addr;
  155. if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)ap,
  156. NULL, &native_end_addr))
  157. goto fail;
  158. /* fmt has already been adjusted if needed */
  159. while (*fmt) {
  160. if (!might_format) {
  161. if (*fmt != '%') {
  162. out((int) *fmt, ctx);
  163. }
  164. else {
  165. might_format = 1;
  166. min_width = -1;
  167. padding = PAD_NONE;
  168. long_ctr = 0;
  169. }
  170. }
  171. else {
  172. switch (*fmt) {
  173. case '-':
  174. padding = PAD_SPACE_AFTER;
  175. goto still_might_format;
  176. case '0':
  177. if (min_width < 0 && padding == PAD_NONE) {
  178. padding = PAD_ZERO_BEFORE;
  179. goto still_might_format;
  180. }
  181. /* Fall through */
  182. case '1' ... '9':
  183. if (min_width < 0) {
  184. min_width = *fmt - '0';
  185. } else {
  186. min_width = 10 * min_width + *fmt - '0';
  187. }
  188. if (padding == PAD_NONE) {
  189. padding = PAD_SPACE_BEFORE;
  190. }
  191. goto still_might_format;
  192. case 'l':
  193. long_ctr++;
  194. /* Fall through */
  195. case 'z':
  196. case 'h':
  197. /* FIXME: do nothing for these modifiers */
  198. goto still_might_format;
  199. case 'd':
  200. case 'i': {
  201. int32 d;
  202. if (long_ctr < 2) {
  203. CHECK_VA_ARG(ap, int32);
  204. d = _va_arg(ap, int32);
  205. }
  206. else {
  207. int64 lld;
  208. CHECK_VA_ARG(ap, int64);
  209. lld = _va_arg(ap, int64);
  210. if (lld > INT32_MAX || lld < INT32_MIN) {
  211. print_err(out, ctx);
  212. break;
  213. }
  214. d = (int32)lld;
  215. }
  216. if (d < 0) {
  217. out((int)'-', ctx);
  218. d = -d;
  219. min_width--;
  220. }
  221. _printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
  222. break;
  223. }
  224. case 'u': {
  225. uint32 u;
  226. if (long_ctr < 2) {
  227. CHECK_VA_ARG(ap, uint32);
  228. u = _va_arg(ap, uint32);
  229. }
  230. else {
  231. uint64 llu;
  232. CHECK_VA_ARG(ap, uint64);
  233. llu = _va_arg(ap, uint64);
  234. if (llu > INT32_MAX) {
  235. print_err(out, ctx);
  236. break;
  237. }
  238. u = (uint32)llu;
  239. }
  240. _printf_dec_uint(out, ctx, u, padding, min_width);
  241. break;
  242. }
  243. case 'p':
  244. out('0', ctx);
  245. out('x', ctx);
  246. /* left-pad pointers with zeros */
  247. padding = PAD_ZERO_BEFORE;
  248. min_width = 8;
  249. /* Fall through */
  250. case 'x':
  251. case 'X': {
  252. uint64 x;
  253. bool is_ptr = (*fmt == 'p') ? true : false;
  254. if (long_ctr < 2) {
  255. CHECK_VA_ARG(ap, uint32);
  256. x = _va_arg(ap, uint32);
  257. } else {
  258. CHECK_VA_ARG(ap, uint64);
  259. x = _va_arg(ap, uint64);
  260. }
  261. _printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width);
  262. break;
  263. }
  264. case 's': {
  265. char *s;
  266. char *start;
  267. int32 s_offset;
  268. CHECK_VA_ARG(ap, int32);
  269. s_offset = _va_arg(ap, int32);
  270. if (!validate_app_str_addr(s_offset)) {
  271. return false;
  272. }
  273. s = start = addr_app_to_native(s_offset);
  274. while (*s)
  275. out((int) (*s++), ctx);
  276. if (padding == PAD_SPACE_AFTER) {
  277. int remaining = min_width - (int32)(s - start);
  278. while (remaining-- > 0) {
  279. out(' ', ctx);
  280. }
  281. }
  282. break;
  283. }
  284. case 'c': {
  285. int c;
  286. CHECK_VA_ARG(ap, int);
  287. c = _va_arg(ap, int);
  288. out(c, ctx);
  289. break;
  290. }
  291. case '%': {
  292. out((int) '%', ctx);
  293. break;
  294. }
  295. default:
  296. out((int) '%', ctx);
  297. out((int) *fmt, ctx);
  298. break;
  299. }
  300. might_format = 0;
  301. }
  302. still_might_format:
  303. ++fmt;
  304. }
  305. return true;
  306. fail:
  307. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  308. return false;
  309. }
  310. struct str_context {
  311. char *str;
  312. uint32 max;
  313. uint32 count;
  314. };
  315. static int
  316. sprintf_out(int c, struct str_context *ctx)
  317. {
  318. if (!ctx->str || ctx->count >= ctx->max) {
  319. ctx->count++;
  320. return c;
  321. }
  322. if (ctx->count == ctx->max - 1) {
  323. ctx->str[ctx->count++] = '\0';
  324. } else {
  325. ctx->str[ctx->count++] = (char)c;
  326. }
  327. return c;
  328. }
  329. static int
  330. printf_out(int c, struct str_context *ctx)
  331. {
  332. bh_printf("%c", c);
  333. ctx->count++;
  334. return c;
  335. }
  336. static inline _va_list
  337. get_va_list(uint32 *args)
  338. {
  339. union {
  340. uint32 u;
  341. _va_list v;
  342. } u;
  343. u.u = args[0];
  344. return u.v;
  345. }
  346. static bool
  347. parse_printf_args(wasm_module_inst_t module_inst, int32 fmt_offset,
  348. int32 va_list_offset, const char **p_fmt,
  349. _va_list *p_va_args)
  350. {
  351. const char *fmt;
  352. union {
  353. uintptr_t u;
  354. _va_list v;
  355. } u;
  356. if (!validate_app_str_addr(fmt_offset)
  357. || !validate_app_addr(va_list_offset, sizeof(int32)))
  358. return false;
  359. fmt = (const char*) addr_app_to_native(fmt_offset);
  360. u.u = (uintptr_t) addr_app_to_native(va_list_offset);
  361. *p_fmt = fmt;
  362. *p_va_args = u.v;
  363. return true;
  364. }
  365. static int
  366. _printf_wrapper(wasm_module_inst_t module_inst,
  367. int32 fmt_offset, int32 va_list_offset)
  368. {
  369. struct str_context ctx = { NULL, 0, 0 };
  370. const char *fmt;
  371. _va_list va_args;
  372. if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
  373. return 0;
  374. if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst))
  375. return 0;
  376. return (int)ctx.count;
  377. }
  378. static int
  379. _sprintf_wrapper(wasm_module_inst_t module_inst,
  380. int32 str_offset, int32 fmt_offset, int32 va_list_offset)
  381. {
  382. int32 app_end_offset;
  383. struct str_context ctx;
  384. char *str;
  385. const char *fmt;
  386. _va_list va_args;
  387. if (!wasm_runtime_get_app_addr_range(module_inst, str_offset,
  388. NULL, &app_end_offset)) {
  389. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  390. return false;
  391. }
  392. str = addr_app_to_native(str_offset);
  393. if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
  394. return 0;
  395. ctx.str = str;
  396. ctx.max = (uint32)(app_end_offset - str_offset);
  397. ctx.count = 0;
  398. if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst))
  399. return 0;
  400. if (ctx.count < ctx.max) {
  401. str[ctx.count] = '\0';
  402. }
  403. return (int)ctx.count;
  404. }
  405. static int
  406. _snprintf_wrapper(wasm_module_inst_t module_inst,
  407. int32 str_offset, uint32 size, int32 fmt_offset,
  408. int32 va_list_offset)
  409. {
  410. struct str_context ctx;
  411. char *str;
  412. const char *fmt;
  413. _va_list va_args;
  414. if (!validate_app_addr(str_offset, size))
  415. return 0;
  416. str = addr_app_to_native(str_offset);
  417. if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
  418. return 0;
  419. ctx.str = str;
  420. ctx.max = size;
  421. ctx.count = 0;
  422. if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst))
  423. return 0;
  424. if (ctx.count < ctx.max) {
  425. str[ctx.count] = '\0';
  426. }
  427. return (int)ctx.count;
  428. }
  429. static int
  430. _puts_wrapper(wasm_module_inst_t module_inst,
  431. int32 str_offset)
  432. {
  433. const char *str;
  434. if (!validate_app_str_addr(str_offset))
  435. return 0;
  436. str = addr_app_to_native(str_offset);
  437. return bh_printf("%s\n", str);
  438. }
  439. static int
  440. _putchar_wrapper(wasm_module_inst_t module_inst, int c)
  441. {
  442. bh_printf("%c", c);
  443. return 1;
  444. }
  445. static int32
  446. _strdup_wrapper(wasm_module_inst_t module_inst,
  447. int32 str_offset)
  448. {
  449. char *str, *str_ret;
  450. uint32 len;
  451. int32 str_ret_offset = 0;
  452. if (!validate_app_str_addr(str_offset))
  453. return 0;
  454. str = addr_app_to_native(str_offset);
  455. if (str) {
  456. len = (uint32)strlen(str) + 1;
  457. str_ret_offset = module_malloc(len);
  458. if (str_ret_offset) {
  459. str_ret = addr_app_to_native(str_ret_offset);
  460. bh_memcpy_s(str_ret, len, str, len);
  461. }
  462. }
  463. return str_ret_offset;
  464. }
  465. static int32
  466. __strdup_wrapper(wasm_module_inst_t module_inst,
  467. int32 str_offset)
  468. {
  469. return _strdup_wrapper(module_inst, str_offset);
  470. }
  471. static int32
  472. _memcmp_wrapper(wasm_module_inst_t module_inst,
  473. int32 s1_offset, int32 s2_offset, uint32 size)
  474. {
  475. void *s1, *s2;
  476. if (!validate_app_addr(s1_offset, size)
  477. || !validate_app_addr(s2_offset, size))
  478. return 0;
  479. s1 = addr_app_to_native(s1_offset);
  480. s2 = addr_app_to_native(s2_offset);
  481. return memcmp(s1, s2, size);
  482. }
  483. static int32
  484. _memcpy_wrapper(wasm_module_inst_t module_inst,
  485. int32 dst_offset, int32 src_offset, uint32 size)
  486. {
  487. void *dst, *src;
  488. if (size == 0)
  489. return dst_offset;
  490. if (!validate_app_addr(dst_offset, size)
  491. || !validate_app_addr(src_offset, size))
  492. return dst_offset;
  493. dst = addr_app_to_native(dst_offset);
  494. src = addr_app_to_native(src_offset);
  495. bh_memcpy_s(dst, size, src, size);
  496. return dst_offset;
  497. }
  498. static int32
  499. _memmove_wrapper(wasm_module_inst_t module_inst,
  500. int32 dst_offset, int32 src_offset, uint32 size)
  501. {
  502. void *dst, *src;
  503. if (!validate_app_addr(dst_offset, size)
  504. || !validate_app_addr(src_offset, size))
  505. return dst_offset;
  506. dst = addr_app_to_native(dst_offset);
  507. src = addr_app_to_native(src_offset);
  508. memmove(dst, src, size);
  509. return dst_offset;
  510. }
  511. static int32
  512. _memset_wrapper(wasm_module_inst_t module_inst,
  513. int32 s_offset, int32 c, uint32 size)
  514. {
  515. void *s;
  516. if (!validate_app_addr(s_offset, size))
  517. return s_offset;
  518. s = addr_app_to_native(s_offset);
  519. memset(s, c, size);
  520. return s_offset;
  521. }
  522. static int32
  523. _strchr_wrapper(wasm_module_inst_t module_inst,
  524. int32 s_offset, int32 c)
  525. {
  526. const char *s;
  527. char *ret;
  528. if (!validate_app_str_addr(s_offset))
  529. return s_offset;
  530. s = addr_app_to_native(s_offset);
  531. ret = strchr(s, c);
  532. return ret ? addr_native_to_app(ret) : 0;
  533. }
  534. static int32
  535. _strcmp_wrapper(wasm_module_inst_t module_inst,
  536. int32 s1_offset, int32 s2_offset)
  537. {
  538. void *s1, *s2;
  539. if (!validate_app_str_addr(s1_offset)
  540. || !validate_app_str_addr(s2_offset))
  541. return 0;
  542. s1 = addr_app_to_native(s1_offset);
  543. s2 = addr_app_to_native(s2_offset);
  544. return strcmp(s1, s2);
  545. }
  546. static int32
  547. _strncmp_wrapper(wasm_module_inst_t module_inst,
  548. int32 s1_offset, int32 s2_offset, uint32 size)
  549. {
  550. void *s1, *s2;
  551. if (!validate_app_addr(s1_offset, size)
  552. || !validate_app_addr(s2_offset, size))
  553. return 0;
  554. s1 = addr_app_to_native(s1_offset);
  555. s2 = addr_app_to_native(s2_offset);
  556. return strncmp(s1, s2, size);
  557. }
  558. static int32
  559. _strcpy_wrapper(wasm_module_inst_t module_inst,
  560. int32 dst_offset, int32 src_offset)
  561. {
  562. char *dst, *src;
  563. uint32 len;
  564. if (!validate_app_str_addr(src_offset))
  565. return 0;
  566. src = addr_app_to_native(src_offset);
  567. len = (uint32)strlen(src);
  568. if (!validate_app_addr(dst_offset, len + 1))
  569. return 0;
  570. dst = addr_app_to_native(dst_offset);
  571. strncpy(dst, src, len + 1);
  572. return dst_offset;
  573. }
  574. static int32
  575. _strncpy_wrapper(wasm_module_inst_t module_inst,
  576. int32 dst_offset, int32 src_offset, uint32 size)
  577. {
  578. char *dst, *src;
  579. if (!validate_app_addr(dst_offset, size)
  580. || !validate_app_addr(src_offset, size))
  581. return 0;
  582. dst = addr_app_to_native(dst_offset);
  583. src = addr_app_to_native(src_offset);
  584. strncpy(dst, src, size);
  585. return dst_offset;
  586. }
  587. static uint32
  588. _strlen_wrapper(wasm_module_inst_t module_inst,
  589. int32 s_offset)
  590. {
  591. char *s;
  592. if (!validate_app_str_addr(s_offset))
  593. return 0;
  594. s = addr_app_to_native(s_offset);
  595. return (uint32)strlen(s);
  596. }
  597. static int32
  598. _malloc_wrapper(wasm_module_inst_t module_inst,
  599. uint32 size)
  600. {
  601. return module_malloc(size);
  602. }
  603. static int32
  604. _calloc_wrapper(wasm_module_inst_t module_inst,
  605. uint32 nmemb, uint32 size)
  606. {
  607. uint64 total_size = (uint64) nmemb * (uint64) size;
  608. int32 ret_offset = 0;
  609. uint8 *ret_ptr;
  610. if (total_size >= UINT32_MAX)
  611. return 0;
  612. ret_offset = module_malloc((uint32)total_size);
  613. if (ret_offset) {
  614. ret_ptr = addr_app_to_native(ret_offset);
  615. memset(ret_ptr, 0, (uint32) total_size);
  616. }
  617. return ret_offset;
  618. }
  619. static void
  620. _free_wrapper(wasm_module_inst_t module_inst,
  621. int32 ptr_offset)
  622. {
  623. if (!validate_app_addr(ptr_offset, 4))
  624. return;
  625. return module_free(ptr_offset);
  626. }
  627. static int32
  628. _atoi_wrapper(wasm_module_inst_t module_inst,
  629. int32 s_offset)
  630. {
  631. char *str;
  632. if (!validate_app_str_addr(s_offset))
  633. return 0;
  634. str = addr_app_to_native(s_offset);
  635. return atoi(str);
  636. }
  637. static int32
  638. _bsearch_wrapper(wasm_module_inst_t module_inst,
  639. int32 key_offset, /* const void * */
  640. int32 array_offset, /* const void * */
  641. uint32 count,
  642. uint32 size,
  643. int32 cmp_index)
  644. {
  645. wasm_runtime_set_exception(module_inst, "bsearch not implemented.");
  646. return 0;
  647. }
  648. static void
  649. _exit_wrapper(wasm_module_inst_t module_inst,
  650. int32 status)
  651. {
  652. char buf[32];
  653. snprintf(buf, sizeof(buf), "env.exit(%i)", status);
  654. wasm_runtime_set_exception(module_inst, buf);
  655. }
  656. static int32
  657. _strtol_wrapper(wasm_module_inst_t module_inst,
  658. int32 nptr_offset, /* const char * */
  659. int32 endptr_offset, /* char ** */
  660. int32 base)
  661. {
  662. char *nptr, **endptr;
  663. int32 num = 0;
  664. if (!validate_app_str_addr(nptr_offset)
  665. || !validate_app_addr(endptr_offset, sizeof(int32)))
  666. return 0;
  667. nptr = addr_app_to_native(nptr_offset);
  668. endptr = addr_app_to_native(endptr_offset);
  669. num = (int32)strtol(nptr, endptr, base);
  670. *(int32 *)endptr = addr_native_to_app(*endptr);
  671. return num;
  672. }
  673. static uint32
  674. _strtoul_wrapper(wasm_module_inst_t module_inst,
  675. int32 nptr_offset, /* const char * */
  676. int32 endptr_offset, /* char ** */
  677. int32 base)
  678. {
  679. char *nptr, **endptr;
  680. uint32 num = 0;
  681. if (!validate_app_str_addr(nptr_offset)
  682. || !validate_app_addr(endptr_offset, sizeof(int32)))
  683. return 0;
  684. nptr = addr_app_to_native(nptr_offset);
  685. endptr = addr_app_to_native(endptr_offset);
  686. num = (uint32)strtoul(nptr, endptr, base);
  687. *(int32 *)endptr = addr_native_to_app(*endptr);
  688. return num;
  689. }
  690. static int32
  691. _memchr_wrapper(wasm_module_inst_t module_inst,
  692. int32 s_offset, /* const void * */
  693. int32 c,
  694. uint32 n)
  695. {
  696. void *s, *res;
  697. if (!validate_app_addr(s_offset, n))
  698. return 0;
  699. s = (void*)addr_app_to_native(s_offset);
  700. res = memchr(s, c, n);
  701. return addr_native_to_app(res);
  702. }
  703. static int32
  704. _strncasecmp_wrapper(wasm_module_inst_t module_inst,
  705. int32 s1_offset, /* const char * */
  706. int32 s2_offset, /* const char * */
  707. uint32 n)
  708. {
  709. char *s1, *s2;
  710. if (!validate_app_str_addr(s1_offset)
  711. || !validate_app_str_addr(s2_offset))
  712. return 0;
  713. s1 = addr_app_to_native(s1_offset);
  714. s2 = addr_app_to_native(s2_offset);
  715. return strncasecmp(s1, s2, n);
  716. }
  717. static uint32
  718. _strspn_wrapper(wasm_module_inst_t module_inst,
  719. int32 s_offset, /* const char * */
  720. int32 accept_offset) /* const char * */
  721. {
  722. char *s, *accept;
  723. if (!validate_app_str_addr(s_offset)
  724. || !validate_app_str_addr(accept_offset))
  725. return 0;
  726. s = addr_app_to_native(s_offset);
  727. accept = addr_app_to_native(accept_offset);
  728. return (uint32)strspn(s, accept);
  729. }
  730. static uint32
  731. _strcspn_wrapper(wasm_module_inst_t module_inst,
  732. int32 s_offset, /* const char * */
  733. int32 reject_offset) /* const char * */
  734. {
  735. char *s, *reject;
  736. if (!validate_app_str_addr(s_offset)
  737. || !validate_app_str_addr(reject_offset))
  738. return 0;
  739. s = addr_app_to_native(s_offset);
  740. reject = addr_app_to_native(reject_offset);
  741. return (uint32)strcspn(s, reject);
  742. }
  743. static int32
  744. _strstr_wrapper(wasm_module_inst_t module_inst,
  745. int32 s_offset, /* const char * */
  746. int32 find_offset) /* const char * */
  747. {
  748. char *s, *find, *res;
  749. if (!validate_app_str_addr(s_offset)
  750. || !validate_app_str_addr(find_offset))
  751. return 0;
  752. s = addr_app_to_native(s_offset);
  753. find = addr_app_to_native(find_offset);
  754. res = strstr(s, find);
  755. return addr_native_to_app(res);
  756. }
  757. static int32
  758. _isupper_wrapper(wasm_module_inst_t module_inst,
  759. int32 c)
  760. {
  761. return isupper(c);
  762. }
  763. static int32
  764. _isalpha_wrapper(wasm_module_inst_t module_inst,
  765. int32 c)
  766. {
  767. return isalpha(c);
  768. }
  769. static int32
  770. _isspace_wrapper(wasm_module_inst_t module_inst,
  771. int32 c)
  772. {
  773. return isspace(c);
  774. }
  775. static int32
  776. _isgraph_wrapper(wasm_module_inst_t module_inst,
  777. int32 c)
  778. {
  779. return isgraph(c);
  780. }
  781. static int32
  782. _isprint_wrapper(wasm_module_inst_t module_inst,
  783. int32 c)
  784. {
  785. return isprint(c);
  786. }
  787. static int32
  788. _isdigit_wrapper(wasm_module_inst_t module_inst,
  789. int32 c)
  790. {
  791. return isdigit(c);
  792. }
  793. static int32
  794. _isxdigit_wrapper(wasm_module_inst_t module_inst,
  795. int32 c)
  796. {
  797. return isxdigit(c);
  798. }
  799. static int32
  800. _tolower_wrapper(wasm_module_inst_t module_inst,
  801. int32 c)
  802. {
  803. return tolower(c);
  804. }
  805. static int32
  806. _toupper_wrapper(wasm_module_inst_t module_inst,
  807. int32 c)
  808. {
  809. return toupper(c);
  810. }
  811. static int32
  812. _isalnum_wrapper(wasm_module_inst_t module_inst,
  813. int32 c)
  814. {
  815. return isalnum(c);
  816. }
  817. static void
  818. setTempRet0_wrapper(wasm_module_inst_t module_inst,
  819. uint32 temp_ret)
  820. {
  821. wasm_runtime_set_temp_ret(module_inst, temp_ret);
  822. }
  823. static uint32
  824. getTempRet0_wrapper(wasm_module_inst_t module_inst)
  825. {
  826. return wasm_runtime_get_temp_ret(module_inst);
  827. }
  828. static uint32
  829. _llvm_bswap_i16_wrapper(wasm_module_inst_t module_inst,
  830. uint32 data)
  831. {
  832. return (data & 0xFFFF0000)
  833. | ((data & 0xFF) << 8)
  834. | ((data & 0xFF00) >> 8);
  835. }
  836. static uint32
  837. _llvm_bswap_i32_wrapper(wasm_module_inst_t module_inst,
  838. uint32 data)
  839. {
  840. return ((data & 0xFF) << 24)
  841. | ((data & 0xFF00) << 8)
  842. | ((data & 0xFF0000) >> 8)
  843. | ((data & 0xFF000000) >> 24);
  844. }
  845. static uint32
  846. _bitshift64Lshr_wrapper(wasm_module_inst_t module_inst,
  847. uint32 uint64_part0, uint32 uint64_part1,
  848. uint32 bits)
  849. {
  850. union {
  851. uint64 value;
  852. uint32 parts[2];
  853. } u;
  854. u.parts[0] = uint64_part0;
  855. u.parts[1] = uint64_part1;
  856. u.value >>= bits;
  857. /* return low 32bit and save high 32bit to temp ret */
  858. wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
  859. return (uint32) u.value;
  860. }
  861. static uint32
  862. _bitshift64Shl_wrapper(wasm_module_inst_t module_inst,
  863. uint32 int64_part0, uint32 int64_part1,
  864. uint32 bits)
  865. {
  866. union {
  867. int64 value;
  868. uint32 parts[2];
  869. } u;
  870. u.parts[0] = int64_part0;
  871. u.parts[1] = int64_part1;
  872. u.value <<= bits;
  873. /* return low 32bit and save high 32bit to temp ret */
  874. wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
  875. return (uint32) u.value;
  876. }
  877. static void
  878. _llvm_stackrestore_wrapper(wasm_module_inst_t module_inst,
  879. uint32 llvm_stack)
  880. {
  881. bh_printf("_llvm_stackrestore called!\n");
  882. wasm_runtime_set_llvm_stack(module_inst, llvm_stack);
  883. }
  884. static uint32
  885. _llvm_stacksave_wrapper(wasm_module_inst_t module_inst)
  886. {
  887. bh_printf("_llvm_stacksave called!\n");
  888. return wasm_runtime_get_llvm_stack(module_inst);
  889. }
  890. static int32
  891. _emscripten_memcpy_big_wrapper(wasm_module_inst_t module_inst,
  892. int32 dst_offset, int32 src_offset,
  893. uint32 size)
  894. {
  895. void *dst, *src;
  896. if (!validate_app_addr(dst_offset, size)
  897. || !validate_app_addr(src_offset, size))
  898. return dst_offset;
  899. dst = addr_app_to_native(dst_offset);
  900. src = addr_app_to_native(src_offset);
  901. bh_memcpy_s(dst, size, src, size);
  902. return dst_offset;
  903. }
  904. static void
  905. abort_wrapper(wasm_module_inst_t module_inst,
  906. int32 code)
  907. {
  908. char buf[32];
  909. snprintf(buf, sizeof(buf), "env.abort(%i)", code);
  910. wasm_runtime_set_exception(module_inst, buf);
  911. }
  912. static void
  913. abortStackOverflow_wrapper(wasm_module_inst_t module_inst,
  914. int32 code)
  915. {
  916. char buf[32];
  917. snprintf(buf, sizeof(buf), "env.abortStackOverflow(%i)", code);
  918. wasm_runtime_set_exception(module_inst, buf);
  919. }
  920. static void
  921. nullFunc_X_wrapper(wasm_module_inst_t module_inst,
  922. int32 code)
  923. {
  924. char buf[32];
  925. snprintf(buf, sizeof(buf), "env.nullFunc_X(%i)", code);
  926. wasm_runtime_set_exception(module_inst, buf);
  927. }
  928. static int32
  929. __cxa_allocate_exception_wrapper(wasm_module_inst_t module_inst,
  930. uint32 thrown_size)
  931. {
  932. int32 exception = module_malloc(thrown_size);
  933. if (!exception)
  934. return 0;
  935. return exception;
  936. }
  937. static void
  938. __cxa_begin_catch_wrapper(wasm_module_inst_t module_inst,
  939. int32 exception_object_offset)
  940. {
  941. }
  942. static void
  943. __cxa_throw_wrapper(wasm_module_inst_t module_inst,
  944. int32 thrown_exception_offset,
  945. int32 tinfo_offset,
  946. uint32 table_elem_idx)
  947. {
  948. char buf[32];
  949. snprintf(buf, sizeof(buf), "%s", "exception thrown by stdc++");
  950. wasm_runtime_set_exception(module_inst, buf);
  951. }
  952. /*#define ENABLE_SPEC_TEST 1*/
  953. #ifdef ENABLE_SPEC_TEST
  954. static void
  955. print_i32_wrapper(wasm_module_inst_t module_inst, int i32)
  956. {
  957. bh_printf("%d\n", i32);
  958. }
  959. static void
  960. print_wrapper(wasm_module_inst_t module_inst, int i32)
  961. {
  962. bh_printf("%d\n", i32);
  963. }
  964. #endif
  965. /* TODO: add function parameter/result types check */
  966. #define REG_NATIVE_FUNC(module_name, func_name) \
  967. { #module_name, #func_name, func_name##_wrapper }
  968. typedef struct WASMNativeFuncDef {
  969. const char *module_name;
  970. const char *func_name;
  971. void *func_ptr;
  972. } WASMNativeFuncDef;
  973. static WASMNativeFuncDef native_func_defs[] = {
  974. #ifdef ENABLE_SPEC_TEST
  975. REG_NATIVE_FUNC(spectest, print_i32),
  976. REG_NATIVE_FUNC(spectest, print),
  977. #endif
  978. REG_NATIVE_FUNC(env, _printf),
  979. REG_NATIVE_FUNC(env, _sprintf),
  980. REG_NATIVE_FUNC(env, _snprintf),
  981. REG_NATIVE_FUNC(env, _puts),
  982. REG_NATIVE_FUNC(env, _putchar),
  983. REG_NATIVE_FUNC(env, _memcmp),
  984. REG_NATIVE_FUNC(env, _memcpy),
  985. REG_NATIVE_FUNC(env, _memmove),
  986. REG_NATIVE_FUNC(env, _memset),
  987. REG_NATIVE_FUNC(env, _strchr),
  988. REG_NATIVE_FUNC(env, _strcmp),
  989. REG_NATIVE_FUNC(env, _strcpy),
  990. REG_NATIVE_FUNC(env, _strlen),
  991. REG_NATIVE_FUNC(env, _strncmp),
  992. REG_NATIVE_FUNC(env, _strncpy),
  993. REG_NATIVE_FUNC(env, _malloc),
  994. REG_NATIVE_FUNC(env, _calloc),
  995. REG_NATIVE_FUNC(env, _strdup),
  996. /* clang may introduce __strdup */
  997. REG_NATIVE_FUNC(env, __strdup),
  998. REG_NATIVE_FUNC(env, _free),
  999. REG_NATIVE_FUNC(env, _atoi),
  1000. REG_NATIVE_FUNC(env, _bsearch),
  1001. REG_NATIVE_FUNC(env, _exit),
  1002. REG_NATIVE_FUNC(env, _strtol),
  1003. REG_NATIVE_FUNC(env, _strtoul),
  1004. REG_NATIVE_FUNC(env, _memchr),
  1005. REG_NATIVE_FUNC(env, _strncasecmp),
  1006. REG_NATIVE_FUNC(env, _strspn),
  1007. REG_NATIVE_FUNC(env, _strcspn),
  1008. REG_NATIVE_FUNC(env, _strstr),
  1009. REG_NATIVE_FUNC(env, _isupper),
  1010. REG_NATIVE_FUNC(env, _isalpha),
  1011. REG_NATIVE_FUNC(env, _isspace),
  1012. REG_NATIVE_FUNC(env, _isgraph),
  1013. REG_NATIVE_FUNC(env, _isprint),
  1014. REG_NATIVE_FUNC(env, _isdigit),
  1015. REG_NATIVE_FUNC(env, _isxdigit),
  1016. REG_NATIVE_FUNC(env, _tolower),
  1017. REG_NATIVE_FUNC(env, _toupper),
  1018. REG_NATIVE_FUNC(env, _isalnum),
  1019. REG_NATIVE_FUNC(env, setTempRet0),
  1020. REG_NATIVE_FUNC(env, getTempRet0),
  1021. REG_NATIVE_FUNC(env, _llvm_bswap_i16),
  1022. REG_NATIVE_FUNC(env, _llvm_bswap_i32),
  1023. REG_NATIVE_FUNC(env, _bitshift64Lshr),
  1024. REG_NATIVE_FUNC(env, _bitshift64Shl),
  1025. REG_NATIVE_FUNC(env, _llvm_stackrestore),
  1026. REG_NATIVE_FUNC(env, _llvm_stacksave),
  1027. REG_NATIVE_FUNC(env, _emscripten_memcpy_big),
  1028. REG_NATIVE_FUNC(env, abort),
  1029. REG_NATIVE_FUNC(env, abortStackOverflow),
  1030. REG_NATIVE_FUNC(env, nullFunc_X),
  1031. REG_NATIVE_FUNC(env, __cxa_allocate_exception),
  1032. REG_NATIVE_FUNC(env, __cxa_begin_catch),
  1033. REG_NATIVE_FUNC(env, __cxa_throw)
  1034. };
  1035. void*
  1036. wasm_native_func_lookup(const char *module_name, const char *func_name)
  1037. {
  1038. uint32 size = sizeof(native_func_defs) / sizeof(WASMNativeFuncDef);
  1039. WASMNativeFuncDef *func_def = native_func_defs;
  1040. WASMNativeFuncDef *func_def_end = func_def + size;
  1041. void *ret;
  1042. if (!module_name || !func_name)
  1043. return NULL;
  1044. while (func_def < func_def_end) {
  1045. if (!strcmp(func_def->module_name, module_name)
  1046. && (!strcmp(func_def->func_name, func_name)
  1047. || (func_def->func_name[0] == '_'
  1048. && !strcmp(func_def->func_name + 1, func_name))))
  1049. return (void*) (uintptr_t) func_def->func_ptr;
  1050. func_def++;
  1051. }
  1052. if ((ret = wasm_platform_native_func_lookup(module_name, func_name)))
  1053. return ret;
  1054. #if WASM_ENABLE_WASI != 0
  1055. if ((ret = wasi_native_func_lookup(module_name, func_name)))
  1056. return ret;
  1057. #endif
  1058. return NULL;
  1059. }
  1060. /*************************************
  1061. * Global Variables *
  1062. *************************************/
  1063. typedef struct WASMNativeGlobalDef {
  1064. const char *module_name;
  1065. const char *global_name;
  1066. WASMValue global_data;
  1067. } WASMNativeGlobalDef;
  1068. static WASMNativeGlobalDef native_global_defs[] = {
  1069. #ifdef ENABLE_SPEC_TEST
  1070. { "spectest", "global_i32", .global_data.u32 = 0 },
  1071. #endif
  1072. { "env", "STACKTOP", .global_data.u32 = 0 },
  1073. { "env", "STACK_MAX", .global_data.u32 = 0 },
  1074. { "env", "ABORT", .global_data.u32 = 0 },
  1075. { "env", "memoryBase", .global_data.u32 = 0 },
  1076. { "env", "__memory_base", .global_data.u32 = 0 },
  1077. { "env", "tableBase", .global_data.u32 = 0 },
  1078. { "env", "__table_base", .global_data.u32 = 0 },
  1079. { "env", "DYNAMICTOP_PTR", .global_data.addr = 0 },
  1080. { "env", "tempDoublePtr", .global_data.addr = 0 },
  1081. { "global", "NaN", .global_data.u64 = 0x7FF8000000000000LL },
  1082. { "global", "Infinity", .global_data.u64 = 0x7FF0000000000000LL }
  1083. };
  1084. bool
  1085. wasm_native_global_lookup(const char *module_name, const char *global_name,
  1086. WASMGlobalImport *global)
  1087. {
  1088. uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef);
  1089. WASMNativeGlobalDef *global_def = native_global_defs;
  1090. WASMNativeGlobalDef *global_def_end = global_def + size;
  1091. if (!module_name || !global_name || !global)
  1092. return false;
  1093. /* Lookup constant globals which can be defined by table */
  1094. while (global_def < global_def_end) {
  1095. if (!strcmp(global_def->module_name, module_name)
  1096. && !strcmp(global_def->global_name, global_name)) {
  1097. global->global_data_linked = global_def->global_data;
  1098. return true;
  1099. }
  1100. global_def++;
  1101. }
  1102. return false;
  1103. }
  1104. bool
  1105. wasm_native_init()
  1106. {
  1107. /* TODO: qsort the function defs and global defs. */
  1108. return true;
  1109. }