Add a new query/set which changes the memory GDB sees to physical memory only.
gdb> maint packet qqemu.PhyMemMode will reply the current phy_mem_mode state (1 for enabled, 0 for disabled) gdb> maint packet Qqemu.PhyMemMode:1 Will make GDB read/write only to physical memory, set to 0 to disable Signed-off-by: Jon Doron <ari...@gmail.com> --- gdbstub.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 9dd934a079..c9269319d8 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -46,11 +46,27 @@ #define GDB_ATTACHED "1" #endif +#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 = CPU_GET_CLASS(cpu); + 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); } @@ -2118,8 +2134,36 @@ static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx) static void handle_query_qemu_supported(GdbCmdContext *gdb_ctx, void *user_ctx) { - put_packet(gdb_ctx->s, "sstepbits;sstep"); + snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "sstepbits;sstep"); +#ifndef CONFIG_USER_ONLY + pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";PhyMemMode"); +#endif + put_packet(gdb_ctx->s, gdb_ctx->str_buf); +} + +#ifndef CONFIG_USER_ONLY +static void handle_query_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx, + void *user_ctx) +{ + snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "%d", phy_memory_mode); + put_packet(gdb_ctx->s, gdb_ctx->str_buf); +} + +static void handle_set_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx, void *user_ctx) +{ + if (!gdb_ctx->num_params) { + put_packet(gdb_ctx->s, "E22"); + return; + } + + if (!gdb_ctx->params[0].val_ul) { + phy_memory_mode = 0; + } else { + phy_memory_mode = 1; + } + put_packet(gdb_ctx->s, "OK"); } +#endif static GdbCmdParseEntry gdb_gen_query_set_common_table[] = { /* Order is important if has same prefix */ @@ -2201,6 +2245,12 @@ static GdbCmdParseEntry gdb_gen_query_table[] = { .handler = handle_query_qemu_supported, .cmd = "qemu.Supported", }, +#ifndef CONFIG_USER_ONLY + { + .handler = handle_query_qemu_phy_mem_mode, + .cmd = "qemu.PhyMemMode", + }, +#endif }; static GdbCmdParseEntry gdb_gen_set_table[] = { @@ -2211,6 +2261,14 @@ static GdbCmdParseEntry gdb_gen_set_table[] = { .cmd_startswith = 1, .schema = "l0" }, +#ifndef CONFIG_USER_ONLY + { + .handler = handle_set_qemu_phy_mem_mode, + .cmd = "qemu.PhyMemMode:", + .cmd_startswith = 1, + .schema = "l0" + }, +#endif }; static void handle_gen_query(GdbCmdContext *gdb_ctx, void *user_ctx) -- 2.21.0