From ab4752ec8d9b0b19ab80915016b739350418a078 Mon Sep 17 00:00:00 2001 From: Jon Doron Date: Wed, 29 May 2019 09:41:48 +0300 Subject: [PATCH] gdbstub: Implement qemu physical memory mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Message-Id: <20190529064148.19856-21-arilou@gmail.com> Signed-off-by: Alex Bennée --- gdbstub.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 4af94d8f78..d614a1f3c0 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -50,11 +50,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); } @@ -2136,9 +2152,37 @@ 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 */ { @@ -2219,6 +2263,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[] = { @@ -2229,6 +2279,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)