libc_wrapper.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "wasm_native.h"
  17. #include "wasm_export.h"
  18. #include "wasm_log.h"
  19. #include "wasm_platform_log.h"
  20. void
  21. wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
  22. uint32
  23. wasm_runtime_get_temp_ret(wasm_module_inst_t module);
  24. void
  25. wasm_runtime_set_temp_ret(wasm_module_inst_t module, uint32 temp_ret);
  26. uint32
  27. wasm_runtime_get_llvm_stack(wasm_module_inst_t module);
  28. void
  29. wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack);
  30. #define validate_app_addr(offset, size) \
  31. wasm_runtime_validate_app_addr(module_inst, offset, size)
  32. #define addr_app_to_native(offset) \
  33. wasm_runtime_addr_app_to_native(module_inst, offset)
  34. #define addr_native_to_app(ptr) \
  35. wasm_runtime_addr_native_to_app(module_inst, ptr)
  36. #define module_malloc(size) \
  37. wasm_runtime_module_malloc(module_inst, size)
  38. #define module_free(offset) \
  39. wasm_runtime_module_free(module_inst, offset)
  40. static bool
  41. validate_str_addr(wasm_module_inst_t module_inst, int32 str_offset)
  42. {
  43. int32 app_end_offset;
  44. char *str, *str_end;
  45. if (!wasm_runtime_get_app_addr_range(module_inst, str_offset,
  46. NULL, &app_end_offset))
  47. goto fail;
  48. str = addr_app_to_native(str_offset);
  49. str_end = str + (app_end_offset - str_offset);
  50. while (str < str_end && *str != '\0')
  51. str++;
  52. if (str == str_end)
  53. goto fail;
  54. return true;
  55. fail:
  56. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  57. return false;
  58. }
  59. typedef int (*out_func_t)(int c, void *ctx);
  60. enum pad_type {
  61. PAD_NONE,
  62. PAD_ZERO_BEFORE,
  63. PAD_SPACE_BEFORE,
  64. PAD_SPACE_AFTER,
  65. };
  66. typedef char *_va_list;
  67. #define _INTSIZEOF(n) \
  68. ((sizeof(n) + 3) & ~3)
  69. #define _va_arg(ap, t) \
  70. (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
  71. #define CHECK_VA_ARG(ap, t) do { \
  72. if ((uint8*)ap + _INTSIZEOF(t) > native_end_addr) \
  73. goto fail; \
  74. } while (0)
  75. /**
  76. * @brief Output an unsigned int in hex format
  77. *
  78. * Output an unsigned int on output installed by platform at init time. Should
  79. * be able to handle an unsigned int of any size, 32 or 64 bit.
  80. * @param num Number to output
  81. *
  82. * @return N/A
  83. */
  84. static void
  85. _printf_hex_uint(out_func_t out, void *ctx,
  86. const uint64 num, bool is_u64,
  87. enum pad_type padding,
  88. int min_width)
  89. {
  90. int size = sizeof(num) * (is_u64 ? 2 : 1);
  91. int found_largest_digit = 0;
  92. int remaining = 8; /* 8 digits max */
  93. int digits = 0;
  94. for (; size; size--) {
  95. char nibble = (num >> ((size - 1) << 2) & 0xf);
  96. if (nibble || found_largest_digit || size == 1) {
  97. found_largest_digit = 1;
  98. nibble += nibble > 9 ? 87 : 48;
  99. out((int) nibble, ctx);
  100. digits++;
  101. continue;
  102. }
  103. if (remaining-- <= min_width) {
  104. if (padding == PAD_ZERO_BEFORE) {
  105. out('0', ctx);
  106. } else if (padding == PAD_SPACE_BEFORE) {
  107. out(' ', ctx);
  108. }
  109. }
  110. }
  111. if (padding == PAD_SPACE_AFTER) {
  112. remaining = min_width * 2 - digits;
  113. while (remaining-- > 0) {
  114. out(' ', ctx);
  115. }
  116. }
  117. }
  118. /**
  119. * @brief Output an unsigned int in decimal format
  120. *
  121. * Output an unsigned int on output installed by platform at init time. Only
  122. * works with 32-bit values.
  123. * @param num Number to output
  124. *
  125. * @return N/A
  126. */
  127. static void
  128. _printf_dec_uint(out_func_t out, void *ctx,
  129. const uint32 num,
  130. enum pad_type padding,
  131. int min_width)
  132. {
  133. uint32 pos = 999999999;
  134. uint32 remainder = num;
  135. int found_largest_digit = 0;
  136. int remaining = 10; /* 10 digits max */
  137. int digits = 1;
  138. /* make sure we don't skip if value is zero */
  139. if (min_width <= 0) {
  140. min_width = 1;
  141. }
  142. while (pos >= 9) {
  143. if (found_largest_digit || remainder > pos) {
  144. found_largest_digit = 1;
  145. out((int) ((remainder / (pos + 1)) + 48), ctx);
  146. digits++;
  147. } else if (remaining <= min_width && padding < PAD_SPACE_AFTER) {
  148. out((int) (padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx);
  149. digits++;
  150. }
  151. remaining--;
  152. remainder %= (pos + 1);
  153. pos /= 10;
  154. }
  155. out((int) (remainder + 48), ctx);
  156. if (padding == PAD_SPACE_AFTER) {
  157. remaining = min_width - digits;
  158. while (remaining-- > 0) {
  159. out(' ', ctx);
  160. }
  161. }
  162. }
  163. static void
  164. print_err(out_func_t out, void *ctx)
  165. {
  166. out('E', ctx);
  167. out('R', ctx);
  168. out('R', ctx);
  169. }
  170. static bool
  171. _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
  172. wasm_module_inst_t module_inst)
  173. {
  174. int might_format = 0; /* 1 if encountered a '%' */
  175. enum pad_type padding = PAD_NONE;
  176. int min_width = -1;
  177. int long_ctr = 0;
  178. uint8 *native_end_addr;
  179. if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)ap,
  180. NULL, &native_end_addr))
  181. goto fail;
  182. /* fmt has already been adjusted if needed */
  183. while (*fmt) {
  184. if (!might_format) {
  185. if (*fmt != '%') {
  186. out((int) *fmt, ctx);
  187. }
  188. else {
  189. might_format = 1;
  190. min_width = -1;
  191. padding = PAD_NONE;
  192. long_ctr = 0;
  193. }
  194. }
  195. else {
  196. switch (*fmt) {
  197. case '-':
  198. padding = PAD_SPACE_AFTER;
  199. goto still_might_format;
  200. case '0':
  201. if (min_width < 0 && padding == PAD_NONE) {
  202. padding = PAD_ZERO_BEFORE;
  203. goto still_might_format;
  204. }
  205. /* Fall through */
  206. case '1' ... '9':
  207. if (min_width < 0) {
  208. min_width = *fmt - '0';
  209. } else {
  210. min_width = 10 * min_width + *fmt - '0';
  211. }
  212. if (padding == PAD_NONE) {
  213. padding = PAD_SPACE_BEFORE;
  214. }
  215. goto still_might_format;
  216. case 'l':
  217. long_ctr++;
  218. /* Fall through */
  219. case 'z':
  220. case 'h':
  221. /* FIXME: do nothing for these modifiers */
  222. goto still_might_format;
  223. case 'd':
  224. case 'i': {
  225. int32 d;
  226. if (long_ctr < 2) {
  227. CHECK_VA_ARG(ap, int32);
  228. d = _va_arg(ap, int32);
  229. }
  230. else {
  231. int64 lld;
  232. CHECK_VA_ARG(ap, int64);
  233. lld = _va_arg(ap, int64);
  234. if (lld > INT32_MAX || lld < INT32_MIN) {
  235. print_err(out, ctx);
  236. break;
  237. }
  238. d = (int32)lld;
  239. }
  240. if (d < 0) {
  241. out((int)'-', ctx);
  242. d = -d;
  243. min_width--;
  244. }
  245. _printf_dec_uint(out, ctx, d, padding, min_width);
  246. break;
  247. }
  248. case 'u': {
  249. uint32 u;
  250. if (long_ctr < 2) {
  251. CHECK_VA_ARG(ap, uint32);
  252. u = _va_arg(ap, uint32);
  253. }
  254. else {
  255. uint64 llu;
  256. CHECK_VA_ARG(ap, uint64);
  257. llu = _va_arg(ap, uint64);
  258. if (llu > INT32_MAX) {
  259. print_err(out, ctx);
  260. break;
  261. }
  262. u = (uint32)llu;
  263. }
  264. _printf_dec_uint(out, ctx, u, padding, min_width);
  265. break;
  266. }
  267. case 'p':
  268. out('0', ctx);
  269. out('x', ctx);
  270. /* left-pad pointers with zeros */
  271. padding = PAD_ZERO_BEFORE;
  272. min_width = 8;
  273. /* Fall through */
  274. case 'x':
  275. case 'X': {
  276. uint64 x;
  277. bool is_ptr = (*fmt == 'p') ? true : false;
  278. if (long_ctr < 2) {
  279. CHECK_VA_ARG(ap, uint32);
  280. x = _va_arg(ap, uint32);
  281. } else {
  282. CHECK_VA_ARG(ap, uint64);
  283. x = _va_arg(ap, uint64);
  284. }
  285. _printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width);
  286. break;
  287. }
  288. case 's': {
  289. char *s;
  290. char *start;
  291. int32 s_offset;
  292. CHECK_VA_ARG(ap, uint32);
  293. s_offset = _va_arg(ap, uint32);
  294. if (!validate_str_addr(module_inst, s_offset)) {
  295. return false;
  296. }
  297. s = start = addr_app_to_native(s_offset);
  298. while (*s)
  299. out((int) (*s++), ctx);
  300. if (padding == PAD_SPACE_AFTER) {
  301. int remaining = min_width - (s - start);
  302. while (remaining-- > 0) {
  303. out(' ', ctx);
  304. }
  305. }
  306. break;
  307. }
  308. case 'c': {
  309. int c;
  310. CHECK_VA_ARG(ap, int);
  311. c = _va_arg(ap, int);
  312. out(c, ctx);
  313. break;
  314. }
  315. case '%': {
  316. out((int) '%', ctx);
  317. break;
  318. }
  319. default:
  320. out((int) '%', ctx);
  321. out((int) *fmt, ctx);
  322. break;
  323. }
  324. might_format = 0;
  325. }
  326. still_might_format:
  327. ++fmt;
  328. }
  329. return true;
  330. fail:
  331. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  332. return false;
  333. }
  334. struct str_context {
  335. char *str;
  336. int max;
  337. int count;
  338. };
  339. static int
  340. sprintf_out(int c, struct str_context *ctx)
  341. {
  342. if (!ctx->str || ctx->count >= ctx->max) {
  343. ctx->count++;
  344. return c;
  345. }
  346. if (ctx->count == ctx->max - 1) {
  347. ctx->str[ctx->count++] = '\0';
  348. } else {
  349. ctx->str[ctx->count++] = c;
  350. }
  351. return c;
  352. }
  353. static int
  354. printf_out(int c, struct str_context *ctx)
  355. {
  356. bh_printf("%c", c);
  357. ctx->count++;
  358. return c;
  359. }
  360. static inline _va_list
  361. get_va_list(uint32 *args)
  362. {
  363. union {
  364. uint32 u;
  365. _va_list v;
  366. } u;
  367. u.u = args[0];
  368. return u.v;
  369. }
  370. static bool
  371. parse_printf_args(wasm_module_inst_t module_inst, int32 fmt_offset,
  372. int32 va_list_offset, const char **p_fmt,
  373. _va_list *p_va_args)
  374. {
  375. const char *fmt;
  376. union {
  377. uintptr_t u;
  378. _va_list v;
  379. } u;
  380. if (!validate_str_addr(module_inst, fmt_offset)
  381. || !validate_app_addr(va_list_offset, sizeof(int32)))
  382. return false;
  383. fmt = (const char*) addr_app_to_native(fmt_offset);
  384. u.u = (uintptr_t) addr_app_to_native(va_list_offset);
  385. *p_fmt = fmt;
  386. *p_va_args = u.v;
  387. return true;
  388. }
  389. static int
  390. _printf_wrapper(wasm_module_inst_t module_inst,
  391. int32 fmt_offset, int32 va_list_offset)
  392. {
  393. struct str_context ctx = { NULL, 0, 0 };
  394. const char *fmt;
  395. _va_list va_args;
  396. if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
  397. return 0;
  398. if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst))
  399. return 0;
  400. return ctx.count;
  401. }
  402. static int
  403. _sprintf_wrapper(wasm_module_inst_t module_inst,
  404. int32 str_offset, int32 fmt_offset, int32 va_list_offset)
  405. {
  406. int32 app_end_offset;
  407. struct str_context ctx;
  408. char *str;
  409. const char *fmt;
  410. _va_list va_args;
  411. if (!wasm_runtime_get_app_addr_range(module_inst, str_offset,
  412. NULL, &app_end_offset)) {
  413. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  414. return false;
  415. }
  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 = app_end_offset - str_offset;
  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 ctx.count;
  428. }
  429. static int
  430. _snprintf_wrapper(wasm_module_inst_t module_inst,
  431. int32 str_offset, int32 size, int32 fmt_offset,
  432. int32 va_list_offset)
  433. {
  434. struct str_context ctx;
  435. char *str;
  436. const char *fmt;
  437. _va_list va_args;
  438. if (!validate_app_addr(str_offset, size))
  439. return 0;
  440. str = addr_app_to_native(str_offset);
  441. if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args))
  442. return 0;
  443. ctx.str = str;
  444. ctx.max = size;
  445. ctx.count = 0;
  446. if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst))
  447. return 0;
  448. if (ctx.count < ctx.max) {
  449. str[ctx.count] = '\0';
  450. }
  451. return ctx.count;
  452. }
  453. static int
  454. _puts_wrapper(wasm_module_inst_t module_inst,
  455. int32 str_offset)
  456. {
  457. const char *str;
  458. if (!validate_str_addr(module_inst, str_offset))
  459. return 0;
  460. str = addr_app_to_native(str_offset);
  461. return bh_printf("%s\n", str);
  462. }
  463. static int
  464. _putchar_wrapper(wasm_module_inst_t module_inst, int c)
  465. {
  466. bh_printf("%c", c);
  467. return 1;
  468. }
  469. static int32
  470. _strdup_wrapper(wasm_module_inst_t module_inst,
  471. int32 str_offset)
  472. {
  473. char *str, *str_ret;
  474. uint32 len;
  475. int32 str_ret_offset = 0;
  476. if (!validate_str_addr(module_inst, str_offset))
  477. return 0;
  478. str = addr_app_to_native(str_offset);
  479. if (str) {
  480. len = strlen(str) + 1;
  481. str_ret_offset = module_malloc(len);
  482. if (str_ret_offset) {
  483. str_ret = addr_app_to_native(str_ret_offset);
  484. memcpy(str_ret, str, len);
  485. }
  486. }
  487. return str_ret_offset;
  488. }
  489. static int32
  490. _memcmp_wrapper(wasm_module_inst_t module_inst,
  491. int32 s1_offset, int32 s2_offset, int32 size)
  492. {
  493. void *s1, *s2;
  494. if (!validate_app_addr(s1_offset, size)
  495. || !validate_app_addr(s2_offset, size))
  496. return 0;
  497. s1 = addr_app_to_native(s1_offset);
  498. s2 = addr_app_to_native(s2_offset);
  499. return memcmp(s1, s2, size);
  500. }
  501. static int32
  502. _memcpy_wrapper(wasm_module_inst_t module_inst,
  503. int32 dst_offset, int32 src_offset, int32 size)
  504. {
  505. void *dst, *src;
  506. if (size == 0)
  507. return dst_offset;
  508. if (!validate_app_addr(dst_offset, size)
  509. || !validate_app_addr(src_offset, size))
  510. return dst_offset;
  511. dst = addr_app_to_native(dst_offset);
  512. src = addr_app_to_native(src_offset);
  513. memcpy(dst, src, size);
  514. return dst_offset;
  515. }
  516. static int32
  517. _memmove_wrapper(wasm_module_inst_t module_inst,
  518. int32 dst_offset, int32 src_offset, int32 size)
  519. {
  520. void *dst, *src;
  521. if (!validate_app_addr(dst_offset, size)
  522. || !validate_app_addr(src_offset, size))
  523. return dst_offset;
  524. dst = addr_app_to_native(dst_offset);
  525. src = addr_app_to_native(src_offset);
  526. memmove(dst, src, size);
  527. return dst_offset;
  528. }
  529. static int32
  530. _memset_wrapper(wasm_module_inst_t module_inst,
  531. int32 s_offset, int32 c, int32 size)
  532. {
  533. void *s;
  534. if (!validate_app_addr(s_offset, size))
  535. return s_offset;
  536. s = addr_app_to_native(s_offset);
  537. memset(s, c, size);
  538. return s_offset;
  539. }
  540. static int32
  541. _strchr_wrapper(wasm_module_inst_t module_inst,
  542. int32 s_offset, int32 c)
  543. {
  544. const char *s;
  545. char *ret;
  546. if (!validate_str_addr(module_inst, s_offset))
  547. return s_offset;
  548. s = addr_app_to_native(s_offset);
  549. ret = strchr(s, c);
  550. return ret ? addr_native_to_app(ret) : 0;
  551. }
  552. static int32
  553. _strcmp_wrapper(wasm_module_inst_t module_inst,
  554. int32 s1_offset, int32 s2_offset)
  555. {
  556. void *s1, *s2;
  557. if (!validate_str_addr(module_inst, s1_offset)
  558. || !validate_str_addr(module_inst, s2_offset))
  559. return 0;
  560. s1 = addr_app_to_native(s1_offset);
  561. s2 = addr_app_to_native(s2_offset);
  562. return strcmp(s1, s2);
  563. }
  564. static int32
  565. _strncmp_wrapper(wasm_module_inst_t module_inst,
  566. int32 s1_offset, int32 s2_offset, uint32 size)
  567. {
  568. void *s1, *s2;
  569. if (!validate_app_addr(s1_offset, size)
  570. || !validate_app_addr(s2_offset, size))
  571. return 0;
  572. s1 = addr_app_to_native(s1_offset);
  573. s2 = addr_app_to_native(s2_offset);
  574. return strncmp(s1, s2, size);
  575. }
  576. static int32
  577. _strcpy_wrapper(wasm_module_inst_t module_inst,
  578. int32 dst_offset, int32 src_offset)
  579. {
  580. char *dst, *src;
  581. uint32 len;
  582. if (!validate_str_addr(module_inst, src_offset))
  583. return 0;
  584. src = addr_app_to_native(src_offset);
  585. len = strlen(src);
  586. if (!validate_app_addr(dst_offset, len + 1))
  587. return 0;
  588. dst = addr_app_to_native(dst_offset);
  589. strncpy(dst, src, len + 1);
  590. return dst_offset;
  591. }
  592. static int32
  593. _strncpy_wrapper(wasm_module_inst_t module_inst,
  594. int32 dst_offset, int32 src_offset, uint32 size)
  595. {
  596. char *dst, *src;
  597. if (!validate_app_addr(dst_offset, size)
  598. || !validate_app_addr(src_offset, size))
  599. return 0;
  600. dst = addr_app_to_native(dst_offset);
  601. src = addr_app_to_native(src_offset);
  602. strncpy(dst, src, size);
  603. return dst_offset;
  604. }
  605. static uint32
  606. _strlen_wrapper(wasm_module_inst_t module_inst,
  607. int32 s_offset)
  608. {
  609. char *s;
  610. if (!validate_str_addr(module_inst, s_offset))
  611. return 0;
  612. s = addr_app_to_native(s_offset);
  613. return strlen(s);
  614. }
  615. static int32
  616. _malloc_wrapper(wasm_module_inst_t module_inst,
  617. uint32 size)
  618. {
  619. return module_malloc(size);
  620. }
  621. static int32
  622. _calloc_wrapper(wasm_module_inst_t module_inst,
  623. uint32 nmemb, uint32 size)
  624. {
  625. uint64 total_size = (uint64) nmemb * (uint64) size;
  626. uint32 ret_offset = 0;
  627. uint8 *ret_ptr;
  628. if (total_size > UINT32_MAX)
  629. total_size = UINT32_MAX;
  630. ret_offset = module_malloc((uint32 )total_size);
  631. if (ret_offset) {
  632. ret_ptr = addr_app_to_native(ret_offset);
  633. memset(ret_ptr, 0, (uint32) total_size);
  634. }
  635. return ret_offset;
  636. }
  637. static void
  638. _free_wrapper(wasm_module_inst_t module_inst,
  639. int32 ptr_offset)
  640. {
  641. if (!validate_app_addr(ptr_offset, 4))
  642. return;
  643. return module_free(ptr_offset);
  644. }
  645. static void
  646. setTempRet0_wrapper(wasm_module_inst_t module_inst,
  647. uint32 temp_ret)
  648. {
  649. wasm_runtime_set_temp_ret(module_inst, temp_ret);
  650. }
  651. static uint32
  652. getTempRet0_wrapper(wasm_module_inst_t module_inst)
  653. {
  654. return wasm_runtime_get_temp_ret(module_inst);
  655. }
  656. static uint32
  657. _llvm_bswap_i16_wrapper(wasm_module_inst_t module_inst,
  658. uint32 data)
  659. {
  660. return (data & 0xFFFF0000)
  661. | ((data & 0xFF) << 8)
  662. | ((data & 0xFF00) >> 8);
  663. }
  664. static uint32
  665. _llvm_bswap_i32_wrapper(wasm_module_inst_t module_inst,
  666. uint32 data)
  667. {
  668. return ((data & 0xFF) << 24)
  669. | ((data & 0xFF00) << 8)
  670. | ((data & 0xFF0000) >> 8)
  671. | ((data & 0xFF000000) >> 24);
  672. }
  673. static uint32
  674. _bitshift64Lshr_wrapper(wasm_module_inst_t module_inst,
  675. uint32 uint64_part0, uint32 uint64_part1,
  676. uint32 bits)
  677. {
  678. union {
  679. uint64 value;
  680. uint32 parts[2];
  681. } u;
  682. u.parts[0] = uint64_part0;
  683. u.parts[1] = uint64_part1;
  684. u.value >>= bits;
  685. /* return low 32bit and save high 32bit to temp ret */
  686. wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
  687. return (uint32) u.value;
  688. }
  689. static uint32
  690. _bitshift64Shl_wrapper(wasm_module_inst_t module_inst,
  691. uint32 int64_part0, uint32 int64_part1,
  692. uint32 bits)
  693. {
  694. union {
  695. int64 value;
  696. uint32 parts[2];
  697. } u;
  698. u.parts[0] = int64_part0;
  699. u.parts[1] = int64_part1;
  700. u.value <<= bits;
  701. /* return low 32bit and save high 32bit to temp ret */
  702. wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
  703. return (uint32) u.value;
  704. }
  705. static void
  706. _llvm_stackrestore_wrapper(wasm_module_inst_t module_inst,
  707. uint32 llvm_stack)
  708. {
  709. bh_printf("_llvm_stackrestore called!\n");
  710. wasm_runtime_set_llvm_stack(module_inst, llvm_stack);
  711. }
  712. static uint32
  713. _llvm_stacksave_wrapper(wasm_module_inst_t module_inst)
  714. {
  715. bh_printf("_llvm_stacksave called!\n");
  716. return wasm_runtime_get_llvm_stack(module_inst);
  717. }
  718. static int32
  719. _emscripten_memcpy_big_wrapper(wasm_module_inst_t module_inst,
  720. int32 dst_offset, int32 src_offset,
  721. uint32 size)
  722. {
  723. void *dst, *src;
  724. if (!validate_app_addr(dst_offset, size)
  725. || !validate_app_addr(src_offset, size))
  726. return dst_offset;
  727. dst = addr_app_to_native(dst_offset);
  728. src = addr_app_to_native(src_offset);
  729. memcpy(dst, src, size);
  730. return dst_offset;
  731. }
  732. static void
  733. abort_wrapper(wasm_module_inst_t module_inst,
  734. int32 code)
  735. {
  736. char buf[32];
  737. snprintf(buf, sizeof(buf), "env.abort(%i)", code);
  738. wasm_runtime_set_exception(module_inst, buf);
  739. }
  740. static void
  741. abortStackOverflow_wrapper(wasm_module_inst_t module_inst,
  742. int32 code)
  743. {
  744. char buf[32];
  745. snprintf(buf, sizeof(buf), "env.abortStackOverflow(%i)", code);
  746. wasm_runtime_set_exception(module_inst, buf);
  747. }
  748. static void
  749. nullFunc_X_wrapper(wasm_module_inst_t module_inst,
  750. int32 code)
  751. {
  752. char buf[32];
  753. snprintf(buf, sizeof(buf), "env.nullFunc_X(%i)", code);
  754. wasm_runtime_set_exception(module_inst, buf);
  755. }
  756. /*#define ENABLE_SPEC_TEST 1*/
  757. #ifdef ENABLE_SPEC_TEST
  758. static void
  759. print_i32_wrapper(wasm_module_inst_t module_inst, int i32)
  760. {
  761. bh_printf("%d\n", i32);
  762. }
  763. static void
  764. print_wrapper(wasm_module_inst_t module_inst, int i32)
  765. {
  766. bh_printf("%d\n", i32);
  767. }
  768. #endif
  769. /* TODO: add function parameter/result types check */
  770. #define REG_NATIVE_FUNC(module_name, func_name) \
  771. { #module_name, #func_name, func_name##_wrapper }
  772. typedef struct WASMNativeFuncDef {
  773. const char *module_name;
  774. const char *func_name;
  775. void *func_ptr;
  776. } WASMNativeFuncDef;
  777. static WASMNativeFuncDef native_func_defs[] = {
  778. #ifdef ENABLE_SPEC_TEST
  779. REG_NATIVE_FUNC(spectest, print_i32),
  780. REG_NATIVE_FUNC(spectest, print),
  781. #endif
  782. REG_NATIVE_FUNC(env, _printf),
  783. REG_NATIVE_FUNC(env, _sprintf),
  784. REG_NATIVE_FUNC(env, _snprintf),
  785. REG_NATIVE_FUNC(env, _puts),
  786. REG_NATIVE_FUNC(env, _putchar),
  787. REG_NATIVE_FUNC(env, _memcmp),
  788. REG_NATIVE_FUNC(env, _memcpy),
  789. REG_NATIVE_FUNC(env, _memmove),
  790. REG_NATIVE_FUNC(env, _memset),
  791. REG_NATIVE_FUNC(env, _strchr),
  792. REG_NATIVE_FUNC(env, _strcmp),
  793. REG_NATIVE_FUNC(env, _strcpy),
  794. REG_NATIVE_FUNC(env, _strlen),
  795. REG_NATIVE_FUNC(env, _strncmp),
  796. REG_NATIVE_FUNC(env, _strncpy),
  797. REG_NATIVE_FUNC(env, _malloc),
  798. REG_NATIVE_FUNC(env, _calloc),
  799. REG_NATIVE_FUNC(env, _strdup),
  800. REG_NATIVE_FUNC(env, _free),
  801. REG_NATIVE_FUNC(env, setTempRet0),
  802. REG_NATIVE_FUNC(env, getTempRet0),
  803. REG_NATIVE_FUNC(env, _llvm_bswap_i16),
  804. REG_NATIVE_FUNC(env, _llvm_bswap_i32),
  805. REG_NATIVE_FUNC(env, _bitshift64Lshr),
  806. REG_NATIVE_FUNC(env, _bitshift64Shl),
  807. REG_NATIVE_FUNC(env, _llvm_stackrestore),
  808. REG_NATIVE_FUNC(env, _llvm_stacksave),
  809. REG_NATIVE_FUNC(env, _emscripten_memcpy_big),
  810. REG_NATIVE_FUNC(env, abort),
  811. REG_NATIVE_FUNC(env, abortStackOverflow),
  812. REG_NATIVE_FUNC(env, nullFunc_X)
  813. };
  814. void*
  815. wasm_native_func_lookup(const char *module_name, const char *func_name)
  816. {
  817. uint32 size = sizeof(native_func_defs) / sizeof(WASMNativeFuncDef);
  818. WASMNativeFuncDef *func_def = native_func_defs;
  819. WASMNativeFuncDef *func_def_end = func_def + size;
  820. void *ret;
  821. if (!module_name || !func_name)
  822. return NULL;
  823. while (func_def < func_def_end) {
  824. if (!strcmp(func_def->module_name, module_name)
  825. && (!strcmp(func_def->func_name, func_name)
  826. || (func_def->func_name[0] == '_'
  827. && !strcmp(func_def->func_name + 1, func_name))))
  828. return (void*) (uintptr_t) func_def->func_ptr;
  829. func_def++;
  830. }
  831. if ((ret = wasm_platform_native_func_lookup(module_name, func_name)))
  832. return ret;
  833. return NULL;
  834. }
  835. /*************************************
  836. * Global Variables *
  837. *************************************/
  838. typedef struct WASMNativeGlobalDef {
  839. const char *module_name;
  840. const char *global_name;
  841. WASMValue global_data;
  842. } WASMNativeGlobalDef;
  843. static WASMNativeGlobalDef native_global_defs[] = {
  844. #ifdef ENABLE_SPEC_TEST
  845. { "spectest", "global_i32", .global_data.u32 = 0 },
  846. #endif
  847. { "env", "STACKTOP", .global_data.u32 = 0 },
  848. { "env", "STACK_MAX", .global_data.u32 = 0 },
  849. { "env", "ABORT", .global_data.u32 = 0 },
  850. { "env", "memoryBase", .global_data.u32 = 0 },
  851. { "env", "__memory_base", .global_data.u32 = 0 },
  852. { "env", "tableBase", .global_data.u32 = 0 },
  853. { "env", "__table_base", .global_data.u32 = 0 },
  854. { "env", "DYNAMICTOP_PTR", .global_data.addr = 0 },
  855. { "env", "tempDoublePtr", .global_data.addr = 0 },
  856. { "global", "NaN", .global_data.u64 = 0x7FF8000000000000LL },
  857. { "global", "Infinity", .global_data.u64 = 0x7FF0000000000000LL }
  858. };
  859. bool
  860. wasm_native_global_lookup(const char *module_name, const char *global_name,
  861. WASMGlobalImport *global)
  862. {
  863. uint32 size = sizeof(native_global_defs) / sizeof(WASMNativeGlobalDef);
  864. WASMNativeGlobalDef *global_def = native_global_defs;
  865. WASMNativeGlobalDef *global_def_end = global_def + size;
  866. if (!module_name || !global_name || !global)
  867. return false;
  868. /* Lookup constant globals which can be defined by table */
  869. while (global_def < global_def_end) {
  870. if (!strcmp(global_def->module_name, module_name)
  871. && !strcmp(global_def->global_name, global_name)) {
  872. global->global_data_linked = global_def->global_data;
  873. return true;
  874. }
  875. global_def++;
  876. }
  877. return false;
  878. }
  879. bool
  880. wasm_native_init()
  881. {
  882. /* TODO: qsort the function defs and global defs. */
  883. return true;
  884. }