qemu/disas/disas-mon.c
<<
>>
Prefs
   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
  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}
  66