mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-30 21:02:27 +00:00 
			
		
		
		
	 ccb2de35d7
			
		
	
	
		ccb2de35d7
		
			
		
	
	
	
	
		
			
			- use platform independent data types in debug-engine library - add os_socket APIs and provide windows and posix implementation - avoid using platform related header files in non-platform layer - use format specifiers macros for sprintf and sscanf - change thread handle type from uint64 to korp_tid - add lock when sending socket packet to avoid thread racing
		
			
				
	
	
		
			179 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2021 Ant Group.  All rights reserved.
 | |
|  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
|  */
 | |
| 
 | |
| #include "bh_platform.h"
 | |
| #include "packets.h"
 | |
| #include "gdbserver.h"
 | |
| 
 | |
| void
 | |
| pktbuf_insert(WASMGDBServer *gdbserver, const uint8 *buf, ssize_t len)
 | |
| {
 | |
|     WasmDebugPacket *pkt = &gdbserver->pkt;
 | |
| 
 | |
|     if ((unsigned long)(pkt->size + len) >= sizeof(pkt->buf)) {
 | |
|         LOG_ERROR("Packet buffer overflow");
 | |
|         exit(-2);
 | |
|     }
 | |
| 
 | |
|     memcpy(pkt->buf + pkt->size, buf, len);
 | |
|     pkt->size += len;
 | |
| }
 | |
| 
 | |
| void
 | |
| pktbuf_erase_head(WASMGDBServer *gdbserver, ssize_t index)
 | |
| {
 | |
|     WasmDebugPacket *pkt = &gdbserver->pkt;
 | |
|     memmove(pkt->buf, pkt->buf + index, pkt->size - index);
 | |
|     pkt->size -= index;
 | |
| }
 | |
| 
 | |
| void
 | |
| inbuf_erase_head(WASMGDBServer *gdbserver, ssize_t index)
 | |
| {
 | |
|     pktbuf_erase_head(gdbserver, index);
 | |
| }
 | |
| 
 | |
| void
 | |
| pktbuf_clear(WASMGDBServer *gdbserver)
 | |
| {
 | |
|     WasmDebugPacket *pkt = &gdbserver->pkt;
 | |
|     pkt->size = 0;
 | |
| }
 | |
| 
 | |
| int32
 | |
| read_data_once(WASMGDBServer *gdbserver)
 | |
| {
 | |
|     ssize_t nread;
 | |
|     uint8 buf[4096];
 | |
| 
 | |
|     nread = os_socket_recv(gdbserver->socket_fd, buf, sizeof(buf));
 | |
|     if (nread <= 0) {
 | |
|         LOG_ERROR("Connection closed");
 | |
|         return -1;
 | |
|     }
 | |
|     pktbuf_insert(gdbserver, buf, nread);
 | |
|     return nread;
 | |
| }
 | |
| 
 | |
| void
 | |
| write_data_raw(WASMGDBServer *gdbserver, const uint8 *data, ssize_t len)
 | |
| {
 | |
|     ssize_t nwritten;
 | |
| 
 | |
|     nwritten = os_socket_send(gdbserver->socket_fd, data, len);
 | |
|     if (nwritten < 0) {
 | |
|         LOG_ERROR("Write error\n");
 | |
|         exit(-2);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| write_hex(WASMGDBServer *gdbserver, unsigned long hex)
 | |
| {
 | |
|     char buf[32];
 | |
|     size_t len;
 | |
| 
 | |
|     len = snprintf(buf, sizeof(buf) - 1, "%02lx", hex);
 | |
|     write_data_raw(gdbserver, (uint8 *)buf, len);
 | |
| }
 | |
| 
 | |
| void
 | |
| write_packet_bytes(WASMGDBServer *gdbserver, const uint8 *data,
 | |
|                    size_t num_bytes)
 | |
| {
 | |
|     uint8 checksum;
 | |
|     size_t i;
 | |
| 
 | |
|     write_data_raw(gdbserver, (uint8 *)"$", 1);
 | |
|     for (i = 0, checksum = 0; i < num_bytes; ++i)
 | |
|         checksum += data[i];
 | |
|     write_data_raw(gdbserver, (uint8 *)data, num_bytes);
 | |
|     write_data_raw(gdbserver, (uint8 *)"#", 1);
 | |
|     write_hex(gdbserver, checksum);
 | |
| }
 | |
| 
 | |
| void
 | |
| write_packet(WASMGDBServer *gdbserver, const char *data)
 | |
| {
 | |
|     LOG_VERBOSE("send replay:%s", data);
 | |
|     write_packet_bytes(gdbserver, (const uint8 *)data, strlen(data));
 | |
| }
 | |
| 
 | |
| void
 | |
| write_binary_packet(WASMGDBServer *gdbserver, const char *pfx,
 | |
|                     const uint8 *data, ssize_t num_bytes)
 | |
| {
 | |
|     uint8 *buf;
 | |
|     ssize_t pfx_num_chars = strlen(pfx);
 | |
|     ssize_t buf_num_bytes = 0, total_size;
 | |
|     int32 i;
 | |
| 
 | |
|     total_size = 2 * num_bytes + pfx_num_chars;
 | |
|     buf = wasm_runtime_malloc(total_size);
 | |
|     if (!buf) {
 | |
|         LOG_ERROR("Failed to allocate memory for binary packet");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     memset(buf, 0, total_size);
 | |
|     memcpy(buf, pfx, pfx_num_chars);
 | |
|     buf_num_bytes += pfx_num_chars;
 | |
| 
 | |
|     for (i = 0; i < num_bytes; ++i) {
 | |
|         uint8 b = data[i];
 | |
|         switch (b) {
 | |
|             case '#':
 | |
|             case '$':
 | |
|             case '}':
 | |
|             case '*':
 | |
|                 buf[buf_num_bytes++] = '}';
 | |
|                 buf[buf_num_bytes++] = b ^ 0x20;
 | |
|                 break;
 | |
|             default:
 | |
|                 buf[buf_num_bytes++] = b;
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
|     write_packet_bytes(gdbserver, buf, buf_num_bytes);
 | |
|     wasm_runtime_free(buf);
 | |
| }
 | |
| 
 | |
| bool
 | |
| skip_to_packet_start(WASMGDBServer *gdbserver)
 | |
| {
 | |
|     ssize_t start_index = -1, i;
 | |
| 
 | |
|     for (i = 0; i < (ssize_t)gdbserver->pkt.size; ++i) {
 | |
|         if (gdbserver->pkt.buf[i] == '$') {
 | |
|             start_index = i;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (start_index < 0) {
 | |
|         pktbuf_clear(gdbserver);
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     pktbuf_erase_head(gdbserver, start_index);
 | |
| 
 | |
|     bh_assert(1 <= gdbserver->pkt.size);
 | |
|     bh_assert('$' == gdbserver->pkt.buf[0]);
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool
 | |
| read_packet(WASMGDBServer *gdbserver)
 | |
| {
 | |
|     while (!skip_to_packet_start(gdbserver)) {
 | |
|         if (read_data_once(gdbserver) < 0)
 | |
|             return false;
 | |
|     }
 | |
|     if (!gdbserver->noack)
 | |
|         write_data_raw(gdbserver, (uint8 *)"+", 1);
 | |
|     return true;
 | |
| }
 |