aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdbstub/gdbstub.c276
-rw-r--r--gdbstub/internals.h25
2 files changed, 165 insertions, 136 deletions
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index ba46ed73b3..f59ab12cc3 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -85,12 +85,13 @@ static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
}
-/* Return the GDB index for a given vCPU state.
+/*
+ * Return the GDB index for a given vCPU state.
*
* For user mode this is simply the thread id. In system mode GDB
* numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
*/
-static inline int cpu_gdb_index(CPUState *cpu)
+int gdb_get_cpu_index(CPUState *cpu)
{
#if defined(CONFIG_USER_ONLY)
TaskState *ts = (TaskState *) cpu->opaque;
@@ -342,7 +343,7 @@ static GDBSystemState gdbserver_system_state;
static GDBState gdbserver_state;
-static void init_gdbserver_state(void)
+void gdb_init_gdbserver_state(void)
{
g_assert(!gdbserver_state.init);
memset(&gdbserver_state, 0, sizeof(GDBState));
@@ -524,7 +525,7 @@ static int gdb_continue_partial(char *newstates)
return res;
}
-static void put_buffer(const uint8_t *buf, int len)
+void gdb_put_buffer(const uint8_t *buf, int len)
{
#ifdef CONFIG_USER_ONLY
int ret;
@@ -547,7 +548,7 @@ static void put_buffer(const uint8_t *buf, int len)
}
/* writes 2*len+1 bytes in buf */
-static void memtohex(GString *buf, const uint8_t *mem, int len)
+void gdb_memtohex(GString *buf, const uint8_t *mem, int len)
{
int i, c;
for(i = 0; i < len; i++) {
@@ -558,7 +559,7 @@ static void memtohex(GString *buf, const uint8_t *mem, int len)
g_string_append_c(buf, '\0');
}
-static void hextomem(GByteArray *mem, const char *buf, int len)
+void gdb_hextomem(GByteArray *mem, const char *buf, int len)
{
int i;
@@ -603,7 +604,7 @@ static void hexdump(const char *buf, int len,
}
/* return -1 if error, 0 if OK */
-static int put_packet_binary(const char *buf, int len, bool dump)
+int gdb_put_packet_binary(const char *buf, int len, bool dump)
{
int csum, i;
uint8_t footer[3];
@@ -627,7 +628,7 @@ static int put_packet_binary(const char *buf, int len, bool dump)
footer[2] = tohex((csum) & 0xf);
g_byte_array_append(gdbserver_state.last_packet, footer, 3);
- put_buffer(gdbserver_state.last_packet->data,
+ gdb_put_buffer(gdbserver_state.last_packet->data,
gdbserver_state.last_packet->len);
#ifdef CONFIG_USER_ONLY
@@ -644,20 +645,20 @@ static int put_packet_binary(const char *buf, int len, bool dump)
}
/* return -1 if error, 0 if OK */
-static int put_packet(const char *buf)
+int gdb_put_packet(const char *buf)
{
trace_gdbstub_io_reply(buf);
- return put_packet_binary(buf, strlen(buf), false);
+ return gdb_put_packet_binary(buf, strlen(buf), false);
}
-static void put_strbuf(void)
+void gdb_put_strbuf(void)
{
- put_packet(gdbserver_state.str_buf->str);
+ gdb_put_packet(gdbserver_state.str_buf->str);
}
/* Encode data using the encoding for 'x' packets. */
-static void memtox(GString *buf, const char *mem, int len)
+void gdb_memtox(GString *buf, const char *mem, int len)
{
char c;
@@ -714,7 +715,7 @@ static CPUState *find_cpu(uint32_t thread_id)
CPUState *cpu;
CPU_FOREACH(cpu) {
- if (cpu_gdb_index(cpu) == thread_id) {
+ if (gdb_get_cpu_index(cpu) == thread_id) {
return cpu;
}
}
@@ -768,7 +769,7 @@ static CPUState *gdb_next_attached_cpu(CPUState *cpu)
}
/* Return the first attached cpu */
-static CPUState *gdb_first_attached_cpu(void)
+CPUState *gdb_first_attached_cpu(void)
{
CPUState *cpu = first_cpu;
GDBProcess *process = gdb_get_cpu_process(cpu);
@@ -982,13 +983,13 @@ static void gdb_set_cpu_pc(target_ulong pc)
cpu_set_pc(cpu, pc);
}
-static void gdb_append_thread_id(CPUState *cpu, GString *buf)
+void gdb_append_thread_id(CPUState *cpu, GString *buf)
{
if (gdbserver_state.multiprocess) {
g_string_append_printf(buf, "p%02x.%02x",
- gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
+ gdb_get_cpu_pid(cpu), gdb_get_cpu_index(cpu));
} else {
- g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
+ g_string_append_printf(buf, "%02x", gdb_get_cpu_index(cpu));
}
}
@@ -1359,7 +1360,7 @@ static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
/* In case there was an error during the command parsing we must
* send a NULL packet to indicate the command is not supported */
if (process_string_cmd(NULL, data, cmd, 1)) {
- put_packet("");
+ gdb_put_packet("");
}
}
@@ -1370,7 +1371,7 @@ static void handle_detach(GArray *params, void *user_ctx)
if (gdbserver_state.multiprocess) {
if (!params->len) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -1394,7 +1395,7 @@ static void handle_detach(GArray *params, void *user_ctx)
gdb_syscall_mode = GDB_SYS_DISABLED;
gdb_continue();
}
- put_packet("OK");
+ gdb_put_packet("OK");
}
static void handle_thread_alive(GArray *params, void *user_ctx)
@@ -1402,23 +1403,23 @@ static void handle_thread_alive(GArray *params, void *user_ctx)
CPUState *cpu;
if (!params->len) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
get_param(params, 0)->thread_id.tid);
if (!cpu) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
- put_packet("OK");
+ gdb_put_packet("OK");
}
static void handle_continue(GArray *params, void *user_ctx)
@@ -1455,24 +1456,24 @@ static void handle_set_thread(GArray *params, void *user_ctx)
CPUState *cpu;
if (params->len != 2) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
- put_packet("OK");
+ gdb_put_packet("OK");
return;
}
cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
get_param(params, 1)->thread_id.tid);
if (!cpu) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -1483,14 +1484,14 @@ static void handle_set_thread(GArray *params, void *user_ctx)
switch (get_param(params, 0)->opcode) {
case 'c':
gdbserver_state.c_cpu = cpu;
- put_packet("OK");
+ gdb_put_packet("OK");
break;
case 'g':
gdbserver_state.g_cpu = cpu;
- put_packet("OK");
+ gdb_put_packet("OK");
break;
default:
- put_packet("E22");
+ gdb_put_packet("E22");
break;
}
}
@@ -1500,7 +1501,7 @@ static void handle_insert_bp(GArray *params, void *user_ctx)
int res;
if (params->len != 3) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -1509,14 +1510,14 @@ static void handle_insert_bp(GArray *params, void *user_ctx)
get_param(params, 1)->val_ull,
get_param(params, 2)->val_ull);
if (res >= 0) {
- put_packet("OK");
+ gdb_put_packet("OK");
return;
} else if (res == -ENOSYS) {
- put_packet("");
+ gdb_put_packet("");
return;
}
- put_packet("E22");
+ gdb_put_packet("E22");
}
static void handle_remove_bp(GArray *params, void *user_ctx)
@@ -1524,7 +1525,7 @@ static void handle_remove_bp(GArray *params, void *user_ctx)
int res;
if (params->len != 3) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -1533,14 +1534,14 @@ static void handle_remove_bp(GArray *params, void *user_ctx)
get_param(params, 1)->val_ull,
get_param(params, 2)->val_ull);
if (res >= 0) {
- put_packet("OK");
+ gdb_put_packet("OK");
return;
} else if (res == -ENOSYS) {
- put_packet("");
+ gdb_put_packet("");
return;
}
- put_packet("E22");
+ gdb_put_packet("E22");
}
/*
@@ -1559,20 +1560,20 @@ static void handle_set_reg(GArray *params, void *user_ctx)
int reg_size;
if (!gdb_has_xml) {
- put_packet("");
+ gdb_put_packet("");
return;
}
if (params->len != 2) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
reg_size = strlen(get_param(params, 1)->data) / 2;
- hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
+ gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
get_param(params, 0)->val_ull);
- put_packet("OK");
+ gdb_put_packet("OK");
}
static void handle_get_reg(GArray *params, void *user_ctx)
@@ -1580,12 +1581,12 @@ static void handle_get_reg(GArray *params, void *user_ctx)
int reg_size;
if (!gdb_has_xml) {
- put_packet("");
+ gdb_put_packet("");
return;
}
if (!params->len) {
- put_packet("E14");
+ gdb_put_packet("E14");
return;
}
@@ -1593,53 +1594,54 @@ static void handle_get_reg(GArray *params, void *user_ctx)
gdbserver_state.mem_buf,
get_param(params, 0)->val_ull);
if (!reg_size) {
- put_packet("E14");
+ gdb_put_packet("E14");
return;
} else {
g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
}
- memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
- put_strbuf();
+ gdb_memtohex(gdbserver_state.str_buf,
+ gdbserver_state.mem_buf->data, reg_size);
+ gdb_put_strbuf();
}
static void handle_write_mem(GArray *params, void *user_ctx)
{
if (params->len != 3) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
- /* hextomem() reads 2*len bytes */
+ /* gdb_hextomem() reads 2*len bytes */
if (get_param(params, 1)->val_ull >
strlen(get_param(params, 2)->data) / 2) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
- hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
+ gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
get_param(params, 1)->val_ull);
if (target_memory_rw_debug(gdbserver_state.g_cpu,
get_param(params, 0)->val_ull,
gdbserver_state.mem_buf->data,
gdbserver_state.mem_buf->len, true)) {
- put_packet("E14");
+ gdb_put_packet("E14");
return;
}
- put_packet("OK");
+ gdb_put_packet("OK");
}
static void handle_read_mem(GArray *params, void *user_ctx)
{
if (params->len != 2) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
- /* memtohex() doubles the required space */
+ /* gdb_memtohex() doubles the required space */
if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -1650,13 +1652,13 @@ static void handle_read_mem(GArray *params, void *user_ctx)
get_param(params, 0)->val_ull,
gdbserver_state.mem_buf->data,
gdbserver_state.mem_buf->len, false)) {
- put_packet("E14");
+ gdb_put_packet("E14");
return;
}
- memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
+ gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
gdbserver_state.mem_buf->len);
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_write_all_regs(GArray *params, void *user_ctx)
@@ -1671,7 +1673,7 @@ static void handle_write_all_regs(GArray *params, void *user_ctx)
cpu_synchronize_state(gdbserver_state.g_cpu);
len = strlen(get_param(params, 0)->data) / 2;
- hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
+ gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
registers = gdbserver_state.mem_buf->data;
for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
addr++) {
@@ -1679,7 +1681,7 @@ static void handle_write_all_regs(GArray *params, void *user_ctx)
len -= reg_size;
registers += reg_size;
}
- put_packet("OK");
+ gdb_put_packet("OK");
}
static void handle_read_all_regs(GArray *params, void *user_ctx)
@@ -1696,8 +1698,8 @@ static void handle_read_all_regs(GArray *params, void *user_ctx)
}
g_assert(len == gdbserver_state.mem_buf->len);
- memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
- put_strbuf();
+ gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
+ gdb_put_strbuf();
}
static void handle_file_io(GArray *params, void *user_ctx)
@@ -1748,7 +1750,7 @@ static void handle_file_io(GArray *params, void *user_ctx)
}
if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
- put_packet("T02");
+ gdb_put_packet("T02");
return;
}
@@ -1768,7 +1770,7 @@ static void handle_step(GArray *params, void *user_ctx)
static void handle_backward(GArray *params, void *user_ctx)
{
if (!stub_can_reverse()) {
- put_packet("E22");
+ gdb_put_packet("E22");
}
if (params->len == 1) {
switch (get_param(params, 0)->opcode) {
@@ -1776,26 +1778,26 @@ static void handle_backward(GArray *params, void *user_ctx)
if (replay_reverse_step()) {
gdb_continue();
} else {
- put_packet("E14");
+ gdb_put_packet("E14");
}
return;
case 'c':
if (replay_reverse_continue()) {
gdb_continue();
} else {
- put_packet("E14");
+ gdb_put_packet("E14");
}
return;
}
}
/* Default invalid command */
- put_packet("");
+ gdb_put_packet("");
}
static void handle_v_cont_query(GArray *params, void *user_ctx)
{
- put_packet("vCont;c;C;s;S");
+ gdb_put_packet("vCont;c;C;s;S");
}
static void handle_v_cont(GArray *params, void *user_ctx)
@@ -1808,9 +1810,9 @@ static void handle_v_cont(GArray *params, void *user_ctx)
res = gdb_handle_vcont(get_param(params, 0)->data);
if ((res == -EINVAL) || (res == -ERANGE)) {
- put_packet("E22");
+ gdb_put_packet("E22");
} else if (res) {
- put_packet("");
+ gdb_put_packet("");
}
}
@@ -1842,13 +1844,13 @@ static void handle_v_attach(GArray *params, void *user_ctx)
gdb_append_thread_id(cpu, gdbserver_state.str_buf);
g_string_append_c(gdbserver_state.str_buf, ';');
cleanup:
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_v_kill(GArray *params, void *user_ctx)
{
/* Kill the target */
- put_packet("OK");
+ gdb_put_packet("OK");
error_report("QEMU: Terminated via GDBstub");
gdb_exit(0);
exit(0);
@@ -1889,7 +1891,7 @@ static void handle_v_commands(GArray *params, void *user_ctx)
if (process_string_cmd(NULL, get_param(params, 0)->data,
gdb_v_commands_table,
ARRAY_SIZE(gdb_v_commands_table))) {
- put_packet("");
+ gdb_put_packet("");
}
}
@@ -1907,7 +1909,7 @@ static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
SSTEP_NOTIMER);
}
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
@@ -1921,19 +1923,19 @@ static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
new_sstep_flags = get_param(params, 0)->val_ul;
if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
gdbserver_state.sstep_flags = new_sstep_flags;
- put_packet("OK");
+ gdb_put_packet("OK");
}
static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
{
g_string_printf(gdbserver_state.str_buf, "0x%x",
gdbserver_state.sstep_flags);
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_query_curr_tid(GArray *params, void *user_ctx)
@@ -1950,19 +1952,19 @@ static void handle_query_curr_tid(GArray *params, void *user_ctx)
cpu = get_first_cpu_in_process(process);
g_string_assign(gdbserver_state.str_buf, "QC");
gdb_append_thread_id(cpu, gdbserver_state.str_buf);
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_query_threads(GArray *params, void *user_ctx)
{
if (!gdbserver_state.query_cpu) {
- put_packet("l");
+ gdb_put_packet("l");
return;
}
g_string_assign(gdbserver_state.str_buf, "m");
gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
- put_strbuf();
+ gdb_put_strbuf();
gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
}
@@ -1979,7 +1981,7 @@ static void handle_query_thread_extra(GArray *params, void *user_ctx)
if (!params->len ||
get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -2004,8 +2006,8 @@ static void handle_query_thread_extra(GArray *params, void *user_ctx)
cpu->halted ? "halted " : "running");
}
trace_gdbstub_op_extra_info(rs->str);
- memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
- put_strbuf();
+ gdb_memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
+ gdb_put_strbuf();
}
#ifdef CONFIG_USER_ONLY
@@ -2021,7 +2023,7 @@ static void handle_query_offsets(GArray *params, void *user_ctx)
ts->info->code_offset,
ts->info->data_offset,
ts->info->data_offset);
- put_strbuf();
+ gdb_put_strbuf();
}
#else
static void handle_query_rcmd(GArray *params, void *user_ctx)
@@ -2030,24 +2032,24 @@ static void handle_query_rcmd(GArray *params, void *user_ctx)
int len;
if (!params->len) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
len = strlen(get_param(params, 0)->data);
if (len % 2) {
- put_packet("E01");
+ gdb_put_packet("E01");
return;
}
g_assert(gdbserver_state.mem_buf->len == 0);
len = len / 2;
- hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
+ gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
qemu_chr_be_write(gdbserver_system_state.mon_chr,
gdbserver_state.mem_buf->data,
gdbserver_state.mem_buf->len);
- put_packet("OK");
+ gdb_put_packet("OK");
}
#endif
@@ -2078,7 +2080,7 @@ static void handle_query_supported(GArray *params, void *user_ctx)
}
g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_query_xfer_features(GArray *params, void *user_ctx)
@@ -2090,14 +2092,14 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
const char *p;
if (params->len < 3) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
process = gdb_get_cpu_process(gdbserver_state.g_cpu);
cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
if (!cc->gdb_core_xml_file) {
- put_packet("");
+ gdb_put_packet("");
return;
}
@@ -2105,7 +2107,7 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
p = get_param(params, 0)->data;
xml = get_feature_xml(p, &p, process);
if (!xml) {
- put_packet("E00");
+ gdb_put_packet("E00");
return;
}
@@ -2113,7 +2115,7 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
len = get_param(params, 2)->val_ul;
total_len = strlen(xml);
if (addr > total_len) {
- put_packet("E00");
+ gdb_put_packet("E00");
return;
}
@@ -2123,13 +2125,13 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
if (len < total_len - addr) {
g_string_assign(gdbserver_state.str_buf, "m");
- memtox(gdbserver_state.str_buf, xml + addr, len);
+ gdb_memtox(gdbserver_state.str_buf, xml + addr, len);
} else {
g_string_assign(gdbserver_state.str_buf, "l");
- memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
+ gdb_memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
}
- put_packet_binary(gdbserver_state.str_buf->str,
+ gdb_put_packet_binary(gdbserver_state.str_buf->str,
gdbserver_state.str_buf->len, true);
}
@@ -2140,7 +2142,7 @@ static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
unsigned long offset, len, saved_auxv, auxv_len;
if (params->len < 2) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -2151,7 +2153,7 @@ static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
auxv_len = ts->info->auxv_len;
if (offset >= auxv_len) {
- put_packet("E00");
+ gdb_put_packet("E00");
return;
}
@@ -2169,20 +2171,20 @@ static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
g_byte_array_set_size(gdbserver_state.mem_buf, len);
if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
gdbserver_state.mem_buf->data, len, false)) {
- put_packet("E14");
+ gdb_put_packet("E14");
return;
}
- memtox(gdbserver_state.str_buf,
- (const char *)gdbserver_state.mem_buf->data, len);
- put_packet_binary(gdbserver_state.str_buf->str,
- gdbserver_state.str_buf->len, true);
+ gdb_memtox(gdbserver_state.str_buf,
+ (const char *)gdbserver_state.mem_buf->data, len);
+ gdb_put_packet_binary(gdbserver_state.str_buf->str,
+ gdbserver_state.str_buf->len, true);
}
#endif
static void handle_query_attached(GArray *params, void *user_ctx)
{
- put_packet(GDB_ATTACHED);
+ gdb_put_packet(GDB_ATTACHED);
}
static void handle_query_qemu_supported(GArray *params, void *user_ctx)
@@ -2191,7 +2193,7 @@ static void handle_query_qemu_supported(GArray *params, void *user_ctx)
#ifndef CONFIG_USER_ONLY
g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
#endif
- put_strbuf();
+ gdb_put_strbuf();
}
#ifndef CONFIG_USER_ONLY
@@ -2199,13 +2201,13 @@ static void handle_query_qemu_phy_mem_mode(GArray *params,
void *user_ctx)
{
g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
- put_strbuf();
+ gdb_put_strbuf();
}
static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
{
if (!params->len) {
- put_packet("E22");
+ gdb_put_packet("E22");
return;
}
@@ -2214,7 +2216,7 @@ static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
} else {
phy_memory_mode = 1;
}
- put_packet("OK");
+ gdb_put_packet("OK");
}
#endif
@@ -2347,7 +2349,7 @@ static void handle_gen_query(GArray *params, void *user_ctx)
if (process_string_cmd(NULL, get_param(params, 0)->data,
gdb_gen_query_table,
ARRAY_SIZE(gdb_gen_query_table))) {
- put_packet("");
+ gdb_put_packet("");
}
}
@@ -2366,7 +2368,7 @@ static void handle_gen_set(GArray *params, void *user_ctx)
if (process_string_cmd(NULL, get_param(params, 0)->data,
gdb_gen_set_table,
ARRAY_SIZE(gdb_gen_set_table))) {
- put_packet("");
+ gdb_put_packet("");
}
}
@@ -2375,7 +2377,7 @@ static void handle_target_halt(GArray *params, void *user_ctx)
g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
g_string_append_c(gdbserver_state.str_buf, ';');
- put_strbuf();
+ gdb_put_strbuf();
/*
* Remove all the breakpoints when this query is issued,
* because gdb is doing an initial connect and the state
@@ -2392,7 +2394,7 @@ static int gdb_handle_packet(const char *line_buf)
switch (line_buf[0]) {
case '!':
- put_packet("OK");
+ gdb_put_packet("OK");
break;
case '?':
{
@@ -2619,7 +2621,7 @@ static int gdb_handle_packet(const char *line_buf)
break;
default:
/* put empty packet */
- put_packet("");
+ gdb_put_packet("");
break;
}
@@ -2660,7 +2662,7 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
}
/* Is there a GDB syscall waiting to be sent? */
if (gdbserver_state.current_syscall_cb) {
- put_packet(gdbserver_state.syscall_buf);
+ gdb_put_packet(gdbserver_state.syscall_buf);
return;
}
@@ -2685,7 +2687,7 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
type = "";
break;
}
- trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
+ trace_gdbstub_hit_watchpoint(type, gdb_get_cpu_index(cpu),
(target_ulong)cpu->watchpoint_hit->vaddr);
g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
GDB_SIGNAL_TRAP, tid->str, type,
@@ -2733,7 +2735,7 @@ static void gdb_vm_state_change(void *opaque, bool running, RunState state)
g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
send_packet:
- put_packet(buf->str);
+ gdb_put_packet(buf->str);
/* disable single step if it was enabled */
cpu_single_step(cpu, 0);
@@ -2794,7 +2796,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
}
*p = 0;
#ifdef CONFIG_USER_ONLY
- put_packet(gdbserver_state.syscall_buf);
+ gdb_put_packet(gdbserver_state.syscall_buf);
/* Return control to gdb for it to process the syscall request.
* Since the protocol requires that gdb hands control back to us
* using a "here are the results" F packet, we don't need to check
@@ -2822,7 +2824,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
va_end(va);
}
-static void gdb_read_byte(uint8_t ch)
+void gdb_read_byte(uint8_t ch)
{
uint8_t reply;
@@ -2832,7 +2834,7 @@ static void gdb_read_byte(uint8_t ch)
of a new command then abandon the previous response. */
if (ch == '-') {
trace_gdbstub_err_got_nack();
- put_buffer(gdbserver_state.last_packet->data,
+ gdb_put_buffer(gdbserver_state.last_packet->data,
gdbserver_state.last_packet->len);
} else if (ch == '+') {
trace_gdbstub_io_got_ack();
@@ -2954,12 +2956,12 @@ static void gdb_read_byte(uint8_t ch)
trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
/* send NAK reply */
reply = '-';
- put_buffer(&reply, 1);
+ gdb_put_buffer(&reply, 1);
gdbserver_state.state = RS_IDLE;
} else {
/* send ACK reply */
reply = '+';
- put_buffer(&reply, 1);
+ gdb_put_buffer(&reply, 1);
gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
}
break;
@@ -2989,7 +2991,7 @@ void gdb_exit(int code)
trace_gdbstub_op_exiting((uint8_t)code);
snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
- put_packet(buf);
+ gdb_put_packet(buf);
#ifndef CONFIG_USER_ONLY
qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
@@ -3001,7 +3003,7 @@ void gdb_exit(int code)
* part of a CPU cluster). Note that if this process contains no CPUs, it won't
* be attachable and thus will be invisible to the user.
*/
-static void create_default_process(GDBState *s)
+void gdb_create_default_process(GDBState *s)
{
GDBProcess *process;
int max_pid = 0;
@@ -3042,10 +3044,12 @@ gdb_handlesig(CPUState *cpu, int sig)
"T%02xthread:", target_signal_to_gdb(sig));
gdb_append_thread_id(cpu, gdbserver_state.str_buf);
g_string_append_c(gdbserver_state.str_buf, ';');
- put_strbuf();
+ gdb_put_strbuf();
}
- /* put_packet() might have detected that the peer terminated the
- connection. */
+ /*
+ * gdb_put_packet() might have detected that the peer terminated the
+ * connection.
+ */
if (gdbserver_user_state.fd < 0) {
return sig;
}
@@ -3086,13 +3090,13 @@ void gdb_signalled(CPUArchState *env, int sig)
}
snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
- put_packet(buf);
+ gdb_put_packet(buf);
}
static void gdb_accept_init(int fd)
{
- init_gdbserver_state();
- create_default_process(&gdbserver_state);
+ gdb_init_gdbserver_state();
+ gdb_create_default_process(&gdbserver_state);
gdbserver_state.processes[0].attached = true;
gdbserver_state.c_cpu = gdb_first_attached_cpu();
gdbserver_state.g_cpu = gdbserver_state.c_cpu;
@@ -3292,8 +3296,8 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent event)
static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
{
g_autoptr(GString) hex_buf = g_string_new("O");
- memtohex(hex_buf, buf, len);
- put_packet(hex_buf->str);
+ gdb_memtohex(hex_buf, buf, len);
+ gdb_put_packet(hex_buf->str);
return len;
}
@@ -3379,7 +3383,7 @@ static void create_processes(GDBState *s)
qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
}
- create_default_process(s);
+ gdb_create_default_process(s);
}
int gdbserver_start(const char *device)
@@ -3429,7 +3433,7 @@ int gdbserver_start(const char *device)
}
if (!gdbserver_state.init) {
- init_gdbserver_state();
+ gdb_init_gdbserver_state();
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index b4620f99c4..cf76627cf7 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -85,6 +85,31 @@ static inline int tohex(int v)
}
/*
+ * Connection helpers for both softmmu and user backends
+ */
+
+void gdb_put_strbuf(void);
+int gdb_put_packet(const char *buf);
+int gdb_put_packet_binary(const char *buf, int len, bool dump);
+void gdb_hextomem(GByteArray *mem, const char *buf, int len);
+void gdb_memtohex(GString *buf, const uint8_t *mem, int len);
+void gdb_memtox(GString *buf, const char *mem, int len);
+void gdb_read_byte(uint8_t ch);
+
+/* utility helpers */
+CPUState *gdb_first_attached_cpu(void);
+void gdb_append_thread_id(CPUState *cpu, GString *buf);
+int gdb_get_cpu_index(CPUState *cpu);
+
+void gdb_init_gdbserver_state(void);
+void gdb_create_default_process(GDBState *s);
+
+/*
+ * Helpers with separate softmmu and user implementations
+ */
+void gdb_put_buffer(const uint8_t *buf, int len);
+
+/*
* Break/Watch point support - there is an implementation for softmmu
* and user mode.
*/