gdbstub: specialise target_memory_rw_debug

The two implementations are different enough to encourage having a
specialisation and we can move some of the softmmu only stuff out of
gdbstub.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230302190846.2593720-16-alex.bennee@linaro.org>
Message-Id: <20230303025805.625589-16-richard.henderson@linaro.org>
This commit is contained in:
Alex Bennée 2023-03-02 18:57:51 -08:00
parent 8a2025b36b
commit 589a58672e
4 changed files with 96 additions and 62 deletions

View file

@ -46,33 +46,6 @@
#include "internals.h"
#ifndef CONFIG_USER_ONLY
static int phy_memory_mode;
#endif
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
uint8_t *buf, int len, bool is_write)
{
CPUClass *cc;
#ifndef CONFIG_USER_ONLY
if (phy_memory_mode) {
if (is_write) {
cpu_physical_memory_write(addr, buf, len);
} else {
cpu_physical_memory_read(addr, buf, len);
}
return 0;
}
#endif
cc = CPU_GET_CLASS(cpu);
if (cc->memory_rw_debug) {
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
}
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
}
typedef struct GDBRegisterState {
int base_reg;
int num_regs;
@ -1195,11 +1168,11 @@ static void handle_write_mem(GArray *params, void *user_ctx)
}
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)) {
get_param(params, 1)->val_ull);
if (gdb_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)) {
gdb_put_packet("E14");
return;
}
@ -1223,10 +1196,10 @@ static void handle_read_mem(GArray *params, void *user_ctx)
g_byte_array_set_size(gdbserver_state.mem_buf,
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, false)) {
if (gdb_target_memory_rw_debug(gdbserver_state.g_cpu,
get_param(params, 0)->val_ull,
gdbserver_state.mem_buf->data,
gdbserver_state.mem_buf->len, false)) {
gdb_put_packet("E14");
return;
}
@ -1676,30 +1649,6 @@ static void handle_query_qemu_supported(GArray *params, void *user_ctx)
gdb_put_strbuf();
}
#ifndef CONFIG_USER_ONLY
static void handle_query_qemu_phy_mem_mode(GArray *params,
void *user_ctx)
{
g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
gdb_put_strbuf();
}
static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
{
if (!params->len) {
gdb_put_packet("E22");
return;
}
if (!get_param(params, 0)->val_ul) {
phy_memory_mode = 0;
} else {
phy_memory_mode = 1;
}
gdb_put_packet("OK");
}
#endif
static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
/* Order is important if has same prefix */
{
@ -1790,7 +1739,7 @@ static const GdbCmdParseEntry gdb_gen_query_table[] = {
},
#ifndef CONFIG_USER_ONLY
{
.handler = handle_query_qemu_phy_mem_mode,
.handler = gdb_handle_query_qemu_phy_mem_mode,
.cmd = "qemu.PhyMemMode",
},
#endif
@ -1806,7 +1755,7 @@ static const GdbCmdParseEntry gdb_gen_set_table[] = {
},
#ifndef CONFIG_USER_ONLY
{
.handler = handle_set_qemu_phy_mem_mode,
.handler = gdb_handle_set_qemu_phy_mem_mode,
.cmd = "qemu.PhyMemMode:",
.cmd_startswith = 1,
.schema = "l0"

View file

@ -185,6 +185,10 @@ void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx); /*user */
void gdb_handle_query_attached(GArray *params, void *user_ctx); /* both */
/* softmmu only */
void gdb_handle_query_qemu_phy_mem_mode(GArray *params, void *user_ctx);
void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx);
/*
* Break/Watch point support - there is an implementation for softmmu
* and user mode.
@ -194,4 +198,19 @@ int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len);
int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len);
void gdb_breakpoint_remove_all(CPUState *cs);
/**
* gdb_target_memory_rw_debug() - handle debug access to memory
* @cs: CPUState
* @addr: nominal address, could be an entire physical address
* @buf: data
* @len: length of access
* @is_write: is it a write operation
*
* This function is specialised depending on the mode we are running
* in. For softmmu guests we can switch the interpretation of the
* address to a physical address.
*/
int gdb_target_memory_rw_debug(CPUState *cs, hwaddr addr,
uint8_t *buf, int len, bool is_write);
#endif /* GDBSTUB_INTERNALS_H */

View file

@ -413,9 +413,60 @@ void gdb_exit(int code)
qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
}
/*
* Memory access
*/
static int phy_memory_mode;
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
uint8_t *buf, int len, bool is_write)
{
CPUClass *cc;
if (phy_memory_mode) {
if (is_write) {
cpu_physical_memory_write(addr, buf, len);
} else {
cpu_physical_memory_read(addr, buf, len);
}
return 0;
}
cc = CPU_GET_CLASS(cpu);
if (cc->memory_rw_debug) {
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
}
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
}
/*
* Softmmu specific command helpers
*/
void gdb_handle_query_qemu_phy_mem_mode(GArray *params,
void *user_ctx)
{
g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
gdb_put_strbuf();
}
void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
{
if (!params->len) {
gdb_put_packet("E22");
return;
}
if (!get_param(params, 0)->val_ul) {
phy_memory_mode = 0;
} else {
phy_memory_mode = 1;
}
gdb_put_packet("OK");
}
void gdb_handle_query_rcmd(GArray *params, void *user_ctx)
{
const guint8 zero = 0;

View file

@ -378,6 +378,21 @@ int gdb_continue_partial(char *newstates)
return res;
}
/*
* Memory access helpers
*/
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
uint8_t *buf, int len, bool is_write)
{
CPUClass *cc;
cc = CPU_GET_CLASS(cpu);
if (cc->memory_rw_debug) {
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
}
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
}
/*
* Break/Watch point helpers
*/