2021-09-29 05:36:46 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2021 Ant Group. All rights reserved.
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
*/
|
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
#include "bh_platform.h"
|
2021-09-29 05:36:46 +00:00
|
|
|
#include "gdbserver.h"
|
|
|
|
#include "handler.h"
|
|
|
|
#include "packets.h"
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
typedef void (*PacketHandler)(WASMGDBServer *server, char *payload);
|
|
|
|
|
|
|
|
struct packet_handler_elem {
|
|
|
|
char request;
|
|
|
|
PacketHandler handler;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define DEL_HANDLER(r, h) [r] = { .request = r, .handler = h }
|
|
|
|
|
|
|
|
static struct packet_handler_elem packet_handler_table[255] = {
|
|
|
|
DEL_HANDLER('Q', handle_generay_set),
|
|
|
|
DEL_HANDLER('q', handle_generay_query),
|
|
|
|
DEL_HANDLER('v', handle_v_packet),
|
|
|
|
DEL_HANDLER('?', handle_threadstop_request),
|
|
|
|
DEL_HANDLER('H', handle_set_current_thread),
|
|
|
|
DEL_HANDLER('p', handle_get_register),
|
|
|
|
DEL_HANDLER('j', handle_get_json_request),
|
|
|
|
DEL_HANDLER('m', handle_get_read_memory),
|
|
|
|
DEL_HANDLER('M', handle_get_write_memory),
|
|
|
|
DEL_HANDLER('x', handle_get_read_binary_memory),
|
|
|
|
DEL_HANDLER('Z', handle_add_break),
|
|
|
|
DEL_HANDLER('z', handle_remove_break),
|
|
|
|
DEL_HANDLER('c', handle_continue_request),
|
|
|
|
DEL_HANDLER('k', handle_kill_request),
|
|
|
|
DEL_HANDLER('_', handle____request),
|
|
|
|
};
|
|
|
|
|
|
|
|
WASMGDBServer *
|
2021-12-22 11:52:07 +00:00
|
|
|
wasm_create_gdbserver(const char *host, int32 *port)
|
2021-09-29 05:36:46 +00:00
|
|
|
{
|
2021-12-22 11:52:07 +00:00
|
|
|
bh_socket_t listen_fd = (bh_socket_t)-1;
|
2021-09-29 05:36:46 +00:00
|
|
|
WASMGDBServer *server;
|
|
|
|
|
2021-12-06 02:25:38 +00:00
|
|
|
bh_assert(port);
|
|
|
|
|
2021-09-29 05:36:46 +00:00
|
|
|
if (!(server = wasm_runtime_malloc(sizeof(WASMGDBServer)))) {
|
|
|
|
LOG_ERROR("wasm gdb server error: failed to allocate memory");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-10-09 07:56:58 +00:00
|
|
|
memset(server, 0, sizeof(WASMGDBServer));
|
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
if (0 != os_socket_create(&listen_fd, 1)) {
|
|
|
|
LOG_ERROR("wasm gdb server error: create socket failed");
|
2021-09-29 05:36:46 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
if (0 != os_socket_bind(listen_fd, host, port)) {
|
|
|
|
LOG_ERROR("wasm gdb server error: socket bind failed");
|
2021-10-30 07:44:41 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
2021-12-06 02:25:38 +00:00
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
LOG_WARNING("Debug server listening on %s:%" PRIu32 "\n", host, *port);
|
2021-12-06 02:25:38 +00:00
|
|
|
server->listen_fd = listen_fd;
|
|
|
|
|
|
|
|
return server;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
if (listen_fd >= 0) {
|
2021-12-22 11:52:07 +00:00
|
|
|
os_socket_shutdown(listen_fd);
|
|
|
|
os_socket_close(listen_fd);
|
2021-12-06 02:25:38 +00:00
|
|
|
}
|
|
|
|
if (server)
|
|
|
|
wasm_runtime_free(server);
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-10-30 07:44:41 +00:00
|
|
|
|
2021-12-06 02:25:38 +00:00
|
|
|
bool
|
|
|
|
wasm_gdbserver_listen(WASMGDBServer *server)
|
|
|
|
{
|
2021-12-22 11:52:07 +00:00
|
|
|
bh_socket_t sockt_fd = (bh_socket_t)-1;
|
|
|
|
int32 ret;
|
2021-10-30 07:44:41 +00:00
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
ret = os_socket_listen(server->listen_fd, 1);
|
|
|
|
if (ret != 0) {
|
|
|
|
LOG_ERROR("wasm gdb server error: socket listen failed");
|
2021-09-29 05:36:46 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
os_socket_accept(server->listen_fd, &sockt_fd, NULL, NULL);
|
2021-09-29 05:36:46 +00:00
|
|
|
if (sockt_fd < 0) {
|
2021-12-22 11:52:07 +00:00
|
|
|
LOG_ERROR("wasm gdb server error: socket accept failed");
|
2021-09-29 05:36:46 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
2021-12-06 02:25:38 +00:00
|
|
|
|
2021-09-29 05:36:46 +00:00
|
|
|
LOG_VERBOSE("accept gdb client");
|
|
|
|
server->socket_fd = sockt_fd;
|
|
|
|
server->noack = false;
|
2021-12-06 02:25:38 +00:00
|
|
|
return true;
|
2021-09-29 05:36:46 +00:00
|
|
|
|
|
|
|
fail:
|
2021-12-22 11:52:07 +00:00
|
|
|
os_socket_shutdown(server->listen_fd);
|
|
|
|
os_socket_close(server->listen_fd);
|
2021-12-06 02:25:38 +00:00
|
|
|
return false;
|
2021-09-29 05:36:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
wasm_close_gdbserver(WASMGDBServer *server)
|
|
|
|
{
|
|
|
|
if (server->socket_fd > 0) {
|
2021-12-22 11:52:07 +00:00
|
|
|
os_socket_shutdown(server->socket_fd);
|
|
|
|
os_socket_close(server->socket_fd);
|
2021-09-29 05:36:46 +00:00
|
|
|
}
|
|
|
|
if (server->listen_fd > 0) {
|
2021-12-22 11:52:07 +00:00
|
|
|
os_socket_shutdown(server->listen_fd);
|
|
|
|
os_socket_close(server->listen_fd);
|
2021-09-29 05:36:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
handler_packet(WASMGDBServer *server, char request, char *payload)
|
|
|
|
{
|
|
|
|
if (packet_handler_table[(int)request].handler != NULL)
|
|
|
|
packet_handler_table[(int)request].handler(server, payload);
|
|
|
|
}
|
|
|
|
|
2021-10-09 07:56:58 +00:00
|
|
|
/**
|
|
|
|
* The packet layout is:
|
|
|
|
* '$' + payload + '#' + checksum(2bytes)
|
|
|
|
* ^
|
|
|
|
* packetend_ptr
|
|
|
|
*/
|
2021-09-29 05:36:46 +00:00
|
|
|
static void
|
|
|
|
process_packet(WASMGDBServer *server)
|
|
|
|
{
|
2021-12-22 11:52:07 +00:00
|
|
|
uint8 *inbuf = server->pkt.buf;
|
|
|
|
int32 inbuf_size = server->pkt.size;
|
|
|
|
uint8 *packetend_ptr = (uint8 *)memchr(inbuf, '#', inbuf_size);
|
|
|
|
int32 packet_size = (int32)(uintptr_t)(packetend_ptr - inbuf);
|
2021-09-29 05:36:46 +00:00
|
|
|
char request = inbuf[1];
|
2021-10-09 07:56:58 +00:00
|
|
|
char *payload = NULL;
|
2021-12-22 11:52:07 +00:00
|
|
|
uint8 checksum = 0;
|
2021-10-09 07:56:58 +00:00
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
if (packet_size == 1) {
|
2021-10-09 07:56:58 +00:00
|
|
|
LOG_VERBOSE("receive empty request, ignore it\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bh_assert('$' == inbuf[0]);
|
2021-12-22 11:52:07 +00:00
|
|
|
inbuf[packet_size] = '\0';
|
2021-09-29 05:36:46 +00:00
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
for (int i = 1; i < packet_size; i++)
|
2021-09-29 05:36:46 +00:00
|
|
|
checksum += inbuf[i];
|
2021-12-22 11:52:07 +00:00
|
|
|
bh_assert(
|
|
|
|
checksum
|
|
|
|
== (hex(inbuf[packet_size + 1]) << 4 | hex(inbuf[packet_size + 2])));
|
2021-09-29 05:36:46 +00:00
|
|
|
|
2021-10-09 07:56:58 +00:00
|
|
|
payload = (char *)&inbuf[2];
|
|
|
|
|
2021-09-29 05:36:46 +00:00
|
|
|
LOG_VERBOSE("receive request:%c %s\n", request, payload);
|
|
|
|
handler_packet(server, request, payload);
|
2021-10-09 07:56:58 +00:00
|
|
|
|
2021-12-22 11:52:07 +00:00
|
|
|
inbuf_erase_head(server, packet_size + 3);
|
2021-09-29 05:36:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
wasm_gdbserver_handle_packet(WASMGDBServer *server)
|
|
|
|
{
|
|
|
|
bool ret;
|
|
|
|
ret = read_packet(server);
|
|
|
|
if (ret)
|
|
|
|
process_packet(server);
|
|
|
|
return ret;
|
|
|
|
}
|