handler.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. /*
  2. * Copyright (C) 2021 Ant Group. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "bh_platform.h"
  6. #include "handler.h"
  7. #include "debug_engine.h"
  8. #include "packets.h"
  9. #include "utils.h"
  10. #include "wasm_runtime.h"
  11. #define MAX_PACKET_SIZE (0x20000)
  12. static char tmpbuf[MAX_PACKET_SIZE];
  13. static korp_mutex tmpbuf_lock;
  14. int
  15. wasm_debug_handler_init()
  16. {
  17. return os_mutex_init(&tmpbuf_lock);
  18. }
  19. void
  20. wasm_debug_handler_deinit()
  21. {
  22. os_mutex_destroy(&tmpbuf_lock);
  23. }
  24. static void
  25. send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid);
  26. void
  27. handle_generay_set(WASMGDBServer *server, char *payload)
  28. {
  29. const char *name;
  30. char *args;
  31. args = strchr(payload, ':');
  32. if (args)
  33. *args++ = '\0';
  34. name = payload;
  35. LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
  36. if (!strcmp(name, "StartNoAckMode")) {
  37. server->noack = true;
  38. write_packet(server, "OK");
  39. }
  40. if (!strcmp(name, "ThreadSuffixSupported")) {
  41. write_packet(server, "");
  42. }
  43. if (!strcmp(name, "ListThreadsInStopReply")) {
  44. write_packet(server, "");
  45. }
  46. if (!strcmp(name, "EnableErrorStrings")) {
  47. write_packet(server, "OK");
  48. }
  49. }
  50. static void
  51. process_xfer(WASMGDBServer *server, const char *name, char *args)
  52. {
  53. const char *mode = args;
  54. args = strchr(args, ':');
  55. if (args)
  56. *args++ = '\0';
  57. if (!strcmp(name, "libraries") && !strcmp(mode, "read")) {
  58. // TODO: how to get current wasm file name?
  59. uint64 addr = wasm_debug_instance_get_load_addr(
  60. (WASMDebugInstance *)server->thread->debug_instance);
  61. os_mutex_lock(&tmpbuf_lock);
  62. #if WASM_ENABLE_LIBC_WASI != 0
  63. char objname[128];
  64. wasm_debug_instance_get_current_object_name(
  65. (WASMDebugInstance *)server->thread->debug_instance, objname, 128);
  66. snprintf(tmpbuf, sizeof(tmpbuf),
  67. "l<library-list><library name=\"%s\"><section "
  68. "address=\"0x%" PRIx64 "\"/></library></library-list>",
  69. objname, addr);
  70. #else
  71. snprintf(tmpbuf, sizeof(tmpbuf),
  72. "l<library-list><library name=\"%s\"><section "
  73. "address=\"0x%" PRIx64 "\"/></library></library-list>",
  74. "nobody.wasm", addr);
  75. #endif
  76. write_packet(server, tmpbuf);
  77. os_mutex_unlock(&tmpbuf_lock);
  78. }
  79. }
  80. void
  81. porcess_wasm_local(WASMGDBServer *server, char *args)
  82. {
  83. int32 frame_index;
  84. int32 local_index;
  85. char buf[16];
  86. int32 size = 16;
  87. bool ret;
  88. os_mutex_lock(&tmpbuf_lock);
  89. snprintf(tmpbuf, sizeof(tmpbuf), "E01");
  90. if (sscanf(args, "%" PRId32 ";%" PRId32, &frame_index, &local_index) == 2) {
  91. ret = wasm_debug_instance_get_local(
  92. (WASMDebugInstance *)server->thread->debug_instance, frame_index,
  93. local_index, buf, &size);
  94. if (ret && size > 0) {
  95. mem2hex(buf, tmpbuf, size);
  96. }
  97. }
  98. write_packet(server, tmpbuf);
  99. os_mutex_unlock(&tmpbuf_lock);
  100. }
  101. void
  102. porcess_wasm_global(WASMGDBServer *server, char *args)
  103. {
  104. int32 frame_index;
  105. int32 global_index;
  106. char buf[16];
  107. int32 size = 16;
  108. bool ret;
  109. os_mutex_lock(&tmpbuf_lock);
  110. snprintf(tmpbuf, sizeof(tmpbuf), "E01");
  111. if (sscanf(args, "%" PRId32 ";%" PRId32, &frame_index, &global_index)
  112. == 2) {
  113. ret = wasm_debug_instance_get_global(
  114. (WASMDebugInstance *)server->thread->debug_instance, frame_index,
  115. global_index, buf, &size);
  116. if (ret && size > 0) {
  117. mem2hex(buf, tmpbuf, size);
  118. }
  119. }
  120. write_packet(server, tmpbuf);
  121. os_mutex_unlock(&tmpbuf_lock);
  122. }
  123. void
  124. handle_generay_query(WASMGDBServer *server, char *payload)
  125. {
  126. const char *name;
  127. char *args;
  128. char triple[256];
  129. args = strchr(payload, ':');
  130. if (args)
  131. *args++ = '\0';
  132. name = payload;
  133. LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
  134. if (!strcmp(name, "C")) {
  135. uint64 pid, tid;
  136. pid = wasm_debug_instance_get_pid(
  137. (WASMDebugInstance *)server->thread->debug_instance);
  138. tid = (uint64)(uintptr_t)wasm_debug_instance_get_tid(
  139. (WASMDebugInstance *)server->thread->debug_instance);
  140. os_mutex_lock(&tmpbuf_lock);
  141. snprintf(tmpbuf, sizeof(tmpbuf), "QCp%" PRIx64 ".%" PRIx64 "", pid,
  142. tid);
  143. write_packet(server, tmpbuf);
  144. os_mutex_unlock(&tmpbuf_lock);
  145. }
  146. if (!strcmp(name, "Supported")) {
  147. os_mutex_lock(&tmpbuf_lock);
  148. snprintf(tmpbuf, sizeof(tmpbuf),
  149. "qXfer:libraries:read+;PacketSize=%" PRIx32 ";",
  150. MAX_PACKET_SIZE);
  151. write_packet(server, tmpbuf);
  152. os_mutex_unlock(&tmpbuf_lock);
  153. }
  154. if (!strcmp(name, "Xfer")) {
  155. name = args;
  156. if (!args) {
  157. LOG_ERROR("payload parse error during handle_generay_query");
  158. return;
  159. }
  160. args = strchr(args, ':');
  161. if (args) {
  162. *args++ = '\0';
  163. process_xfer(server, name, args);
  164. }
  165. }
  166. if (!strcmp(name, "HostInfo")) {
  167. // Todo: change vendor to Intel for outside tree?
  168. mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
  169. os_mutex_lock(&tmpbuf_lock);
  170. snprintf(tmpbuf, sizeof(tmpbuf),
  171. "vendor:Ant;ostype:wasi;arch:wasm32;"
  172. "triple:%s;endian:little;ptrsize:4;",
  173. triple);
  174. write_packet(server, tmpbuf);
  175. os_mutex_unlock(&tmpbuf_lock);
  176. }
  177. if (!strcmp(name, "ModuleInfo")) {
  178. write_packet(server, "");
  179. }
  180. if (!strcmp(name, "GetWorkingDir")) {
  181. os_mutex_lock(&tmpbuf_lock);
  182. if (getcwd(tmpbuf, PATH_MAX))
  183. write_packet(server, tmpbuf);
  184. os_mutex_unlock(&tmpbuf_lock);
  185. }
  186. if (!strcmp(name, "QueryGDBServer")) {
  187. write_packet(server, "");
  188. }
  189. if (!strcmp(name, "VAttachOrWaitSupported")) {
  190. write_packet(server, "");
  191. }
  192. if (!strcmp(name, "ProcessInfo")) {
  193. // Todo: process id parent-pid
  194. uint64 pid;
  195. pid = wasm_debug_instance_get_pid(
  196. (WASMDebugInstance *)server->thread->debug_instance);
  197. // arch-vendor-os-env(format)
  198. mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
  199. os_mutex_lock(&tmpbuf_lock);
  200. snprintf(tmpbuf, sizeof(tmpbuf),
  201. "pid:%" PRIx64 ";parent-pid:%" PRIx64
  202. ";vendor:Ant;ostype:wasi;arch:wasm32;"
  203. "triple:%s;endian:little;ptrsize:4;",
  204. pid, pid, triple);
  205. write_packet(server, tmpbuf);
  206. os_mutex_unlock(&tmpbuf_lock);
  207. }
  208. if (!strcmp(name, "RegisterInfo0")) {
  209. os_mutex_lock(&tmpbuf_lock);
  210. snprintf(
  211. tmpbuf, sizeof(tmpbuf),
  212. "name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;"
  213. "set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;");
  214. write_packet(server, tmpbuf);
  215. os_mutex_unlock(&tmpbuf_lock);
  216. }
  217. else if (!strncmp(name, "RegisterInfo", strlen("RegisterInfo"))) {
  218. write_packet(server, "E45");
  219. }
  220. if (!strcmp(name, "StructuredDataPlugins")) {
  221. write_packet(server, "");
  222. }
  223. if (args && (!strcmp(name, "MemoryRegionInfo"))) {
  224. uint64 addr = strtoll(args, NULL, 16);
  225. WASMDebugMemoryInfo *mem_info = wasm_debug_instance_get_memregion(
  226. (WASMDebugInstance *)server->thread->debug_instance, addr);
  227. if (mem_info) {
  228. char name_buf[256];
  229. mem2hex(mem_info->name, name_buf, strlen(mem_info->name));
  230. os_mutex_lock(&tmpbuf_lock);
  231. snprintf(tmpbuf, sizeof(tmpbuf),
  232. "start:%" PRIx64 ";size:%" PRIx64
  233. ";permissions:%s;name:%s;",
  234. (uint64)mem_info->start, mem_info->size,
  235. mem_info->permisson, name_buf);
  236. write_packet(server, tmpbuf);
  237. os_mutex_unlock(&tmpbuf_lock);
  238. wasm_debug_instance_destroy_memregion(
  239. (WASMDebugInstance *)server->thread->debug_instance, mem_info);
  240. }
  241. }
  242. if (!strcmp(name, "WasmData")) {
  243. }
  244. if (!strcmp(name, "WasmMem")) {
  245. }
  246. if (!strcmp(name, "Symbol")) {
  247. write_packet(server, "");
  248. }
  249. if (args && (!strcmp(name, "WasmCallStack"))) {
  250. uint64 tid = strtoll(args, NULL, 16);
  251. uint64 buf[1024 / sizeof(uint64)];
  252. uint32 count = wasm_debug_instance_get_call_stack_pcs(
  253. (WASMDebugInstance *)server->thread->debug_instance,
  254. (korp_tid)(uintptr_t)tid, buf, 1024 / sizeof(uint64));
  255. if (count > 0) {
  256. os_mutex_lock(&tmpbuf_lock);
  257. mem2hex((char *)buf, tmpbuf, count * sizeof(uint64));
  258. write_packet(server, tmpbuf);
  259. os_mutex_unlock(&tmpbuf_lock);
  260. }
  261. else
  262. write_packet(server, "");
  263. }
  264. if (args && (!strcmp(name, "WasmLocal"))) {
  265. porcess_wasm_local(server, args);
  266. }
  267. if (args && (!strcmp(name, "WasmGlobal"))) {
  268. porcess_wasm_global(server, args);
  269. }
  270. if (!strcmp(name, "Offsets")) {
  271. write_packet(server, "");
  272. }
  273. if (!strncmp(name, "ThreadStopInfo", strlen("ThreadStopInfo"))) {
  274. int32 prefix_len = strlen("ThreadStopInfo");
  275. uint64 tid_number = strtoll(name + prefix_len, NULL, 16);
  276. korp_tid tid = (korp_tid)(uintptr_t)tid_number;
  277. uint32 status;
  278. status = wasm_debug_instance_get_thread_status(
  279. server->thread->debug_instance, tid);
  280. send_thread_stop_status(server, status, tid);
  281. }
  282. }
  283. static void
  284. send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
  285. {
  286. int32 len = 0;
  287. uint64 pc;
  288. korp_tid tids[20];
  289. char pc_string[17];
  290. uint32 tids_count, i = 0;
  291. uint32 gdb_status = status;
  292. if (status == 0) {
  293. os_mutex_lock(&tmpbuf_lock);
  294. snprintf(tmpbuf, sizeof(tmpbuf), "W%02x", status);
  295. write_packet(server, tmpbuf);
  296. os_mutex_unlock(&tmpbuf_lock);
  297. return;
  298. }
  299. tids_count = wasm_debug_instance_get_tids(
  300. (WASMDebugInstance *)server->thread->debug_instance, tids, 20);
  301. pc = wasm_debug_instance_get_pc(
  302. (WASMDebugInstance *)server->thread->debug_instance);
  303. if (status == WAMR_SIG_SINGSTEP) {
  304. gdb_status = WAMR_SIG_TRAP;
  305. }
  306. os_mutex_lock(&tmpbuf_lock);
  307. // TODO: how name a wasm thread?
  308. len += snprintf(tmpbuf, sizeof(tmpbuf), "T%02xthread:%" PRIx64 ";name:%s;",
  309. gdb_status, (uint64)(uintptr_t)tid, "nobody");
  310. if (tids_count > 0) {
  311. len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "threads:");
  312. while (i < tids_count) {
  313. if (i == tids_count - 1)
  314. len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
  315. "%" PRIx64 ";", (uint64)(uintptr_t)tids[i]);
  316. else
  317. len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
  318. "%" PRIx64 ",", (uint64)(uintptr_t)tids[i]);
  319. i++;
  320. }
  321. }
  322. mem2hex((void *)&pc, pc_string, 8);
  323. pc_string[8 * 2] = '\0';
  324. if (status == WAMR_SIG_TRAP) {
  325. len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
  326. "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
  327. pc_string, "breakpoint");
  328. }
  329. else if (status == WAMR_SIG_SINGSTEP) {
  330. len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
  331. "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
  332. pc_string, "trace");
  333. }
  334. else if (status > 0) {
  335. len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
  336. "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
  337. pc_string, "signal");
  338. }
  339. write_packet(server, tmpbuf);
  340. os_mutex_unlock(&tmpbuf_lock);
  341. }
  342. void
  343. handle_v_packet(WASMGDBServer *server, char *payload)
  344. {
  345. const char *name;
  346. char *args;
  347. uint32 status;
  348. args = strchr(payload, ';');
  349. if (args)
  350. *args++ = '\0';
  351. name = payload;
  352. LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
  353. if (!strcmp("Cont?", name))
  354. write_packet(server, "vCont;c;C;s;S;");
  355. if (!strcmp("Cont", name)) {
  356. if (args) {
  357. if (args[0] == 's' || args[0] == 'c') {
  358. char *numstring = strchr(args, ':');
  359. if (numstring) {
  360. uint64 tid_number;
  361. korp_tid tid;
  362. *numstring++ = '\0';
  363. tid_number = strtoll(numstring, NULL, 16);
  364. tid = (korp_tid)(uintptr_t)tid_number;
  365. wasm_debug_instance_set_cur_thread(
  366. (WASMDebugInstance *)server->thread->debug_instance,
  367. tid);
  368. if (args[0] == 's') {
  369. wasm_debug_instance_singlestep(
  370. (WASMDebugInstance *)server->thread->debug_instance,
  371. tid);
  372. }
  373. else {
  374. wasm_debug_instance_continue(
  375. (WASMDebugInstance *)
  376. server->thread->debug_instance);
  377. }
  378. tid = wasm_debug_instance_wait_thread(
  379. (WASMDebugInstance *)server->thread->debug_instance,
  380. tid, &status);
  381. send_thread_stop_status(server, status, tid);
  382. }
  383. }
  384. }
  385. }
  386. }
  387. void
  388. handle_threadstop_request(WASMGDBServer *server, char *payload)
  389. {
  390. korp_tid tid = wasm_debug_instance_get_tid(
  391. (WASMDebugInstance *)server->thread->debug_instance);
  392. uint32 status;
  393. tid = wasm_debug_instance_wait_thread(
  394. (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
  395. send_thread_stop_status(server, status, tid);
  396. }
  397. void
  398. handle_set_current_thread(WASMGDBServer *server, char *payload)
  399. {
  400. LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload, payload);
  401. if ('g' == *payload++) {
  402. uint64 tid = strtoll(payload, NULL, 16);
  403. if (tid > 0)
  404. wasm_debug_instance_set_cur_thread(
  405. (WASMDebugInstance *)server->thread->debug_instance,
  406. (korp_tid)(uintptr_t)tid);
  407. }
  408. write_packet(server, "OK");
  409. }
  410. void
  411. handle_get_register(WASMGDBServer *server, char *payload)
  412. {
  413. uint64 regdata;
  414. int32 i = strtol(payload, NULL, 16);
  415. if (i != 0) {
  416. write_packet(server, "E01");
  417. return;
  418. }
  419. regdata = wasm_debug_instance_get_pc(
  420. (WASMDebugInstance *)server->thread->debug_instance);
  421. os_mutex_lock(&tmpbuf_lock);
  422. mem2hex((void *)&regdata, tmpbuf, 8);
  423. tmpbuf[8 * 2] = '\0';
  424. write_packet(server, tmpbuf);
  425. os_mutex_unlock(&tmpbuf_lock);
  426. }
  427. void
  428. handle_get_json_request(WASMGDBServer *server, char *payload)
  429. {
  430. char *args;
  431. args = strchr(payload, ':');
  432. if (args)
  433. *args++ = '\0';
  434. write_packet(server, "");
  435. }
  436. void
  437. handle_get_read_binary_memory(WASMGDBServer *server, char *payload)
  438. {
  439. write_packet(server, "");
  440. }
  441. void
  442. handle_get_read_memory(WASMGDBServer *server, char *payload)
  443. {
  444. uint64 maddr, mlen;
  445. bool ret;
  446. os_mutex_lock(&tmpbuf_lock);
  447. snprintf(tmpbuf, sizeof(tmpbuf), "%s", "");
  448. if (sscanf(payload, "%" SCNx64 ",%" SCNx64, &maddr, &mlen) == 2) {
  449. char *buff;
  450. if (mlen * 2 > MAX_PACKET_SIZE) {
  451. LOG_ERROR("Buffer overflow!");
  452. mlen = MAX_PACKET_SIZE / 2;
  453. }
  454. buff = wasm_runtime_malloc(mlen);
  455. if (buff) {
  456. ret = wasm_debug_instance_get_mem(
  457. (WASMDebugInstance *)server->thread->debug_instance, maddr,
  458. buff, &mlen);
  459. if (ret) {
  460. mem2hex(buff, tmpbuf, mlen);
  461. }
  462. wasm_runtime_free(buff);
  463. }
  464. }
  465. write_packet(server, tmpbuf);
  466. os_mutex_unlock(&tmpbuf_lock);
  467. }
  468. void
  469. handle_get_write_memory(WASMGDBServer *server, char *payload)
  470. {
  471. size_t hex_len;
  472. int32 offset, act_len;
  473. uint64 maddr, mlen;
  474. char *buff;
  475. bool ret;
  476. os_mutex_lock(&tmpbuf_lock);
  477. snprintf(tmpbuf, sizeof(tmpbuf), "%s", "");
  478. if (sscanf(payload, "%" SCNx64 ",%" SCNx64 ":%n", &maddr, &mlen, &offset)
  479. == 2) {
  480. payload += offset;
  481. hex_len = strlen(payload);
  482. act_len = hex_len / 2 < mlen ? hex_len / 2 : mlen;
  483. buff = wasm_runtime_malloc(act_len);
  484. if (buff) {
  485. hex2mem(payload, buff, act_len);
  486. ret = wasm_debug_instance_set_mem(
  487. (WASMDebugInstance *)server->thread->debug_instance, maddr,
  488. buff, &mlen);
  489. if (ret) {
  490. snprintf(tmpbuf, sizeof(tmpbuf), "%s", "OK");
  491. }
  492. wasm_runtime_free(buff);
  493. }
  494. }
  495. write_packet(server, tmpbuf);
  496. os_mutex_unlock(&tmpbuf_lock);
  497. }
  498. void
  499. handle_add_break(WASMGDBServer *server, char *payload)
  500. {
  501. size_t type, length;
  502. uint64 addr;
  503. if (sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length) == 3) {
  504. if (type == eBreakpointSoftware) {
  505. bool ret = wasm_debug_instance_add_breakpoint(
  506. (WASMDebugInstance *)server->thread->debug_instance, addr,
  507. length);
  508. if (ret)
  509. write_packet(server, "OK");
  510. else
  511. write_packet(server, "E01");
  512. return;
  513. }
  514. }
  515. write_packet(server, "");
  516. }
  517. void
  518. handle_remove_break(WASMGDBServer *server, char *payload)
  519. {
  520. size_t type, length;
  521. uint64 addr;
  522. if (sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length) == 3) {
  523. if (type == eBreakpointSoftware) {
  524. bool ret = wasm_debug_instance_remove_breakpoint(
  525. (WASMDebugInstance *)server->thread->debug_instance, addr,
  526. length);
  527. if (ret)
  528. write_packet(server, "OK");
  529. else
  530. write_packet(server, "E01");
  531. return;
  532. }
  533. }
  534. write_packet(server, "");
  535. }
  536. void
  537. handle_continue_request(WASMGDBServer *server, char *payload)
  538. {
  539. korp_tid tid;
  540. uint32 status;
  541. wasm_debug_instance_continue(
  542. (WASMDebugInstance *)server->thread->debug_instance);
  543. tid = wasm_debug_instance_get_tid(
  544. (WASMDebugInstance *)server->thread->debug_instance);
  545. tid = wasm_debug_instance_wait_thread(
  546. (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
  547. send_thread_stop_status(server, status, tid);
  548. }
  549. void
  550. handle_kill_request(WASMGDBServer *server, char *payload)
  551. {
  552. korp_tid tid;
  553. uint32 status;
  554. wasm_debug_instance_kill(
  555. (WASMDebugInstance *)server->thread->debug_instance);
  556. tid = wasm_debug_instance_get_tid(
  557. (WASMDebugInstance *)server->thread->debug_instance);
  558. tid = wasm_debug_instance_wait_thread(
  559. (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
  560. send_thread_stop_status(server, status, tid);
  561. }
  562. static void
  563. handle_malloc(WASMGDBServer *server, char *payload)
  564. {
  565. char *args;
  566. uint64 addr, size;
  567. int32 map_port = MMAP_PROT_NONE;
  568. args = strstr(payload, ",");
  569. if (args) {
  570. *args++ = '\0';
  571. }
  572. else {
  573. LOG_ERROR("Payload parse error during handle malloc");
  574. return;
  575. }
  576. os_mutex_lock(&tmpbuf_lock);
  577. snprintf(tmpbuf, sizeof(tmpbuf), "%s", "E03");
  578. size = strtoll(payload, NULL, 16);
  579. if (size > 0) {
  580. while (*args) {
  581. if (*args == 'r') {
  582. map_port |= MMAP_PROT_READ;
  583. }
  584. if (*args == 'w') {
  585. map_port |= MMAP_PROT_WRITE;
  586. }
  587. if (*args == 'x') {
  588. map_port |= MMAP_PROT_EXEC;
  589. }
  590. args++;
  591. }
  592. addr = wasm_debug_instance_mmap(
  593. (WASMDebugInstance *)server->thread->debug_instance, size,
  594. map_port);
  595. if (addr) {
  596. snprintf(tmpbuf, sizeof(tmpbuf), "%" PRIx64, addr);
  597. }
  598. }
  599. write_packet(server, tmpbuf);
  600. os_mutex_unlock(&tmpbuf_lock);
  601. }
  602. static void
  603. handle_free(WASMGDBServer *server, char *payload)
  604. {
  605. uint64 addr;
  606. bool ret;
  607. os_mutex_lock(&tmpbuf_lock);
  608. snprintf(tmpbuf, sizeof(tmpbuf), "%s", "E03");
  609. addr = strtoll(payload, NULL, 16);
  610. ret = wasm_debug_instance_ummap(
  611. (WASMDebugInstance *)server->thread->debug_instance, addr);
  612. if (ret) {
  613. snprintf(tmpbuf, sizeof(tmpbuf), "%s", "OK");
  614. }
  615. write_packet(server, tmpbuf);
  616. os_mutex_unlock(&tmpbuf_lock);
  617. }
  618. void
  619. handle____request(WASMGDBServer *server, char *payload)
  620. {
  621. char *args;
  622. if (payload[0] == 'M') {
  623. args = payload + 1;
  624. handle_malloc(server, args);
  625. }
  626. if (payload[0] == 'm') {
  627. args = payload + 1;
  628. handle_free(server, args);
  629. }
  630. }