shared_heap_test.cc 46 KB

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