disas: Move softmmu specific code to separate file
We'd like to move disas.c into the common code source set, where CONFIG_USER_ONLY is not available anymore. So we have to move the related code into a separate file instead. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <20230508133745.109463-2-thuth@redhat.com> [rth: Type change done in a separate patch] Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
45dfbd4320
commit
e22d3c48db
21
disas/disas-internal.h
Normal file
21
disas/disas-internal.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Definitions used internally in the disassembly code
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DISAS_INTERNAL_H
|
||||||
|
#define DISAS_INTERNAL_H
|
||||||
|
|
||||||
|
#include "disas/dis-asm.h"
|
||||||
|
|
||||||
|
typedef struct CPUDebug {
|
||||||
|
struct disassemble_info info;
|
||||||
|
CPUState *cpu;
|
||||||
|
} CPUDebug;
|
||||||
|
|
||||||
|
void disas_initialize_debug_target(CPUDebug *s, CPUState *cpu);
|
||||||
|
int disas_gstring_printf(FILE *stream, const char *fmt, ...)
|
||||||
|
G_GNUC_PRINTF(2, 3);
|
||||||
|
|
||||||
|
#endif
|
65
disas/disas-mon.c
Normal file
65
disas/disas-mon.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Functions related to disassembly from the monitor
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "disas-internal.h"
|
||||||
|
#include "disas/disas.h"
|
||||||
|
#include "exec/memory.h"
|
||||||
|
#include "hw/core/cpu.h"
|
||||||
|
#include "monitor/monitor.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||||
|
struct disassemble_info *info)
|
||||||
|
{
|
||||||
|
CPUDebug *s = container_of(info, CPUDebug, info);
|
||||||
|
MemTxResult res;
|
||||||
|
|
||||||
|
res = address_space_read(s->cpu->as, memaddr, MEMTXATTRS_UNSPECIFIED,
|
||||||
|
myaddr, length);
|
||||||
|
return res == MEMTX_OK ? 0 : EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disassembler for the monitor. */
|
||||||
|
void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
|
||||||
|
int nb_insn, bool is_physical)
|
||||||
|
{
|
||||||
|
int count, i;
|
||||||
|
CPUDebug s;
|
||||||
|
g_autoptr(GString) ds = g_string_new("");
|
||||||
|
|
||||||
|
disas_initialize_debug_target(&s, cpu);
|
||||||
|
s.info.fprintf_func = disas_gstring_printf;
|
||||||
|
s.info.stream = (FILE *)ds; /* abuse this slot */
|
||||||
|
|
||||||
|
if (is_physical) {
|
||||||
|
s.info.read_memory_func = physical_read_memory;
|
||||||
|
}
|
||||||
|
s.info.buffer_vma = pc;
|
||||||
|
|
||||||
|
if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) {
|
||||||
|
monitor_puts(mon, ds->str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s.info.print_insn) {
|
||||||
|
monitor_printf(mon, "0x%08" PRIx64
|
||||||
|
": Asm output not supported on this arch\n", pc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nb_insn; i++) {
|
||||||
|
g_string_append_printf(ds, "0x%08" PRIx64 ": ", pc);
|
||||||
|
count = s.info.print_insn(pc, &s.info);
|
||||||
|
g_string_append_c(ds, '\n');
|
||||||
|
if (count < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pc += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_puts(mon, ds->str);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/* General "disassemble this chunk" code. Used for debugging. */
|
/* General "disassemble this chunk" code. Used for debugging. */
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "disas/dis-asm.h"
|
#include "disas/disas-internal.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "qemu/qemu-print.h"
|
#include "qemu/qemu-print.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
@ -8,11 +8,6 @@
|
|||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
|
|
||||||
typedef struct CPUDebug {
|
|
||||||
struct disassemble_info info;
|
|
||||||
CPUState *cpu;
|
|
||||||
} CPUDebug;
|
|
||||||
|
|
||||||
/* Filled in by elfload.c. Simplistic, but will do for now. */
|
/* Filled in by elfload.c. Simplistic, but will do for now. */
|
||||||
struct syminfo *syminfos = NULL;
|
struct syminfo *syminfos = NULL;
|
||||||
|
|
||||||
@ -120,7 +115,7 @@ static void initialize_debug(CPUDebug *s)
|
|||||||
s->info.symbol_at_address_func = symbol_at_address;
|
s->info.symbol_at_address_func = symbol_at_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize_debug_target(CPUDebug *s, CPUState *cpu)
|
void disas_initialize_debug_target(CPUDebug *s, CPUState *cpu)
|
||||||
{
|
{
|
||||||
initialize_debug(s);
|
initialize_debug(s);
|
||||||
|
|
||||||
@ -211,7 +206,7 @@ void target_disas(FILE *out, CPUState *cpu, uint64_t code, size_t size)
|
|||||||
int count;
|
int count;
|
||||||
CPUDebug s;
|
CPUDebug s;
|
||||||
|
|
||||||
initialize_debug_target(&s, cpu);
|
disas_initialize_debug_target(&s, cpu);
|
||||||
s.info.fprintf_func = fprintf;
|
s.info.fprintf_func = fprintf;
|
||||||
s.info.stream = out;
|
s.info.stream = out;
|
||||||
s.info.buffer_vma = code;
|
s.info.buffer_vma = code;
|
||||||
@ -242,8 +237,7 @@ void target_disas(FILE *out, CPUState *cpu, uint64_t code, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int G_GNUC_PRINTF(2, 3)
|
int disas_gstring_printf(FILE *stream, const char *fmt, ...)
|
||||||
gstring_printf(FILE *stream, const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
/* We abuse the FILE parameter to pass a GString. */
|
/* We abuse the FILE parameter to pass a GString. */
|
||||||
GString *s = (GString *)stream;
|
GString *s = (GString *)stream;
|
||||||
@ -273,8 +267,8 @@ char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
|
|||||||
CPUDebug s;
|
CPUDebug s;
|
||||||
GString *ds = g_string_new(NULL);
|
GString *ds = g_string_new(NULL);
|
||||||
|
|
||||||
initialize_debug_target(&s, cpu);
|
disas_initialize_debug_target(&s, cpu);
|
||||||
s.info.fprintf_func = gstring_printf;
|
s.info.fprintf_func = disas_gstring_printf;
|
||||||
s.info.stream = (FILE *)ds; /* abuse this slot */
|
s.info.stream = (FILE *)ds; /* abuse this slot */
|
||||||
s.info.buffer_vma = addr;
|
s.info.buffer_vma = addr;
|
||||||
s.info.buffer_length = size;
|
s.info.buffer_length = size;
|
||||||
@ -339,61 +333,3 @@ const char *lookup_symbol(uint64_t orig_addr)
|
|||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
|
|
||||||
#include "monitor/monitor.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
|
|
||||||
struct disassemble_info *info)
|
|
||||||
{
|
|
||||||
CPUDebug *s = container_of(info, CPUDebug, info);
|
|
||||||
MemTxResult res;
|
|
||||||
|
|
||||||
res = address_space_read(s->cpu->as, memaddr, MEMTXATTRS_UNSPECIFIED,
|
|
||||||
myaddr, length);
|
|
||||||
return res == MEMTX_OK ? 0 : EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disassembler for the monitor. */
|
|
||||||
void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
|
|
||||||
int nb_insn, bool is_physical)
|
|
||||||
{
|
|
||||||
int count, i;
|
|
||||||
CPUDebug s;
|
|
||||||
g_autoptr(GString) ds = g_string_new("");
|
|
||||||
|
|
||||||
initialize_debug_target(&s, cpu);
|
|
||||||
s.info.fprintf_func = gstring_printf;
|
|
||||||
s.info.stream = (FILE *)ds; /* abuse this slot */
|
|
||||||
|
|
||||||
if (is_physical) {
|
|
||||||
s.info.read_memory_func = physical_read_memory;
|
|
||||||
}
|
|
||||||
s.info.buffer_vma = pc;
|
|
||||||
|
|
||||||
if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) {
|
|
||||||
monitor_puts(mon, ds->str);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s.info.print_insn) {
|
|
||||||
monitor_printf(mon, "0x%08" PRIx64
|
|
||||||
": Asm output not supported on this arch\n", pc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nb_insn; i++) {
|
|
||||||
g_string_append_printf(ds, "0x%08" PRIx64 ": ", pc);
|
|
||||||
count = s.info.print_insn(pc, &s.info);
|
|
||||||
g_string_append_c(ds, '\n');
|
|
||||||
if (count < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pc += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_puts(mon, ds->str);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -12,4 +12,5 @@ common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
|
|||||||
common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
|
common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
|
||||||
common_ss.add(when: capstone, if_true: [files('capstone.c'), capstone])
|
common_ss.add(when: capstone, if_true: [files('capstone.c'), capstone])
|
||||||
|
|
||||||
|
softmmu_ss.add(files('disas-mon.c'))
|
||||||
specific_ss.add(files('disas.c'), capstone)
|
specific_ss.add(files('disas.c'), capstone)
|
||||||
|
Loading…
Reference in New Issue
Block a user