packets.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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 "packets.h"
  7. #include "gdbserver.h"
  8. void
  9. pktbuf_insert(WASMGDBServer *gdbserver, const uint8 *buf, ssize_t len)
  10. {
  11. WasmDebugPacket *pkt = &gdbserver->pkt;
  12. if ((unsigned long)(pkt->size + len) >= sizeof(pkt->buf)) {
  13. LOG_ERROR("Packet buffer overflow");
  14. exit(-2);
  15. }
  16. memcpy(pkt->buf + pkt->size, buf, len);
  17. pkt->size += len;
  18. }
  19. void
  20. pktbuf_erase_head(WASMGDBServer *gdbserver, ssize_t index)
  21. {
  22. WasmDebugPacket *pkt = &gdbserver->pkt;
  23. memmove(pkt->buf, pkt->buf + index, pkt->size - index);
  24. pkt->size -= index;
  25. }
  26. void
  27. inbuf_erase_head(WASMGDBServer *gdbserver, ssize_t index)
  28. {
  29. pktbuf_erase_head(gdbserver, index);
  30. }
  31. void
  32. pktbuf_clear(WASMGDBServer *gdbserver)
  33. {
  34. WasmDebugPacket *pkt = &gdbserver->pkt;
  35. pkt->size = 0;
  36. }
  37. int32
  38. read_data_once(WASMGDBServer *gdbserver)
  39. {
  40. ssize_t nread;
  41. uint8 buf[4096];
  42. nread = os_socket_recv(gdbserver->socket_fd, buf, sizeof(buf));
  43. if (nread <= 0) {
  44. LOG_ERROR("Connection closed");
  45. return -1;
  46. }
  47. pktbuf_insert(gdbserver, buf, nread);
  48. return nread;
  49. }
  50. void
  51. write_data_raw(WASMGDBServer *gdbserver, const uint8 *data, ssize_t len)
  52. {
  53. ssize_t nwritten;
  54. nwritten = os_socket_send(gdbserver->socket_fd, data, len);
  55. if (nwritten < 0) {
  56. LOG_ERROR("Write error\n");
  57. exit(-2);
  58. }
  59. }
  60. void
  61. write_hex(WASMGDBServer *gdbserver, unsigned long hex)
  62. {
  63. char buf[32];
  64. size_t len;
  65. len = snprintf(buf, sizeof(buf) - 1, "%02lx", hex);
  66. write_data_raw(gdbserver, (uint8 *)buf, len);
  67. }
  68. void
  69. write_packet_bytes(WASMGDBServer *gdbserver, const uint8 *data,
  70. size_t num_bytes)
  71. {
  72. uint8 checksum;
  73. size_t i;
  74. write_data_raw(gdbserver, (uint8 *)"$", 1);
  75. for (i = 0, checksum = 0; i < num_bytes; ++i)
  76. checksum += data[i];
  77. write_data_raw(gdbserver, (uint8 *)data, num_bytes);
  78. write_data_raw(gdbserver, (uint8 *)"#", 1);
  79. write_hex(gdbserver, checksum);
  80. }
  81. void
  82. write_packet(WASMGDBServer *gdbserver, const char *data)
  83. {
  84. LOG_VERBOSE("send replay:%s", data);
  85. write_packet_bytes(gdbserver, (const uint8 *)data, strlen(data));
  86. }
  87. void
  88. write_binary_packet(WASMGDBServer *gdbserver, const char *pfx,
  89. const uint8 *data, ssize_t num_bytes)
  90. {
  91. uint8 *buf;
  92. ssize_t pfx_num_chars = strlen(pfx);
  93. ssize_t buf_num_bytes = 0, total_size;
  94. int32 i;
  95. total_size = 2 * num_bytes + pfx_num_chars;
  96. buf = wasm_runtime_malloc(total_size);
  97. if (!buf) {
  98. LOG_ERROR("Failed to allocate memory for binary packet");
  99. return;
  100. }
  101. memset(buf, 0, total_size);
  102. memcpy(buf, pfx, pfx_num_chars);
  103. buf_num_bytes += pfx_num_chars;
  104. for (i = 0; i < num_bytes; ++i) {
  105. uint8 b = data[i];
  106. switch (b) {
  107. case '#':
  108. case '$':
  109. case '}':
  110. case '*':
  111. buf[buf_num_bytes++] = '}';
  112. buf[buf_num_bytes++] = b ^ 0x20;
  113. break;
  114. default:
  115. buf[buf_num_bytes++] = b;
  116. break;
  117. }
  118. }
  119. write_packet_bytes(gdbserver, buf, buf_num_bytes);
  120. wasm_runtime_free(buf);
  121. }
  122. bool
  123. skip_to_packet_start(WASMGDBServer *gdbserver)
  124. {
  125. ssize_t start_index = -1, i;
  126. for (i = 0; i < (ssize_t)gdbserver->pkt.size; ++i) {
  127. if (gdbserver->pkt.buf[i] == '$') {
  128. start_index = i;
  129. break;
  130. }
  131. }
  132. if (start_index < 0) {
  133. pktbuf_clear(gdbserver);
  134. return false;
  135. }
  136. pktbuf_erase_head(gdbserver, start_index);
  137. bh_assert(1 <= gdbserver->pkt.size);
  138. bh_assert('$' == gdbserver->pkt.buf[0]);
  139. return true;
  140. }
  141. bool
  142. read_packet(WASMGDBServer *gdbserver)
  143. {
  144. while (!skip_to_packet_start(gdbserver)) {
  145. if (read_data_once(gdbserver) < 0)
  146. return false;
  147. }
  148. if (!gdbserver->noack)
  149. write_data_raw(gdbserver, (uint8 *)"+", 1);
  150. return true;
  151. }