hw/sd/sdcard: Convert SEND_TUNING_BLOCK to generic_read_byte (CMD19)
[qemu/armbru.git] / disas / disas-host.c
blob8146fafe804cd81f0217d4217ce6f17171934e90
1 /*
2 * Routines for host instruction 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 "disas-internal.h"
13 * Get LENGTH bytes from info's buffer, at host address memaddr.
14 * Transfer them to myaddr.
16 static int host_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
17 struct disassemble_info *info)
19 if (memaddr < info->buffer_vma
20 || memaddr + length > info->buffer_vma + info->buffer_length) {
21 /* Out of bounds. Use EIO because GDB uses it. */
22 return EIO;
24 memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
25 return 0;
28 /* Print address in hex, truncated to the width of a host virtual address. */
29 static void host_print_address(bfd_vma addr, struct disassemble_info *info)
31 info->fprintf_func(info->stream, "0x%" PRIxPTR, (uintptr_t)addr);
34 static void initialize_debug_host(CPUDebug *s)
36 disas_initialize_debug(s);
38 s->info.read_memory_func = host_read_memory;
39 s->info.print_address_func = host_print_address;
40 #if HOST_BIG_ENDIAN
41 s->info.endian = BFD_ENDIAN_BIG;
42 #else
43 s->info.endian = BFD_ENDIAN_LITTLE;
44 #endif
45 #if defined(CONFIG_TCG_INTERPRETER)
46 s->info.print_insn = print_insn_tci;
47 #elif defined(__i386__)
48 s->info.mach = bfd_mach_i386_i386;
49 s->info.cap_arch = CS_ARCH_X86;
50 s->info.cap_mode = CS_MODE_32;
51 s->info.cap_insn_unit = 1;
52 s->info.cap_insn_split = 8;
53 #elif defined(__x86_64__)
54 s->info.mach = bfd_mach_x86_64;
55 s->info.cap_arch = CS_ARCH_X86;
56 s->info.cap_mode = CS_MODE_64;
57 s->info.cap_insn_unit = 1;
58 s->info.cap_insn_split = 8;
59 #elif defined(_ARCH_PPC)
60 s->info.cap_arch = CS_ARCH_PPC;
61 # ifdef _ARCH_PPC64
62 s->info.cap_mode = CS_MODE_64;
63 # endif
64 #elif defined(__riscv)
65 #if defined(_ILP32) || (__riscv_xlen == 32)
66 s->info.print_insn = print_insn_riscv32;
67 #elif defined(_LP64)
68 s->info.print_insn = print_insn_riscv64;
69 #else
70 #error unsupported RISC-V ABI
71 #endif
72 #elif defined(__aarch64__)
73 s->info.cap_arch = CS_ARCH_ARM64;
74 #elif defined(__alpha__)
75 s->info.print_insn = print_insn_alpha;
76 #elif defined(__sparc__)
77 s->info.print_insn = print_insn_sparc;
78 s->info.mach = bfd_mach_sparc_v9b;
79 #elif defined(__arm__)
80 /* TCG only generates code for arm mode. */
81 s->info.cap_arch = CS_ARCH_ARM;
82 #elif defined(__MIPSEB__)
83 s->info.print_insn = print_insn_big_mips;
84 #elif defined(__MIPSEL__)
85 s->info.print_insn = print_insn_little_mips;
86 #elif defined(__m68k__)
87 s->info.print_insn = print_insn_m68k;
88 #elif defined(__s390__)
89 s->info.cap_arch = CS_ARCH_SYSZ;
90 s->info.cap_insn_unit = 2;
91 s->info.cap_insn_split = 6;
92 #elif defined(__hppa__)
93 s->info.print_insn = print_insn_hppa;
94 #elif defined(__loongarch__)
95 s->info.print_insn = print_insn_loongarch;
96 #endif
99 /* Disassemble this for me please... (debugging). */
100 void disas(FILE *out, const void *code, size_t size)
102 uintptr_t pc;
103 int count;
104 CPUDebug s;
106 initialize_debug_host(&s);
107 s.info.fprintf_func = fprintf;
108 s.info.stream = out;
109 s.info.buffer = code;
110 s.info.buffer_vma = (uintptr_t)code;
111 s.info.buffer_length = size;
112 s.info.show_opcodes = true;
114 if (s.info.cap_arch >= 0 && cap_disas_host(&s.info, code, size)) {
115 return;
118 if (s.info.print_insn == NULL) {
119 s.info.print_insn = print_insn_od_host;
121 for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
122 fprintf(out, "0x%08" PRIxPTR ": ", pc);
123 count = s.info.print_insn(pc, &s.info);
124 fprintf(out, "\n");
125 if (count < 0) {
126 break;