blob: 48ac492c6ca240af7ce698703573a4d967da7b16 [file] [log] [blame]
Thomas Huthe22d3c42023-05-09 17:14:36 +01001/*
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
14static int
15physical_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. */
27void 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}