1 /* 2 * Functions related to disassembly from the monitor 3 * 4 * SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #include "qemu/osdep.h" 8 #include "disas-internal.h" 9 #include "disas/disas.h" 10 #include "exec/memory.h" 11 #include "hw/core/cpu.h" 12 #include "monitor/monitor.h" 13 14 static int 15 physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length, 16 struct disassemble_info *info) 17 { 18 CPUDebug *s = container_of(info, CPUDebug, info); 19 MemTxResult res; 20 21 res = address_space_read(s->cpu->as, memaddr, MEMTXATTRS_UNSPECIFIED, 22 myaddr, length); 23 return res == MEMTX_OK ? 0 : EIO; 24 } 25 26 /* Disassembler for the monitor. */ 27 void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc, 28 int nb_insn, bool is_physical) 29 { 30 int count, i; 31 CPUDebug s; 32 g_autoptr(GString) ds = g_string_new(""); 33 34 disas_initialize_debug_target(&s, cpu); 35 s.info.fprintf_func = disas_gstring_printf; 36 s.info.stream = (FILE *)ds; /* abuse this slot */ 37 38 if (is_physical) { 39 s.info.read_memory_func = physical_read_memory; 40 } 41 s.info.buffer_vma = pc; 42 43 if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) { 44 monitor_puts(mon, ds->str); 45 return; 46 } 47 48 if (!s.info.print_insn) { 49 monitor_printf(mon, "0x%08" PRIx64 50 ": Asm output not supported on this arch\n", pc); 51 return; 52 } 53 54 for (i = 0; i < nb_insn; i++) { 55 g_string_append_printf(ds, "0x%08" PRIx64 ": ", pc); 56 count = s.info.print_insn(pc, &s.info); 57 g_string_append_c(ds, '\n'); 58 if (count < 0) { 59 break; 60 } 61 pc += count; 62 } 63 64 monitor_puts(mon, ds->str); 65 } 66