Merge tag 'pull-maintainer-june24-240624-1' of https://gitlab.com/stsquad/qemu into...
[qemu/armbru.git] / disas / disas-common.c
blobde61f6d8a1233465f5e7aee30b74f53267bd79eb
1 /*
2 * Common routines for disassembly.
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
6 #include "qemu/osdep.h"
7 #include "disas/disas.h"
8 #include "disas/capstone.h"
9 #include "hw/core/cpu.h"
10 #include "exec/tswap.h"
11 #include "disas-internal.h"
14 /* Filled in by elfload.c. Simplistic, but will do for now. */
15 struct syminfo *syminfos = NULL;
18 * Print an error message. We can assume that this is in response to
19 * an error return from {host,target}_read_memory.
21 static void perror_memory(int status, bfd_vma memaddr,
22 struct disassemble_info *info)
24 if (status != EIO) {
25 /* Can't happen. */
26 info->fprintf_func(info->stream, "Unknown error %d\n", status);
27 } else {
28 /* Address between memaddr and memaddr + len was out of bounds. */
29 info->fprintf_func(info->stream,
30 "Address 0x%" PRIx64 " is out of bounds.\n",
31 memaddr);
35 /* Print address in hex. */
36 static void print_address(bfd_vma addr, struct disassemble_info *info)
38 info->fprintf_func(info->stream, "0x%" PRIx64, addr);
41 /* Stub prevents some fruitless earching in optabs disassemblers. */
42 static int symbol_at_address(bfd_vma addr, struct disassemble_info *info)
44 return 1;
47 void disas_initialize_debug(CPUDebug *s)
49 memset(s, 0, sizeof(*s));
50 s->info.arch = bfd_arch_unknown;
51 s->info.cap_arch = -1;
52 s->info.cap_insn_unit = 4;
53 s->info.cap_insn_split = 4;
54 s->info.memory_error_func = perror_memory;
55 s->info.symbol_at_address_func = symbol_at_address;
58 void disas_initialize_debug_target(CPUDebug *s, CPUState *cpu)
60 disas_initialize_debug(s);
62 s->cpu = cpu;
63 s->info.print_address_func = print_address;
64 if (target_words_bigendian()) {
65 s->info.endian = BFD_ENDIAN_BIG;
66 } else {
67 s->info.endian = BFD_ENDIAN_LITTLE;
70 CPUClass *cc = CPU_GET_CLASS(cpu);
71 if (cc->disas_set_info) {
72 cc->disas_set_info(cpu, &s->info);
76 int disas_gstring_printf(FILE *stream, const char *fmt, ...)
78 /* We abuse the FILE parameter to pass a GString. */
79 GString *s = (GString *)stream;
80 int initial_len = s->len;
81 va_list va;
83 va_start(va, fmt);
84 g_string_append_vprintf(s, fmt, va);
85 va_end(va);
87 return s->len - initial_len;
90 /* Look up symbol for debugging purpose. Returns "" if unknown. */
91 const char *lookup_symbol(uint64_t orig_addr)
93 const char *symbol = "";
94 struct syminfo *s;
96 for (s = syminfos; s; s = s->next) {
97 symbol = s->lookup_symbol(s, orig_addr);
98 if (symbol[0] != '\0') {
99 break;
103 return symbol;