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 s.info.show_opcodes = true; 38 39 if (is_physical) { 40 s.info.read_memory_func = physical_read_memory; 41 } 42 s.info.buffer_vma = pc; 43 44 if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) { 45 monitor_puts(mon, ds->str); 46 return; 47 } 48 49 if (!s.info.print_insn) { 50 monitor_printf(mon, "0x%08" PRIx64 51 ": Asm output not supported on this arch\n", pc); 52 return; 53 } 54 55 for (i = 0; i < nb_insn; i++) { 56 g_string_append_printf(ds, "0x%08" PRIx64 ": ", pc); 57 count = s.info.print_insn(pc, &s.info); 58 g_string_append_c(ds, '\n'); 59 if (count < 0) { 60 break; 61 } 62 pc += count; 63 } 64 65 monitor_puts(mon, ds->str); 66 } 67