gdbstub: Implement deatch (D pkt) with new infra

Signed-off-by: Jon Doron <arilou@gmail.com>
Message-Id: <20190529064148.19856-3-arilou@gmail.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
Jon Doron 2019-05-29 09:41:30 +03:00 committed by Alex Bennée
parent d14055dc69
commit 3e2c12615b

101
gdbstub.c
View File

@ -1417,11 +1417,6 @@ static inline int startswith(const char *string, const char *pattern)
return !strncmp(string, pattern, strlen(pattern)); return !strncmp(string, pattern, strlen(pattern));
} }
static int process_string_cmd(
GDBState *s, void *user_ctx, const char *data,
const GdbCmdParseEntry *cmds, int num_cmds)
__attribute__((unused));
static int process_string_cmd(GDBState *s, void *user_ctx, const char *data, static int process_string_cmd(GDBState *s, void *user_ctx, const char *data,
const GdbCmdParseEntry *cmds, int num_cmds) const GdbCmdParseEntry *cmds, int num_cmds)
{ {
@ -1467,6 +1462,55 @@ static int process_string_cmd(GDBState *s, void *user_ctx, const char *data,
return -1; return -1;
} }
static void run_cmd_parser(GDBState *s, const char *data,
const GdbCmdParseEntry *cmd)
{
if (!data) {
return;
}
/* 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(s, NULL, data, cmd, 1)) {
put_packet(s, "");
}
}
static void handle_detach(GdbCmdContext *gdb_ctx, void *user_ctx)
{
GDBProcess *process;
GDBState *s = gdb_ctx->s;
uint32_t pid = 1;
if (s->multiprocess) {
if (!gdb_ctx->num_params) {
put_packet(s, "E22");
return;
}
pid = gdb_ctx->params[0].val_ul;
}
process = gdb_get_process(s, pid);
gdb_process_breakpoint_remove_all(s, process);
process->attached = false;
if (pid == gdb_get_cpu_pid(s, s->c_cpu)) {
s->c_cpu = gdb_first_attached_cpu(s);
}
if (pid == gdb_get_cpu_pid(s, s->g_cpu)) {
s->g_cpu = gdb_first_attached_cpu(s);
}
if (!s->c_cpu) {
/* No more process attached */
gdb_syscall_mode = GDB_SYS_DISABLED;
gdb_continue(s);
}
put_packet(s, "OK");
}
static int gdb_handle_packet(GDBState *s, const char *line_buf) static int gdb_handle_packet(GDBState *s, const char *line_buf)
{ {
CPUState *cpu; CPUState *cpu;
@ -1481,6 +1525,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
uint8_t *registers; uint8_t *registers;
target_ulong addr, len; target_ulong addr, len;
GDBThreadIdKind thread_kind; GDBThreadIdKind thread_kind;
const GdbCmdParseEntry *cmd_parser = NULL;
trace_gdbstub_io_command(line_buf); trace_gdbstub_io_command(line_buf);
@ -1581,42 +1626,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
error_report("QEMU: Terminated via GDBstub"); error_report("QEMU: Terminated via GDBstub");
exit(0); exit(0);
case 'D': case 'D':
/* Detach packet */ {
pid = 1; static const GdbCmdParseEntry detach_cmd_desc = {
.handler = handle_detach,
if (s->multiprocess) { .cmd = "D",
unsigned long lpid; .cmd_startswith = 1,
if (*p != ';') { .schema = "?.l0"
put_packet(s, "E22"); };
break; cmd_parser = &detach_cmd_desc;
} }
if (qemu_strtoul(p + 1, &p, 16, &lpid)) {
put_packet(s, "E22");
break;
}
pid = lpid;
}
process = gdb_get_process(s, pid);
gdb_process_breakpoint_remove_all(s, process);
process->attached = false;
if (pid == gdb_get_cpu_pid(s, s->c_cpu)) {
s->c_cpu = gdb_first_attached_cpu(s);
}
if (pid == gdb_get_cpu_pid(s, s->g_cpu)) {
s->g_cpu = gdb_first_attached_cpu(s);
}
if (s->c_cpu == NULL) {
/* No more process attached */
gdb_syscall_mode = GDB_SYS_DISABLED;
gdb_continue(s);
}
put_packet(s, "OK");
break; break;
case 's': case 's':
if (*p != '\0') { if (*p != '\0') {
@ -1989,6 +2007,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
put_packet(s, buf); put_packet(s, buf);
break; break;
} }
run_cmd_parser(s, line_buf, cmd_parser);
return RS_IDLE; return RS_IDLE;
} }