shared_heap_test.cc 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  1. /*
  2. * Copyright (C) 2024 Xiaomi Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "test_helper.h"
  6. #include "gtest/gtest.h"
  7. #include "bh_read_file.h"
  8. #include "wasm_runtime_common.h"
  9. #include <gtest/gtest-spi.h>
  10. class shared_heap_test : public testing::Test
  11. {
  12. protected:
  13. virtual void SetUp() {}
  14. static void SetUpTestCase() {}
  15. virtual void TearDown() {}
  16. WAMRRuntimeRAII<512 * 1024> runtime;
  17. };
  18. struct ret_env {
  19. wasm_exec_env_t exec_env;
  20. wasm_module_t wasm_module;
  21. wasm_module_inst_t wasm_module_inst;
  22. unsigned char *wasm_file_buf;
  23. char error_buf[128];
  24. };
  25. static void
  26. destroy_module_env(struct ret_env module_env);
  27. static bool
  28. load_wasm(const char *wasm_file_tested, unsigned int app_heap_size,
  29. ret_env &ret_module_env)
  30. {
  31. char *wasm_file = strdup(wasm_file_tested);
  32. unsigned int wasm_file_size = 0;
  33. unsigned int stack_size = 16 * 1024, heap_size = app_heap_size;
  34. char error_buf[128] = {};
  35. ret_module_env.wasm_file_buf =
  36. (unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
  37. if (!ret_module_env.wasm_file_buf) {
  38. goto fail;
  39. }
  40. ret_module_env.wasm_module =
  41. wasm_runtime_load(ret_module_env.wasm_file_buf, wasm_file_size,
  42. error_buf, sizeof(error_buf));
  43. if (!ret_module_env.wasm_module) {
  44. memcpy(ret_module_env.error_buf, error_buf, 128);
  45. goto fail;
  46. }
  47. ret_module_env.wasm_module_inst =
  48. wasm_runtime_instantiate(ret_module_env.wasm_module, stack_size,
  49. heap_size, error_buf, sizeof(error_buf));
  50. if (!ret_module_env.wasm_module_inst) {
  51. memcpy(ret_module_env.error_buf, error_buf, 128);
  52. goto fail;
  53. }
  54. ret_module_env.exec_env = wasm_runtime_create_exec_env(
  55. ret_module_env.wasm_module_inst, stack_size);
  56. if (!ret_module_env.exec_env) {
  57. goto fail;
  58. }
  59. free(wasm_file);
  60. return true;
  61. fail:
  62. free(wasm_file);
  63. destroy_module_env(ret_module_env);
  64. return false;
  65. }
  66. void
  67. destroy_module_env(struct ret_env module_env)
  68. {
  69. if (module_env.exec_env) {
  70. wasm_runtime_destroy_exec_env(module_env.exec_env);
  71. }
  72. if (module_env.wasm_module_inst) {
  73. wasm_runtime_deinstantiate(module_env.wasm_module_inst);
  74. }
  75. if (module_env.wasm_module) {
  76. wasm_runtime_unload(module_env.wasm_module);
  77. }
  78. if (module_env.wasm_file_buf) {
  79. wasm_runtime_free(module_env.wasm_file_buf);
  80. }
  81. }
  82. static void
  83. test_shared_heap(WASMSharedHeap *shared_heap, const char *file,
  84. const char *func_name, uint32 argc, uint32 argv[])
  85. {
  86. struct ret_env tmp_module_env;
  87. WASMFunctionInstanceCommon *func_test = nullptr;
  88. bool ret = false;
  89. if (!load_wasm((char *)file, 0, tmp_module_env)) {
  90. ADD_FAILURE() << "Failed to load wasm file\n";
  91. goto fail0;
  92. }
  93. if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst,
  94. shared_heap)) {
  95. ADD_FAILURE() << "Failed to attach shared heap\n";
  96. goto fail1;
  97. }
  98. func_test = wasm_runtime_lookup_function(tmp_module_env.wasm_module_inst,
  99. func_name);
  100. if (!func_test) {
  101. ADD_FAILURE() << "Failed to wasm_runtime_lookup_function!\n";
  102. goto fail2;
  103. }
  104. ret =
  105. wasm_runtime_call_wasm(tmp_module_env.exec_env, func_test, argc, argv);
  106. if (!ret) {
  107. const char *s =
  108. wasm_runtime_get_exception(tmp_module_env.wasm_module_inst);
  109. ADD_FAILURE() << "Failed to wasm_runtime_call_wasm with "
  110. << "exception: " << s;
  111. }
  112. fail2:
  113. wasm_runtime_detach_shared_heap(tmp_module_env.wasm_module_inst);
  114. fail1:
  115. destroy_module_env(tmp_module_env);
  116. fail0:
  117. return;
  118. }
  119. TEST_F(shared_heap_test, test_shared_heap_basic)
  120. {
  121. SharedHeapInitArgs args = {};
  122. WASMSharedHeap *shared_heap = nullptr;
  123. uint32 argv[1] = {};
  124. args.size = 1024;
  125. shared_heap = wasm_runtime_create_shared_heap(&args);
  126. if (!shared_heap) {
  127. FAIL() << "Failed to create shared heap";
  128. }
  129. test_shared_heap(shared_heap, "test.wasm", "test", 0, argv);
  130. EXPECT_EQ(10, argv[0]);
  131. test_shared_heap(shared_heap, "test.aot", "test", 0, argv);
  132. EXPECT_EQ(10, argv[0]);
  133. test_shared_heap(shared_heap, "test_chain.aot", "test", 0, argv);
  134. EXPECT_EQ(10, argv[0]);
  135. }
  136. TEST_F(shared_heap_test, test_shared_heap_malloc_fail)
  137. {
  138. SharedHeapInitArgs args = {};
  139. WASMSharedHeap *shared_heap = nullptr;
  140. uint32 argv[1] = {};
  141. args.size = 1024;
  142. shared_heap = wasm_runtime_create_shared_heap(&args);
  143. if (!shared_heap) {
  144. FAIL() << "Failed to create shared heap";
  145. }
  146. test_shared_heap(shared_heap, "test.wasm", "test_malloc_fail", 0, argv);
  147. EXPECT_EQ(1, argv[0]);
  148. test_shared_heap(shared_heap, "test.aot", "test_malloc_fail", 0, argv);
  149. EXPECT_EQ(1, argv[0]);
  150. test_shared_heap(shared_heap, "test_chain.aot", "test_malloc_fail", 0,
  151. argv);
  152. EXPECT_EQ(1, argv[0]);
  153. }
  154. TEST_F(shared_heap_test, test_preallocated_shared_heap_malloc_fail)
  155. {
  156. SharedHeapInitArgs args = {};
  157. WASMSharedHeap *shared_heap = nullptr;
  158. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  159. uint8 preallocated_buf[BUF_SIZE];
  160. /* create a preallocated shared heap */
  161. args.pre_allocated_addr = preallocated_buf;
  162. args.size = BUF_SIZE;
  163. shared_heap = wasm_runtime_create_shared_heap(&args);
  164. if (!shared_heap) {
  165. FAIL() << "Create preallocated shared heap failed.\n";
  166. }
  167. /* test wasm can't malloc with preallocated shared heap */
  168. argv[0] = 1024;
  169. test_shared_heap(shared_heap, "test.wasm", "my_shared_heap_malloc", 1,
  170. argv);
  171. EXPECT_EQ(0, argv[0]);
  172. argv[0] = 1024;
  173. test_shared_heap(shared_heap, "test.aot", "my_shared_heap_malloc", 1, argv);
  174. EXPECT_EQ(0, argv[0]);
  175. argv[0] = 1024;
  176. test_shared_heap(shared_heap, "test_chain.aot", "my_shared_heap_malloc", 1,
  177. argv);
  178. EXPECT_EQ(0, argv[0]);
  179. }
  180. TEST_F(shared_heap_test, test_preallocated_shared_runtime_api)
  181. {
  182. struct ret_env tmp_module_env;
  183. SharedHeapInitArgs args = {};
  184. WASMSharedHeap *shared_heap = nullptr;
  185. uint32 argv[1] = {};
  186. void *native_ptr;
  187. uint64 offset, size;
  188. bool ret;
  189. args.size = 0x4000;
  190. shared_heap = wasm_runtime_create_shared_heap(&args);
  191. if (!shared_heap) {
  192. FAIL() << "Failed to create shared heap";
  193. }
  194. if (!load_wasm("test.wasm", 0, tmp_module_env)) {
  195. FAIL() << "Failed to load wasm file\n";
  196. }
  197. if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst,
  198. shared_heap)) {
  199. ADD_FAILURE() << "Failed to attach shared heap\n";
  200. goto fail1;
  201. }
  202. offset = wasm_runtime_shared_heap_malloc(tmp_module_env.wasm_module_inst,
  203. 32, &native_ptr);
  204. if (!offset) {
  205. ADD_FAILURE() << "Failed to attach shared heap\n";
  206. goto fail2;
  207. }
  208. size = (uint64_t)UINT32_MAX + 0x2000;
  209. printf("offset %lx size: %lx\n", offset, size);
  210. ASSERT_EQ(false, wasm_runtime_validate_app_addr(
  211. tmp_module_env.wasm_module_inst, offset, size));
  212. ASSERT_EQ(NULL, wasm_runtime_addr_app_to_native(
  213. tmp_module_env.wasm_module_inst, offset + size));
  214. size = (uint64_t)10;
  215. ASSERT_EQ(true, wasm_runtime_validate_app_addr(
  216. tmp_module_env.wasm_module_inst, offset, size));
  217. ASSERT_EQ((char *)native_ptr + size,
  218. wasm_runtime_addr_app_to_native(tmp_module_env.wasm_module_inst,
  219. offset + size));
  220. fail2:
  221. wasm_runtime_detach_shared_heap(tmp_module_env.wasm_module_inst);
  222. fail1:
  223. destroy_module_env(tmp_module_env);
  224. }
  225. static void
  226. create_test_shared_heap(uint8 *preallocated_buf, size_t size,
  227. WASMSharedHeap **shared_heap_res)
  228. {
  229. SharedHeapInitArgs args = {};
  230. WASMSharedHeap *shared_heap = nullptr;
  231. args.pre_allocated_addr = preallocated_buf;
  232. args.size = size;
  233. shared_heap = wasm_runtime_create_shared_heap(&args);
  234. if (!shared_heap) {
  235. FAIL() << "Create preallocated shared heap failed.\n";
  236. }
  237. *shared_heap_res = shared_heap;
  238. if (!*shared_heap_res) {
  239. FAIL() << "Create shared heap chain failed.\n";
  240. }
  241. }
  242. static void
  243. create_test_shared_heap_chain(uint8 *preallocated_buf, size_t size,
  244. uint8 *preallocated_buf2, size_t size2,
  245. WASMSharedHeap **shared_heap_chain)
  246. {
  247. SharedHeapInitArgs args = {};
  248. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr;
  249. args.pre_allocated_addr = preallocated_buf;
  250. args.size = size;
  251. shared_heap = wasm_runtime_create_shared_heap(&args);
  252. if (!shared_heap) {
  253. FAIL() << "Create preallocated shared heap failed.\n";
  254. }
  255. memset(&args, 0, sizeof(args));
  256. args.pre_allocated_addr = preallocated_buf2;
  257. args.size = size2;
  258. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  259. if (!shared_heap2) {
  260. FAIL() << "Create preallocated shared heap failed.\n";
  261. }
  262. *shared_heap_chain =
  263. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  264. if (!*shared_heap_chain) {
  265. FAIL() << "Create shared heap chain failed.\n";
  266. }
  267. }
  268. TEST_F(shared_heap_test, test_shared_heap_rmw)
  269. {
  270. WASMSharedHeap *shared_heap = nullptr;
  271. uint32 argv[2] = {}, BUF_SIZE = os_getpagesize();
  272. uint8 preallocated_buf[BUF_SIZE] = {};
  273. uint32 start1, end1;
  274. create_test_shared_heap(preallocated_buf, BUF_SIZE, &shared_heap);
  275. /* app addr for shared heap */
  276. start1 = UINT32_MAX - BUF_SIZE + 1;
  277. end1 = UINT32_MAX;
  278. argv[0] = end1;
  279. argv[1] = 101;
  280. test_shared_heap(shared_heap, "test.wasm", "read_modify_write_8", 2, argv);
  281. EXPECT_EQ(0, argv[0]);
  282. EXPECT_EQ(preallocated_buf[BUF_SIZE - 1], 101);
  283. argv[0] = start1;
  284. argv[1] = 37;
  285. test_shared_heap(shared_heap, "test.wasm", "read_modify_write_8", 2, argv);
  286. EXPECT_EQ(0, argv[0]);
  287. EXPECT_EQ(preallocated_buf[0], 37);
  288. argv[0] = end1;
  289. argv[1] = 81;
  290. test_shared_heap(shared_heap, "test.aot", "read_modify_write_8", 2, argv);
  291. EXPECT_EQ(101, argv[0]);
  292. EXPECT_EQ(preallocated_buf[BUF_SIZE - 1], 81);
  293. argv[0] = start1;
  294. argv[1] = 98;
  295. test_shared_heap(shared_heap, "test.aot", "read_modify_write_8", 2, argv);
  296. EXPECT_EQ(37, argv[0]);
  297. EXPECT_EQ(preallocated_buf[0], 98);
  298. }
  299. TEST_F(shared_heap_test, test_shared_heap_chain_rmw)
  300. {
  301. SharedHeapInitArgs args = {};
  302. WASMSharedHeap *shared_heap_chain = nullptr;
  303. uint32 argv[2] = {}, BUF_SIZE = os_getpagesize();
  304. uint8 preallocated_buf[BUF_SIZE] = {}, preallocated_buf2[BUF_SIZE] = {};
  305. uint32 start1, end1, start2, end2;
  306. create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
  307. BUF_SIZE, &shared_heap_chain);
  308. /* app addr for shared heap */
  309. start1 = UINT32_MAX - 2 * BUF_SIZE + 1;
  310. end1 = UINT32_MAX - BUF_SIZE;
  311. start2 = UINT32_MAX - BUF_SIZE + 1;
  312. end2 = UINT32_MAX;
  313. /* shared heap 1 */
  314. argv[0] = end1;
  315. argv[1] = 101;
  316. test_shared_heap(shared_heap_chain, "test.wasm", "read_modify_write_8", 2,
  317. argv);
  318. EXPECT_EQ(0, argv[0]);
  319. EXPECT_EQ(preallocated_buf[BUF_SIZE - 1], 101);
  320. /* shared heap 2 */
  321. argv[0] = start2;
  322. argv[1] = 129;
  323. test_shared_heap(shared_heap_chain, "test.wasm", "read_modify_write_8", 2,
  324. argv);
  325. EXPECT_EQ(0, argv[0]);
  326. EXPECT_EQ(preallocated_buf2[0], 129);
  327. argv[0] = start1;
  328. argv[1] = 98;
  329. test_shared_heap(shared_heap_chain, "test_chain.aot", "read_modify_write_8",
  330. 2, argv);
  331. EXPECT_EQ(0, argv[0]);
  332. EXPECT_EQ(preallocated_buf[0], 98);
  333. argv[0] = end2;
  334. argv[1] = 81;
  335. test_shared_heap(shared_heap_chain, "test_chain.aot", "read_modify_write_8",
  336. 2, argv);
  337. EXPECT_EQ(0, argv[0]);
  338. EXPECT_EQ(preallocated_buf2[BUF_SIZE - 1], 81);
  339. }
  340. TEST_F(shared_heap_test, test_shared_heap_chain_rmw_bulk_memory)
  341. {
  342. SharedHeapInitArgs args = {};
  343. WASMSharedHeap *shared_heap_chain = nullptr;
  344. uint32 argv[3] = {}, BUF_SIZE = os_getpagesize();
  345. uint8 preallocated_buf[BUF_SIZE] = {}, preallocated_buf2[BUF_SIZE] = {};
  346. uint32 start1, end1, start2, end2;
  347. create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
  348. BUF_SIZE, &shared_heap_chain);
  349. /* app addr for shared heap */
  350. start1 = UINT32_MAX - 2 * BUF_SIZE + 1;
  351. end1 = UINT32_MAX - BUF_SIZE;
  352. start2 = UINT32_MAX - BUF_SIZE + 1;
  353. end2 = UINT32_MAX;
  354. argv[0] = end1;
  355. argv[1] = 101;
  356. argv[2] = 1;
  357. test_shared_heap(shared_heap_chain, "test_bulk_memory.wasm",
  358. "memory_fill_test", 3, argv);
  359. /* no modification since no return value */
  360. EXPECT_EQ(end1, argv[0]);
  361. EXPECT_EQ(preallocated_buf[BUF_SIZE - 1], 101);
  362. argv[0] = start1;
  363. argv[1] = 14;
  364. argv[2] = 1;
  365. test_shared_heap(shared_heap_chain, "test_bulk_memory_chain.aot",
  366. "memory_fill_test", 3, argv);
  367. /* no modification since no return value */
  368. EXPECT_EQ(start1, argv[0]);
  369. EXPECT_EQ(preallocated_buf[0], 14);
  370. /* nothing happen when memory fill 0 byte */
  371. argv[0] = start2;
  372. argv[1] = 68;
  373. argv[2] = 0;
  374. test_shared_heap(shared_heap_chain, "test_bulk_memory_chain.aot",
  375. "memory_fill_test", 3, argv);
  376. /* no modification since no return value */
  377. EXPECT_EQ(start2, argv[0]);
  378. EXPECT_EQ(preallocated_buf2[0], 0);
  379. argv[0] = end2;
  380. argv[1] = 98;
  381. argv[2] = 1;
  382. test_shared_heap(shared_heap_chain, "test_bulk_memory_chain.aot",
  383. "memory_fill_test", 3, argv);
  384. /* no modification since no return value */
  385. EXPECT_EQ(end2, argv[0]);
  386. EXPECT_EQ(preallocated_buf2[BUF_SIZE - 1], 98);
  387. }
  388. TEST_F(shared_heap_test, test_shared_heap_chain_rmw_bulk_memory_oob)
  389. {
  390. SharedHeapInitArgs args = {};
  391. WASMSharedHeap *shared_heap_chain = nullptr;
  392. uint32 argv[3] = {}, BUF_SIZE = os_getpagesize();
  393. uint8 preallocated_buf[BUF_SIZE] = {}, preallocated_buf2[BUF_SIZE] = {};
  394. uint32 start1, end1, start2, end2;
  395. create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
  396. BUF_SIZE, &shared_heap_chain);
  397. /* app addr for shared heap */
  398. start1 = UINT32_MAX - 2 * BUF_SIZE + 1;
  399. end1 = UINT32_MAX - BUF_SIZE;
  400. start2 = UINT32_MAX - BUF_SIZE + 1;
  401. end2 = UINT32_MAX;
  402. /* shared heap 1 */
  403. argv[0] = end1;
  404. argv[1] = 101;
  405. argv[2] = 2;
  406. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  407. "test_bulk_memory.wasm",
  408. "memory_fill_test", 3, argv),
  409. "Exception: out of bounds memory access");
  410. argv[0] = end2;
  411. argv[1] = 98;
  412. argv[2] = 2;
  413. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  414. "test_bulk_memory.wasm",
  415. "memory_fill_test", 3, argv),
  416. "Exception: out of bounds memory access");
  417. argv[0] = start1;
  418. argv[1] = 98;
  419. argv[2] = BUF_SIZE + 1;
  420. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  421. "test_bulk_memory.wasm",
  422. "memory_fill_test", 3, argv),
  423. "Exception: out of bounds memory access");
  424. argv[0] = start2;
  425. argv[1] = 98;
  426. argv[2] = BUF_SIZE + 1;
  427. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  428. "test_bulk_memory.wasm",
  429. "memory_fill_test", 3, argv),
  430. "Exception: out of bounds memory access");
  431. argv[0] = end1;
  432. argv[1] = 101;
  433. argv[2] = 2;
  434. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  435. "test_bulk_memory_chain.aot",
  436. "memory_fill_test", 3, argv),
  437. "Exception: out of bounds memory access");
  438. argv[0] = end2;
  439. argv[1] = 98;
  440. argv[2] = 2;
  441. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  442. "test_bulk_memory_chain.aot",
  443. "memory_fill_test", 3, argv),
  444. "Exception: out of bounds memory access");
  445. argv[0] = start1;
  446. argv[1] = 98;
  447. argv[2] = BUF_SIZE + 1;
  448. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  449. "test_bulk_memory_chain.aot",
  450. "memory_fill_test", 3, argv),
  451. "Exception: out of bounds memory access");
  452. argv[0] = start2;
  453. argv[1] = 98;
  454. argv[2] = BUF_SIZE + 1;
  455. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  456. "test_bulk_memory_chain.aot",
  457. "memory_fill_test", 3, argv),
  458. "Exception: out of bounds memory access");
  459. }
  460. TEST_F(shared_heap_test, test_shared_heap_rmw_oob)
  461. {
  462. WASMSharedHeap *shared_heap = nullptr;
  463. uint32 argv[2] = {}, BUF_SIZE = os_getpagesize();
  464. uint8 preallocated_buf[BUF_SIZE], preallocated_buf2[BUF_SIZE];
  465. uint32 start1, end1, start2, end2;
  466. create_test_shared_heap(preallocated_buf, BUF_SIZE, &shared_heap);
  467. /* app addr for shared heap */
  468. start1 = UINT32_MAX - BUF_SIZE + 1;
  469. end1 = UINT32_MAX;
  470. /* try to rmw an u16, first u8 is in the first shared heap and second u8 is
  471. * in the second shared heap, will be seen as oob */
  472. argv[0] = end1;
  473. argv[1] = 12025;
  474. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap, "test.wasm",
  475. "read_modify_write_16", 2, argv),
  476. "Exception: out of bounds memory access");
  477. argv[0] = start1 - 1;
  478. argv[1] = 12025;
  479. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap, "test.aot",
  480. "read_modify_write_16", 2, argv),
  481. "Exception: out of bounds memory access");
  482. argv[0] = end1;
  483. argv[1] = 12025;
  484. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap, "test.aot",
  485. "read_modify_write_16", 2, argv),
  486. "Exception: out of bounds memory access");
  487. }
  488. TEST_F(shared_heap_test, test_shared_heap_chain_rmw_oob)
  489. {
  490. WASMSharedHeap *shared_heap_chain = nullptr;
  491. uint32 argv[2] = {}, BUF_SIZE = os_getpagesize();
  492. uint8 preallocated_buf[BUF_SIZE], preallocated_buf2[BUF_SIZE];
  493. uint32 start1, end1, start2, end2;
  494. create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
  495. BUF_SIZE, &shared_heap_chain);
  496. /* app addr for shared heap */
  497. start1 = UINT32_MAX - 2 * BUF_SIZE + 1;
  498. end1 = UINT32_MAX - BUF_SIZE;
  499. start2 = UINT32_MAX - BUF_SIZE + 1;
  500. end2 = UINT32_MAX;
  501. /* try to rmw an u16, first u8 is in the first shared heap and second u8 is
  502. * in the second shared heap, will be seen as oob */
  503. argv[0] = end2;
  504. argv[1] = 12025;
  505. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain, "test.wasm",
  506. "read_modify_write_16", 2, argv),
  507. "Exception: out of bounds memory access");
  508. argv[0] = end1;
  509. argv[1] = 12025;
  510. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  511. "test_chain.aot",
  512. "read_modify_write_16", 2, argv),
  513. "Exception: out of bounds memory access");
  514. }
  515. #if WASM_ENABLE_MEMORY64 != 0
  516. TEST_F(shared_heap_test, test_shared_heap_chain_memory64_rmw)
  517. {
  518. WASMSharedHeap *shared_heap_chain = nullptr;
  519. uint32 argv[3] = {}, BUF_SIZE = os_getpagesize();
  520. uint8 preallocated_buf[BUF_SIZE] = {}, preallocated_buf2[BUF_SIZE] = {};
  521. uint64 start1, end1, start2, end2;
  522. create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
  523. BUF_SIZE, &shared_heap_chain);
  524. /* app addr for shared heap */
  525. start1 = UINT64_MAX - 2 * BUF_SIZE + 1;
  526. end1 = UINT64_MAX - BUF_SIZE;
  527. start2 = UINT64_MAX - BUF_SIZE + 1;
  528. end2 = UINT64_MAX;
  529. /* shared heap 1 */
  530. PUT_I64_TO_ADDR(argv, end1);
  531. argv[2] = 101;
  532. test_shared_heap(shared_heap_chain, "test64.wasm", "read_modify_write_8", 3,
  533. argv);
  534. EXPECT_EQ(0, argv[0]);
  535. EXPECT_EQ(preallocated_buf[BUF_SIZE - 1], 101);
  536. /* shared heap 2 */
  537. PUT_I64_TO_ADDR(argv, start2);
  538. argv[2] = 129;
  539. test_shared_heap(shared_heap_chain, "test64.wasm", "read_modify_write_8", 3,
  540. argv);
  541. EXPECT_EQ(0, argv[0]);
  542. EXPECT_EQ(preallocated_buf2[0], 129);
  543. PUT_I64_TO_ADDR(argv, start1);
  544. argv[2] = 98;
  545. test_shared_heap(shared_heap_chain, "test64_chain.aot",
  546. "read_modify_write_8", 3, argv);
  547. EXPECT_EQ(0, argv[0]);
  548. EXPECT_EQ(preallocated_buf[0], 98);
  549. PUT_I64_TO_ADDR(argv, end2);
  550. argv[2] = 81;
  551. test_shared_heap(shared_heap_chain, "test64_chain.aot",
  552. "read_modify_write_8", 3, argv);
  553. EXPECT_EQ(0, argv[0]);
  554. EXPECT_EQ(preallocated_buf2[BUF_SIZE - 1], 81);
  555. }
  556. TEST_F(shared_heap_test, test_shared_heap_chain_memory64_rmw_oob)
  557. {
  558. WASMSharedHeap *shared_heap_chain = nullptr;
  559. uint32 argv[3] = {}, BUF_SIZE = os_getpagesize();
  560. uint8 preallocated_buf[BUF_SIZE], preallocated_buf2[BUF_SIZE];
  561. uint64 start1, end1, start2, end2;
  562. create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
  563. BUF_SIZE, &shared_heap_chain);
  564. /* app addr for shared heap */
  565. start1 = UINT64_MAX - 2 * BUF_SIZE + 1;
  566. end1 = UINT64_MAX - BUF_SIZE;
  567. start2 = UINT64_MAX - BUF_SIZE + 1;
  568. end2 = UINT64_MAX;
  569. /* try to rmw an u16, first u8 is in the first shared heap and second u8 is
  570. * in the second shared heap, will be seen as oob */
  571. PUT_I64_TO_ADDR(argv, end1);
  572. argv[2] = 12025;
  573. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain, "test64.wasm",
  574. "read_modify_write_16", 3, argv),
  575. "Exception: out of bounds memory access");
  576. PUT_I64_TO_ADDR(argv, end1);
  577. argv[2] = 12025;
  578. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  579. "test64_chain.aot",
  580. "read_modify_write_16", 3, argv),
  581. "Exception: out of bounds memory access");
  582. }
  583. #endif
  584. #ifndef native_function
  585. /* clang-format off */
  586. #define native_function(func_name, signature) \
  587. { #func_name, (void *)glue_## func_name, signature, NULL }
  588. /* clang-format on */
  589. #endif
  590. #ifndef nitems
  591. #define nitems(_a) (sizeof(_a) / sizeof(0 [(_a)]))
  592. #endif /* nitems */
  593. uintptr_t
  594. glue_test_addr_conv(wasm_exec_env_t env, uintptr_t addr)
  595. {
  596. wasm_module_inst_t module_inst = get_module_inst(env);
  597. void *native_addr = (void *)addr;
  598. uintptr_t app_addr = addr_native_to_app(native_addr);
  599. native_addr = addr_app_to_native(app_addr);
  600. if (native_addr != (void *)addr) {
  601. ADD_FAILURE() << "address conversion incorrect";
  602. return 0;
  603. }
  604. return app_addr;
  605. }
  606. static NativeSymbol g_test_native_symbols[] = {
  607. native_function(test_addr_conv, "(*)i"),
  608. };
  609. TEST_F(shared_heap_test, test_addr_conv)
  610. {
  611. SharedHeapInitArgs args = {};
  612. WASMSharedHeap *shared_heap = nullptr;
  613. uint32 argv[1] = {};
  614. bool ret = false;
  615. ret = wasm_native_register_natives("env", g_test_native_symbols,
  616. nitems(g_test_native_symbols));
  617. if (!ret) {
  618. FAIL() << "Failed to register natives";
  619. }
  620. args.size = 1024;
  621. shared_heap = wasm_runtime_create_shared_heap(&args);
  622. if (!shared_heap) {
  623. FAIL() << "Failed to create shared heap";
  624. }
  625. test_shared_heap(shared_heap, "test_addr_conv.wasm", "test", 0, argv);
  626. EXPECT_EQ(1, argv[0]);
  627. test_shared_heap(shared_heap, "test_addr_conv.aot", "test", 0, argv);
  628. EXPECT_EQ(1, argv[0]);
  629. test_shared_heap(shared_heap, "test_addr_conv_chain.aot", "test", 0, argv);
  630. EXPECT_EQ(1, argv[0]);
  631. }
  632. TEST_F(shared_heap_test, test_addr_conv_pre_allocated_oob)
  633. {
  634. SharedHeapInitArgs args = {};
  635. WASMSharedHeap *shared_heap = nullptr;
  636. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize(),
  637. app_addr = 0xFFFFFFFF - BUF_SIZE;
  638. uint8 preallocated_buf[BUF_SIZE];
  639. bool ret = false;
  640. /* create a preallocated shared heap */
  641. ret = wasm_native_register_natives("env", g_test_native_symbols,
  642. nitems(g_test_native_symbols));
  643. if (!ret) {
  644. FAIL() << "Failed to register natives";
  645. }
  646. args.pre_allocated_addr = preallocated_buf;
  647. args.size = BUF_SIZE;
  648. shared_heap = wasm_runtime_create_shared_heap(&args);
  649. if (!shared_heap) {
  650. FAIL() << "Failed to create shared heap";
  651. }
  652. argv[0] = app_addr;
  653. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap, "test_addr_conv.wasm",
  654. "test_preallocated", 1, argv),
  655. "Exception: out of bounds memory access");
  656. argv[0] = app_addr;
  657. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap, "test_addr_conv.aot",
  658. "test_preallocated", 1, argv),
  659. "Exception: out of bounds memory access");
  660. argv[0] = app_addr;
  661. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap,
  662. "test_addr_conv_chain.aot",
  663. "test_preallocated", 1, argv),
  664. "Exception: out of bounds memory access");
  665. }
  666. TEST_F(shared_heap_test, test_shared_heap_chain)
  667. {
  668. SharedHeapInitArgs args = {};
  669. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  670. *shared_heap_chain = nullptr;
  671. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  672. uint8 preallocated_buf[BUF_SIZE];
  673. bool ret = false;
  674. ret = wasm_native_register_natives("env", g_test_native_symbols,
  675. nitems(g_test_native_symbols));
  676. if (!ret) {
  677. FAIL() << "Failed to register natives";
  678. }
  679. args.size = 1024;
  680. shared_heap = wasm_runtime_create_shared_heap(&args);
  681. if (!shared_heap) {
  682. FAIL() << "Failed to create shared heap";
  683. }
  684. /* create a preallocated shared heap */
  685. memset(&args, 0, sizeof(args));
  686. args.pre_allocated_addr = preallocated_buf;
  687. args.size = BUF_SIZE;
  688. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  689. if (!shared_heap2) {
  690. FAIL() << "Create preallocated shared heap failed.\n";
  691. }
  692. shared_heap_chain =
  693. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  694. if (!shared_heap_chain) {
  695. FAIL() << "Create shared heap chain failed.\n";
  696. }
  697. test_shared_heap(shared_heap_chain, "test_addr_conv.wasm", "test", 0, argv);
  698. EXPECT_EQ(1, argv[0]);
  699. test_shared_heap(shared_heap, "test_addr_conv.aot", "test", 0, argv);
  700. EXPECT_EQ(1, argv[0]);
  701. }
  702. TEST_F(shared_heap_test, test_shared_heap_chain_create_fail)
  703. {
  704. SharedHeapInitArgs args = {};
  705. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  706. *shared_heap_chain = nullptr;
  707. args.size = 1024;
  708. shared_heap = wasm_runtime_create_shared_heap(&args);
  709. if (!shared_heap) {
  710. FAIL() << "Failed to create shared heap";
  711. }
  712. args.size = 4096;
  713. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  714. if (!shared_heap2) {
  715. FAIL() << "Create preallocated shared heap failed.\n";
  716. }
  717. shared_heap_chain =
  718. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  719. EXPECT_EQ(shared_heap_chain, nullptr);
  720. }
  721. TEST_F(shared_heap_test, test_shared_heap_chain_create_fail2)
  722. {
  723. SharedHeapInitArgs args = {};
  724. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  725. *shared_heap_chain = nullptr;
  726. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  727. uint8 preallocated_buf[BUF_SIZE];
  728. struct ret_env tmp_module_env;
  729. args.size = 1024;
  730. shared_heap = wasm_runtime_create_shared_heap(&args);
  731. if (!shared_heap) {
  732. FAIL() << "Failed to create shared heap";
  733. }
  734. memset(&args, 0, sizeof(args));
  735. args.pre_allocated_addr = preallocated_buf;
  736. args.size = BUF_SIZE;
  737. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  738. if (!shared_heap2) {
  739. FAIL() << "Create preallocated shared heap failed.\n";
  740. }
  741. if (!load_wasm((char *)"test.wasm", 0, tmp_module_env)) {
  742. FAIL() << "Failed to load wasm file\n";
  743. }
  744. if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst,
  745. shared_heap)) {
  746. FAIL() << "Failed to attach shared heap\n";
  747. }
  748. /* can't create shared heap chain when shared heap is attached to a wasm
  749. * app */
  750. shared_heap_chain =
  751. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  752. EXPECT_EQ(shared_heap_chain, nullptr);
  753. wasm_runtime_detach_shared_heap(tmp_module_env.wasm_module_inst);
  754. destroy_module_env(tmp_module_env);
  755. }
  756. TEST_F(shared_heap_test, test_shared_heap_chain_create_fail3)
  757. {
  758. SharedHeapInitArgs args = {};
  759. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  760. *shared_heap3 = nullptr, *shared_heap_chain = nullptr;
  761. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  762. uint8 preallocated_buf[BUF_SIZE], preallocated_buf2[BUF_SIZE];
  763. args.size = 1024;
  764. shared_heap = wasm_runtime_create_shared_heap(&args);
  765. if (!shared_heap) {
  766. FAIL() << "Failed to create shared heap";
  767. }
  768. memset(&args, 0, sizeof(args));
  769. args.pre_allocated_addr = preallocated_buf;
  770. args.size = BUF_SIZE;
  771. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  772. if (!shared_heap2) {
  773. FAIL() << "Create preallocated shared heap failed.\n";
  774. }
  775. shared_heap_chain =
  776. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  777. if (!shared_heap_chain) {
  778. FAIL() << "Create shared heap chain failed.\n";
  779. }
  780. memset(&args, 0, sizeof(args));
  781. args.pre_allocated_addr = preallocated_buf2;
  782. args.size = BUF_SIZE;
  783. shared_heap3 = wasm_runtime_create_shared_heap(&args);
  784. if (!shared_heap3) {
  785. FAIL() << "Failed to create shared heap";
  786. }
  787. /* The head and body can't be already in other shared heap chain as body */
  788. shared_heap_chain =
  789. wasm_runtime_chain_shared_heaps(shared_heap3, shared_heap2);
  790. EXPECT_EQ(shared_heap_chain, nullptr);
  791. shared_heap_chain =
  792. wasm_runtime_chain_shared_heaps(shared_heap2, shared_heap);
  793. EXPECT_EQ(shared_heap_chain, nullptr);
  794. }
  795. TEST_F(shared_heap_test, test_shared_heap_chain_unchain)
  796. {
  797. SharedHeapInitArgs args = {};
  798. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  799. *shared_heap3 = nullptr, *shared_heap_chain = nullptr;
  800. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  801. uint8 preallocated_buf[BUF_SIZE], preallocated_buf2[BUF_SIZE];
  802. args.size = 1024;
  803. shared_heap = wasm_runtime_create_shared_heap(&args);
  804. if (!shared_heap) {
  805. FAIL() << "Failed to create shared heap";
  806. }
  807. memset(&args, 0, sizeof(args));
  808. args.pre_allocated_addr = preallocated_buf;
  809. args.size = BUF_SIZE;
  810. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  811. if (!shared_heap2) {
  812. FAIL() << "Create preallocated shared heap failed.\n";
  813. }
  814. shared_heap_chain =
  815. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  816. if (!shared_heap_chain) {
  817. FAIL() << "Create shared heap chain failed.\n";
  818. }
  819. memset(&args, 0, sizeof(args));
  820. args.pre_allocated_addr = preallocated_buf2;
  821. args.size = BUF_SIZE;
  822. shared_heap3 = wasm_runtime_create_shared_heap(&args);
  823. if (!shared_heap3) {
  824. FAIL() << "Failed to create shared heap";
  825. }
  826. /* unchain shared heap so that the 'body' can be another chain 'body'
  827. * again(1->2 to 1->3->2) */
  828. EXPECT_EQ(shared_heap2,
  829. wasm_runtime_unchain_shared_heaps(shared_heap_chain, false));
  830. shared_heap_chain =
  831. wasm_runtime_chain_shared_heaps(shared_heap3, shared_heap2);
  832. EXPECT_EQ(shared_heap_chain, shared_heap3);
  833. shared_heap_chain =
  834. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap3);
  835. EXPECT_EQ(shared_heap, shared_heap_chain);
  836. /* break down the entire shared heap chain */
  837. EXPECT_EQ(shared_heap2,
  838. wasm_runtime_unchain_shared_heaps(shared_heap_chain, true));
  839. }
  840. TEST_F(shared_heap_test, test_shared_heap_chain_reset_runtime_managed)
  841. {
  842. SharedHeapInitArgs args = {};
  843. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  844. *shared_heap_chain = nullptr;
  845. uint8 buf_size = 64;
  846. uint64 offset = 0, offset_after_reset = 0;
  847. void *native_ptr = nullptr, *native_ptr_after_reset = nullptr;
  848. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  849. uint8 preallocated_buf[BUF_SIZE];
  850. struct ret_env tmp_module_env;
  851. args.size = 4096;
  852. shared_heap = wasm_runtime_create_shared_heap(&args);
  853. if (!shared_heap) {
  854. FAIL() << "Failed to create shared heap";
  855. }
  856. args.size = BUF_SIZE;
  857. args.pre_allocated_addr = preallocated_buf;
  858. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  859. if (!shared_heap2) {
  860. FAIL() << "Failed to create second shared heap";
  861. }
  862. shared_heap_chain =
  863. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  864. if (!shared_heap_chain) {
  865. FAIL() << "Create shared heap chain failed.\n";
  866. }
  867. if (!load_wasm((char *)"test.wasm", 0, tmp_module_env)) {
  868. FAIL() << "Failed to load wasm file\n";
  869. }
  870. if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst,
  871. shared_heap_chain)) {
  872. destroy_module_env(tmp_module_env);
  873. FAIL() << "Failed to attach shared heap chain";
  874. }
  875. offset = wasm_runtime_shared_heap_malloc(tmp_module_env.wasm_module_inst,
  876. buf_size, &native_ptr);
  877. ASSERT_NE(0u, offset);
  878. ASSERT_NE(nullptr, native_ptr);
  879. memset(native_ptr, 0x5A, buf_size);
  880. for (uint8 i = 0; i < buf_size; i++) {
  881. EXPECT_EQ(0x5A, *((uint8 *)native_ptr + i));
  882. }
  883. wasm_runtime_detach_shared_heap(tmp_module_env.wasm_module_inst);
  884. EXPECT_TRUE(wasm_runtime_reset_shared_heap_chain(shared_heap_chain));
  885. if (!load_wasm((char *)"test.wasm", 0, tmp_module_env)) {
  886. FAIL() << "Failed to load wasm file after reset\n";
  887. }
  888. if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst,
  889. shared_heap_chain)) {
  890. destroy_module_env(tmp_module_env);
  891. FAIL() << "Failed to attach shared heap chain after reset";
  892. }
  893. offset_after_reset = wasm_runtime_shared_heap_malloc(
  894. tmp_module_env.wasm_module_inst, buf_size, &native_ptr_after_reset);
  895. ASSERT_NE(0u, offset_after_reset);
  896. ASSERT_NE(nullptr, native_ptr_after_reset);
  897. EXPECT_EQ(offset, offset_after_reset);
  898. EXPECT_EQ(native_ptr, native_ptr_after_reset);
  899. /* Only on some platform, the os_mmap will memset the memory to 0
  900. for (uint8 i = 0; i < buf_size; i++) {
  901. EXPECT_EQ(0, *((uint8 *)native_ptr_after_reset + i));
  902. }
  903. */
  904. wasm_runtime_detach_shared_heap(tmp_module_env.wasm_module_inst);
  905. destroy_module_env(tmp_module_env);
  906. }
  907. TEST_F(shared_heap_test, test_shared_heap_chain_reset_preallocated)
  908. {
  909. SharedHeapInitArgs args = {};
  910. WASMSharedHeap *shared_heap = nullptr;
  911. uint32 BUF_SIZE = os_getpagesize();
  912. uint8 preallocated_buf[BUF_SIZE];
  913. uint8 set_val = 0xA5;
  914. args.pre_allocated_addr = preallocated_buf;
  915. args.size = BUF_SIZE;
  916. shared_heap = wasm_runtime_create_shared_heap(&args);
  917. if (!shared_heap) {
  918. FAIL() << "Create preallocated shared heap failed.\n";
  919. }
  920. memset(preallocated_buf, set_val, BUF_SIZE);
  921. for (uint32 i = 0; i < BUF_SIZE; i++) {
  922. EXPECT_EQ(set_val, preallocated_buf[i]);
  923. }
  924. EXPECT_TRUE(wasm_runtime_reset_shared_heap_chain(shared_heap));
  925. for (uint32 i = 0; i < BUF_SIZE; i++) {
  926. EXPECT_EQ(0, preallocated_buf[i]);
  927. }
  928. }
  929. TEST_F(shared_heap_test, test_shared_heap_chain_reset_attached_fail)
  930. {
  931. SharedHeapInitArgs args = {};
  932. WASMSharedHeap *shared_heap = nullptr;
  933. struct ret_env module_env = {};
  934. bool ret;
  935. args.size = 1024;
  936. shared_heap = wasm_runtime_create_shared_heap(&args);
  937. if (!shared_heap) {
  938. FAIL() << "Failed to create shared heap";
  939. }
  940. ret = load_wasm((char *)"test.wasm", 0, module_env);
  941. if (!ret) {
  942. FAIL() << "Failed to load wasm";
  943. }
  944. ret = wasm_runtime_attach_shared_heap(module_env.wasm_module_inst,
  945. shared_heap);
  946. if (!ret) {
  947. destroy_module_env(module_env);
  948. FAIL() << "Failed to attach shared heap";
  949. }
  950. EXPECT_FALSE(wasm_runtime_reset_shared_heap_chain(shared_heap));
  951. wasm_runtime_detach_shared_heap(module_env.wasm_module_inst);
  952. destroy_module_env(module_env);
  953. EXPECT_TRUE(wasm_runtime_reset_shared_heap_chain(shared_heap));
  954. }
  955. TEST_F(shared_heap_test, test_shared_heap_chain_addr_conv)
  956. {
  957. SharedHeapInitArgs args = {};
  958. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  959. *shared_heap_chain = nullptr;
  960. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  961. uint8 preallocated_buf[BUF_SIZE];
  962. bool ret = false;
  963. ret = wasm_native_register_natives("env", g_test_native_symbols,
  964. nitems(g_test_native_symbols));
  965. if (!ret) {
  966. FAIL() << "Failed to register natives";
  967. }
  968. args.size = 4096;
  969. shared_heap = wasm_runtime_create_shared_heap(&args);
  970. if (!shared_heap) {
  971. FAIL() << "Failed to create shared heap";
  972. }
  973. /* create a preallocated shared heap */
  974. memset(&args, 0, sizeof(args));
  975. args.pre_allocated_addr = preallocated_buf;
  976. args.size = BUF_SIZE;
  977. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  978. if (!shared_heap2) {
  979. FAIL() << "Create preallocated shared heap failed.\n";
  980. }
  981. shared_heap_chain =
  982. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  983. if (!shared_heap_chain) {
  984. FAIL() << "Create shared heap chain failed.\n";
  985. }
  986. argv[0] = 0xFFFFFFFF;
  987. test_shared_heap(shared_heap_chain, "test_addr_conv.wasm",
  988. "test_preallocated", 1, argv);
  989. EXPECT_EQ(1, argv[0]);
  990. argv[0] = 0xFFFFF000;
  991. test_shared_heap(shared_heap_chain, "test_addr_conv.wasm",
  992. "test_preallocated", 1, argv);
  993. EXPECT_EQ(1, argv[0]);
  994. argv[0] = 0xFFFFFFFF;
  995. test_shared_heap(shared_heap, "test_addr_conv_chain.aot",
  996. "test_preallocated", 1, argv);
  997. EXPECT_EQ(1, argv[0]);
  998. argv[0] = 0xFFFFF000;
  999. test_shared_heap(shared_heap, "test_addr_conv_chain.aot",
  1000. "test_preallocated", 1, argv);
  1001. EXPECT_EQ(1, argv[0]);
  1002. }
  1003. TEST_F(shared_heap_test, test_shared_heap_chain_addr_conv_oob)
  1004. {
  1005. SharedHeapInitArgs args = {};
  1006. WASMSharedHeap *shared_heap = nullptr, *shared_heap2 = nullptr,
  1007. *shared_heap_chain = nullptr;
  1008. uint32 argv[1] = {}, BUF_SIZE = os_getpagesize();
  1009. uint8 preallocated_buf[BUF_SIZE];
  1010. bool ret = false;
  1011. ret = wasm_native_register_natives("env", g_test_native_symbols,
  1012. nitems(g_test_native_symbols));
  1013. if (!ret) {
  1014. FAIL() << "Failed to register natives";
  1015. }
  1016. args.size = 4096;
  1017. shared_heap = wasm_runtime_create_shared_heap(&args);
  1018. if (!shared_heap) {
  1019. FAIL() << "Failed to create shared heap";
  1020. }
  1021. /* create a preallocated shared heap */
  1022. memset(&args, 0, sizeof(args));
  1023. args.pre_allocated_addr = preallocated_buf;
  1024. args.size = BUF_SIZE;
  1025. shared_heap2 = wasm_runtime_create_shared_heap(&args);
  1026. if (!shared_heap2) {
  1027. FAIL() << "Create preallocated shared heap failed.\n";
  1028. }
  1029. shared_heap_chain =
  1030. wasm_runtime_chain_shared_heaps(shared_heap, shared_heap2);
  1031. if (!shared_heap_chain) {
  1032. FAIL() << "Create shared heap chain failed.\n";
  1033. }
  1034. /* test wasm */
  1035. argv[0] = 0xFFFFFFFF - BUF_SIZE - 4096;
  1036. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  1037. "test_addr_conv.wasm",
  1038. "test_preallocated", 1, argv),
  1039. "Exception: out of bounds memory access");
  1040. /* test aot */
  1041. argv[0] = 0xFFFFFFFF - BUF_SIZE - 4096;
  1042. EXPECT_NONFATAL_FAILURE(test_shared_heap(shared_heap_chain,
  1043. "test_addr_conv_chain.aot",
  1044. "test_preallocated", 1, argv),
  1045. "Exception: out of bounds memory access");
  1046. }