From: "Vanderson M. do Rosario" <vandersonmr2@gmail.com>
Introduce a MonitorDisasSpace to replace the current is_physical
boolean argument to monitor_disas. Generate an error if we attempt
to read past the end of a single RAMBlock.
Signed-off-by: Vanderson M. do Rosario <vandersonmr2@gmail.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Fei Wu <fei2.wu@intel.com>
[rth: Split out of a larger patch; validate the RAMBlock size]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/disas/disas.h | 8 +++++++-
disas/disas-mon.c | 32 ++++++++++++++++++++++++++++++--
monitor/hmp-cmds-target.c | 27 ++++++++++++++++-----------
3 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/include/disas/disas.h b/include/disas/disas.h
index 176775eff7..cd99b0ccd0 100644
--- a/include/disas/disas.h
+++ b/include/disas/disas.h
@@ -5,8 +5,14 @@
void disas(FILE *out, const void *code, size_t size);
void target_disas(FILE *out, CPUState *cpu, uint64_t code, size_t size);
+typedef enum {
+ MON_DISAS_GVA, /* virtual */
+ MON_DISAS_GPA, /* physical */
+ MON_DISAS_GRA, /* ram_addr_t */
+} MonitorDisasSpace;
+
void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
- int nb_insn, bool is_physical);
+ int nb_insn, MonitorDisasSpace space);
char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size);
diff --git a/disas/disas-mon.c b/disas/disas-mon.c
index 48ac492c6c..d486f64c92 100644
--- a/disas/disas-mon.c
+++ b/disas/disas-mon.c
@@ -23,9 +23,27 @@ physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
return res == MEMTX_OK ? 0 : EIO;
}
+static int
+ram_addr_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
+ struct disassemble_info *info)
+{
+ hwaddr hw_length;
+ void *p;
+
+ RCU_READ_LOCK_GUARD();
+
+ hw_length = length;
+ p = qemu_ram_ptr_length(NULL, memaddr, &hw_length, false);
+ if (hw_length < length) {
+ return EIO;
+ }
+ memcpy(myaddr, p, length);
+ return 0;
+}
+
/* Disassembler for the monitor. */
void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
- int nb_insn, bool is_physical)
+ int nb_insn, MonitorDisasSpace space)
{
int count, i;
CPUDebug s;
@@ -35,8 +53,18 @@ void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
s.info.fprintf_func = disas_gstring_printf;
s.info.stream = (FILE *)ds; /* abuse this slot */
- if (is_physical) {
+ switch (space) {
+ case MON_DISAS_GVA:
+ /* target_read_memory set in disas_initialize_debug_target */
+ break;
+ case MON_DISAS_GPA:
s.info.read_memory_func = physical_read_memory;
+ break;
+ case MON_DISAS_GRA:
+ s.info.read_memory_func = ram_addr_read_memory;
+ break;
+ default:
+ g_assert_not_reached();
}
s.info.buffer_vma = pc;
diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c
index d9fbcac08d..476cf68e81 100644
--- a/monitor/hmp-cmds-target.c
+++ b/monitor/hmp-cmds-target.c
@@ -120,21 +120,20 @@ void hmp_info_registers(Monitor *mon, const QDict *qdict)
}
static void memory_dump(Monitor *mon, int count, int format, int wsize,
- hwaddr addr, int is_physical)
+ hwaddr addr, MonitorDisasSpace space)
{
int l, line_size, i, max_digits, len;
uint8_t buf[16];
uint64_t v;
CPUState *cs = mon_get_cpu(mon);
- if (!cs && (format == 'i' || !is_physical)) {
+ if (space == MON_DISAS_GVA || format == 'i') {
monitor_printf(mon, "Can not dump without CPU\n");
return;
}
if (format == 'i') {
- monitor_disas(mon, cs, addr, count, is_physical);
- return;
+ monitor_disas(mon, cs, addr, count, space);
}
len = wsize * count;
@@ -163,15 +162,21 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
}
while (len > 0) {
- if (is_physical) {
- monitor_printf(mon, HWADDR_FMT_plx ":", addr);
- } else {
+ switch (space) {
+ case MON_DISAS_GVA:
monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
+ break;
+ case MON_DISAS_GPA:
+ monitor_printf(mon, HWADDR_FMT_plx ":", addr);
+ break;
+ default:
+ g_assert_not_reached();
}
l = len;
- if (l > line_size)
+ if (l > line_size) {
l = line_size;
- if (is_physical) {
+ }
+ if (space == MON_DISAS_GPA) {
AddressSpace *as = cs ? cs->as : &address_space_memory;
MemTxResult r = address_space_read(as, addr,
MEMTXATTRS_UNSPECIFIED, buf, l);
@@ -235,7 +240,7 @@ void hmp_memory_dump(Monitor *mon, const QDict *qdict)
int size = qdict_get_int(qdict, "size");
target_long addr = qdict_get_int(qdict, "addr");
- memory_dump(mon, count, format, size, addr, 0);
+ memory_dump(mon, count, format, size, addr, MON_DISAS_GVA);
}
void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
@@ -245,7 +250,7 @@ void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
int size = qdict_get_int(qdict, "size");
hwaddr addr = qdict_get_int(qdict, "addr");
- memory_dump(mon, count, format, size, addr, 1);
+ memory_dump(mon, count, format, size, addr, MON_DISAS_GPA);
}
void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
--
2.34.1