1 /* General "disassemble this chunk" code. Used for debugging. */
2 #include "qemu/osdep.h"
3 #include "disas/dis-asm.h"
5 #include "qemu/qemu-print.h"
8 #include "disas/disas.h"
9 #include "disas/capstone.h"
11 typedef struct CPUDebug
{
12 struct disassemble_info info
;
16 /* Filled in by elfload.c. Simplistic, but will do for now. */
17 struct syminfo
*syminfos
= NULL
;
20 * Get LENGTH bytes from info's buffer, at host address memaddr.
21 * Transfer them to myaddr.
23 static int host_read_memory(bfd_vma memaddr
, bfd_byte
*myaddr
, int length
,
24 struct disassemble_info
*info
)
26 if (memaddr
< info
->buffer_vma
27 || memaddr
+ length
> info
->buffer_vma
+ info
->buffer_length
) {
28 /* Out of bounds. Use EIO because GDB uses it. */
31 memcpy (myaddr
, info
->buffer
+ (memaddr
- info
->buffer_vma
), length
);
36 * Get LENGTH bytes from info's buffer, at target address memaddr.
37 * Transfer them to myaddr.
39 static int target_read_memory(bfd_vma memaddr
, bfd_byte
*myaddr
, int length
,
40 struct disassemble_info
*info
)
42 CPUDebug
*s
= container_of(info
, CPUDebug
, info
);
43 int r
= cpu_memory_rw_debug(s
->cpu
, memaddr
, myaddr
, length
, 0);
48 * Print an error message. We can assume that this is in response to
49 * an error return from {host,target}_read_memory.
51 static void perror_memory(int status
, bfd_vma memaddr
,
52 struct disassemble_info
*info
)
56 info
->fprintf_func(info
->stream
, "Unknown error %d\n", status
);
58 /* Address between memaddr and memaddr + len was out of bounds. */
59 info
->fprintf_func(info
->stream
,
60 "Address 0x%" PRIx64
" is out of bounds.\n",
65 /* Print address in hex. */
66 static void print_address(bfd_vma addr
, struct disassemble_info
*info
)
68 info
->fprintf_func(info
->stream
, "0x%" PRIx64
, addr
);
71 /* Print address in hex, truncated to the width of a host virtual address. */
72 static void host_print_address(bfd_vma addr
, struct disassemble_info
*info
)
74 print_address((uintptr_t)addr
, info
);
77 /* Stub prevents some fruitless earching in optabs disassemblers. */
78 static int symbol_at_address(bfd_vma addr
, struct disassemble_info
*info
)
83 static int print_insn_objdump(bfd_vma pc
, disassemble_info
*info
,
86 int i
, n
= info
->buffer_length
;
87 uint8_t *buf
= g_malloc(n
);
89 info
->read_memory_func(pc
, buf
, n
, info
);
91 for (i
= 0; i
< n
; ++i
) {
93 info
->fprintf_func(info
->stream
, "\n%s: ", prefix
);
95 info
->fprintf_func(info
->stream
, "%02x", buf
[i
]);
102 static int print_insn_od_host(bfd_vma pc
, disassemble_info
*info
)
104 return print_insn_objdump(pc
, info
, "OBJD-H");
107 static int print_insn_od_target(bfd_vma pc
, disassemble_info
*info
)
109 return print_insn_objdump(pc
, info
, "OBJD-T");
112 #ifdef CONFIG_CAPSTONE
113 /* Temporary storage for the capstone library. This will be alloced via
114 malloc with a size private to the library; thus there's no reason not
115 to share this across calls and across host vs target disassembly. */
116 static __thread cs_insn
*cap_insn
;
118 /* Initialize the Capstone library. */
119 /* ??? It would be nice to cache this. We would need one handle for the
120 host and one for the target. For most targets we can reset specific
121 parameters via cs_option(CS_OPT_MODE, new_mode), but we cannot change
122 CS_ARCH_* in this way. Thus we would need to be able to close and
123 re-open the target handle with a different arch for the target in order
124 to handle AArch64 vs AArch32 mode switching. */
125 static cs_err
cap_disas_start(disassemble_info
*info
, csh
*handle
)
127 cs_mode cap_mode
= info
->cap_mode
;
130 cap_mode
+= (info
->endian
== BFD_ENDIAN_BIG
? CS_MODE_BIG_ENDIAN
131 : CS_MODE_LITTLE_ENDIAN
);
133 err
= cs_open(info
->cap_arch
, cap_mode
, handle
);
134 if (err
!= CS_ERR_OK
) {
138 /* ??? There probably ought to be a better place to put this. */
139 if (info
->cap_arch
== CS_ARCH_X86
) {
140 /* We don't care about errors (if for some reason the library
141 is compiled without AT&T syntax); the user will just have
142 to deal with the Intel syntax. */
143 cs_option(*handle
, CS_OPT_SYNTAX
, CS_OPT_SYNTAX_ATT
);
146 /* "Disassemble" unknown insns as ".byte W,X,Y,Z". */
147 cs_option(*handle
, CS_OPT_SKIPDATA
, CS_OPT_ON
);
149 /* Allocate temp space for cs_disasm_iter. */
150 if (cap_insn
== NULL
) {
151 cap_insn
= cs_malloc(*handle
);
152 if (cap_insn
== NULL
) {
160 static void cap_dump_insn_units(disassemble_info
*info
, cs_insn
*insn
,
163 fprintf_function print
= info
->fprintf_func
;
164 FILE *stream
= info
->stream
;
166 switch (info
->cap_insn_unit
) {
168 if (info
->endian
== BFD_ENDIAN_BIG
) {
169 for (; i
< n
; i
+= 4) {
170 print(stream
, " %08x", ldl_be_p(insn
->bytes
+ i
));
174 for (; i
< n
; i
+= 4) {
175 print(stream
, " %08x", ldl_le_p(insn
->bytes
+ i
));
181 if (info
->endian
== BFD_ENDIAN_BIG
) {
182 for (; i
< n
; i
+= 2) {
183 print(stream
, " %04x", lduw_be_p(insn
->bytes
+ i
));
186 for (; i
< n
; i
+= 2) {
187 print(stream
, " %04x", lduw_le_p(insn
->bytes
+ i
));
194 print(stream
, " %02x", insn
->bytes
[i
]);
200 static void cap_dump_insn(disassemble_info
*info
, cs_insn
*insn
)
202 fprintf_function print
= info
->fprintf_func
;
205 print(info
->stream
, "0x%08" PRIx64
": ", insn
->address
);
208 split
= info
->cap_insn_split
;
210 /* Dump the first SPLIT bytes of the instruction. */
211 cap_dump_insn_units(info
, insn
, 0, MIN(n
, split
));
213 /* Add padding up to SPLIT so that mnemonics line up. */
215 int width
= (split
- n
) / info
->cap_insn_unit
;
216 width
*= (2 * info
->cap_insn_unit
+ 1);
217 print(info
->stream
, "%*s", width
, "");
220 /* Print the actual instruction. */
221 print(info
->stream
, " %-8s %s\n", insn
->mnemonic
, insn
->op_str
);
223 /* Dump any remaining part of the insn on subsequent lines. */
224 for (i
= split
; i
< n
; i
+= split
) {
225 print(info
->stream
, "0x%08" PRIx64
": ", insn
->address
+ i
);
226 cap_dump_insn_units(info
, insn
, i
, MIN(n
, i
+ split
));
227 print(info
->stream
, "\n");
231 /* Disassemble SIZE bytes at PC for the target. */
232 static bool cap_disas_target(disassemble_info
*info
, uint64_t pc
, size_t size
)
234 uint8_t cap_buf
[1024];
239 if (cap_disas_start(info
, &handle
) != CS_ERR_OK
) {
245 size_t tsize
= MIN(sizeof(cap_buf
) - csize
, size
);
246 const uint8_t *cbuf
= cap_buf
;
248 target_read_memory(pc
+ csize
, cap_buf
+ csize
, tsize
, info
);
252 while (cs_disasm_iter(handle
, &cbuf
, &csize
, &pc
, insn
)) {
253 cap_dump_insn(info
, insn
);
256 /* If the target memory is not consumed, go back for more... */
258 /* ... taking care to move any remaining fractional insn
259 to the beginning of the buffer. */
261 memmove(cap_buf
, cbuf
, csize
);
266 /* Since the target memory is consumed, we should not have
267 a remaining fractional insn. */
269 (*info
->fprintf_func
)(info
->stream
,
270 "Disassembler disagrees with translator "
271 "over instruction decoding\n"
272 "Please report this to qemu-devel@nongnu.org\n");
281 /* Disassemble SIZE bytes at CODE for the host. */
282 static bool cap_disas_host(disassemble_info
*info
, void *code
, size_t size
)
289 if (cap_disas_start(info
, &handle
) != CS_ERR_OK
) {
295 pc
= (uintptr_t)code
;
297 while (cs_disasm_iter(handle
, &cbuf
, &size
, &pc
, insn
)) {
298 cap_dump_insn(info
, insn
);
301 (*info
->fprintf_func
)(info
->stream
,
302 "Disassembler disagrees with TCG over instruction encoding\n"
303 "Please report this to qemu-devel@nongnu.org\n");
310 #if !defined(CONFIG_USER_ONLY)
311 /* Disassemble COUNT insns at PC for the target. */
312 static bool cap_disas_monitor(disassemble_info
*info
, uint64_t pc
, int count
)
319 if (cap_disas_start(info
, &handle
) != CS_ERR_OK
) {
325 /* We want to read memory for one insn, but generically we do not
326 know how much memory that is. We have a small buffer which is
327 known to be sufficient for all supported targets. Try to not
328 read beyond the page, Just In Case. For even more simplicity,
329 ignore the actual target page size and use a 1k boundary. If
330 that turns out to be insufficient, we'll come back around the
331 loop and read more. */
332 uint64_t epc
= QEMU_ALIGN_UP(pc
+ csize
+ 1, 1024);
333 size_t tsize
= MIN(sizeof(cap_buf
) - csize
, epc
- pc
);
334 const uint8_t *cbuf
= cap_buf
;
336 /* Make certain that we can make progress. */
338 info
->read_memory_func(pc
, cap_buf
+ csize
, tsize
, info
);
341 if (cs_disasm_iter(handle
, &cbuf
, &csize
, &pc
, insn
)) {
342 cap_dump_insn(info
, insn
);
347 memmove(cap_buf
, cbuf
, csize
);
353 #endif /* !CONFIG_USER_ONLY */
355 # define cap_disas_target(i, p, s) false
356 # define cap_disas_host(i, p, s) false
357 # define cap_disas_monitor(i, p, c) false
358 # define cap_disas_plugin(i, p, c) false
359 #endif /* CONFIG_CAPSTONE */
361 static void initialize_debug(CPUDebug
*s
)
363 memset(s
, 0, sizeof(*s
));
364 s
->info
.arch
= bfd_arch_unknown
;
365 s
->info
.cap_arch
= -1;
366 s
->info
.cap_insn_unit
= 4;
367 s
->info
.cap_insn_split
= 4;
368 s
->info
.memory_error_func
= perror_memory
;
369 s
->info
.symbol_at_address_func
= symbol_at_address
;
372 static void initialize_debug_target(CPUDebug
*s
, CPUState
*cpu
)
377 s
->info
.read_memory_func
= target_read_memory
;
378 s
->info
.print_address_func
= print_address
;
379 #ifdef TARGET_WORDS_BIGENDIAN
380 s
->info
.endian
= BFD_ENDIAN_BIG
;
382 s
->info
.endian
= BFD_ENDIAN_LITTLE
;
385 CPUClass
*cc
= CPU_GET_CLASS(cpu
);
386 if (cc
->disas_set_info
) {
387 cc
->disas_set_info(cpu
, &s
->info
);
391 static void initialize_debug_host(CPUDebug
*s
)
395 s
->info
.read_memory_func
= host_read_memory
;
396 s
->info
.print_address_func
= host_print_address
;
397 #ifdef HOST_WORDS_BIGENDIAN
398 s
->info
.endian
= BFD_ENDIAN_BIG
;
400 s
->info
.endian
= BFD_ENDIAN_LITTLE
;
402 #if defined(CONFIG_TCG_INTERPRETER)
403 s
->info
.print_insn
= print_insn_tci
;
404 #elif defined(__i386__)
405 s
->info
.mach
= bfd_mach_i386_i386
;
406 s
->info
.print_insn
= print_insn_i386
;
407 s
->info
.cap_arch
= CS_ARCH_X86
;
408 s
->info
.cap_mode
= CS_MODE_32
;
409 s
->info
.cap_insn_unit
= 1;
410 s
->info
.cap_insn_split
= 8;
411 #elif defined(__x86_64__)
412 s
->info
.mach
= bfd_mach_x86_64
;
413 s
->info
.print_insn
= print_insn_i386
;
414 s
->info
.cap_arch
= CS_ARCH_X86
;
415 s
->info
.cap_mode
= CS_MODE_64
;
416 s
->info
.cap_insn_unit
= 1;
417 s
->info
.cap_insn_split
= 8;
418 #elif defined(_ARCH_PPC)
419 s
->info
.disassembler_options
= (char *)"any";
420 s
->info
.print_insn
= print_insn_ppc
;
421 s
->info
.cap_arch
= CS_ARCH_PPC
;
423 s
->info
.cap_mode
= CS_MODE_64
;
425 #elif defined(__riscv) && defined(CONFIG_RISCV_DIS)
426 #if defined(_ILP32) || (__riscv_xlen == 32)
427 s
->info
.print_insn
= print_insn_riscv32
;
429 s
->info
.print_insn
= print_insn_riscv64
;
431 #error unsupported RISC-V ABI
433 #elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS)
434 s
->info
.print_insn
= print_insn_arm_a64
;
435 s
->info
.cap_arch
= CS_ARCH_ARM64
;
436 #elif defined(__alpha__)
437 s
->info
.print_insn
= print_insn_alpha
;
438 #elif defined(__sparc__)
439 s
->info
.print_insn
= print_insn_sparc
;
440 s
->info
.mach
= bfd_mach_sparc_v9b
;
441 #elif defined(__arm__)
442 /* TCG only generates code for arm mode. */
443 s
->info
.print_insn
= print_insn_arm
;
444 s
->info
.cap_arch
= CS_ARCH_ARM
;
445 #elif defined(__MIPSEB__)
446 s
->info
.print_insn
= print_insn_big_mips
;
447 #elif defined(__MIPSEL__)
448 s
->info
.print_insn
= print_insn_little_mips
;
449 #elif defined(__m68k__)
450 s
->info
.print_insn
= print_insn_m68k
;
451 #elif defined(__s390__)
452 s
->info
.print_insn
= print_insn_s390
;
453 #elif defined(__hppa__)
454 s
->info
.print_insn
= print_insn_hppa
;
458 /* Disassemble this for me please... (debugging). */
459 void target_disas(FILE *out
, CPUState
*cpu
, target_ulong code
,
466 initialize_debug_target(&s
, cpu
);
467 s
.info
.fprintf_func
= fprintf
;
469 s
.info
.buffer_vma
= code
;
470 s
.info
.buffer_length
= size
;
472 if (s
.info
.cap_arch
>= 0 && cap_disas_target(&s
.info
, code
, size
)) {
476 if (s
.info
.print_insn
== NULL
) {
477 s
.info
.print_insn
= print_insn_od_target
;
480 for (pc
= code
; size
> 0; pc
+= count
, size
-= count
) {
481 fprintf(out
, "0x" TARGET_FMT_lx
": ", pc
);
482 count
= s
.info
.print_insn(pc
, &s
.info
);
488 "Disassembler disagrees with translator over instruction "
490 "Please report this to qemu-devel@nongnu.org\n");
496 static __thread GString plugin_disas_output
;
498 static int plugin_printf(FILE *stream
, const char *fmt
, ...)
501 GString
*s
= &plugin_disas_output
;
502 int initial_len
= s
->len
;
505 g_string_append_vprintf(s
, fmt
, va
);
508 return s
->len
- initial_len
;
511 static void plugin_print_address(bfd_vma addr
, struct disassemble_info
*info
)
517 #ifdef CONFIG_CAPSTONE
518 /* Disassemble a single instruction directly into plugin output */
520 bool cap_disas_plugin(disassemble_info
*info
, uint64_t pc
, size_t size
)
522 uint8_t cap_buf
[1024];
527 GString
*s
= &plugin_disas_output
;
529 if (cap_disas_start(info
, &handle
) != CS_ERR_OK
) {
534 size_t tsize
= MIN(sizeof(cap_buf
) - csize
, size
);
535 const uint8_t *cbuf
= cap_buf
;
536 target_read_memory(pc
, cap_buf
, tsize
, info
);
538 count
= cs_disasm(handle
, cbuf
, size
, 0, 1, &insn
);
541 g_string_printf(s
, "%s %s", insn
->mnemonic
, insn
->op_str
);
543 g_string_printf(s
, "cs_disasm failed");
552 * We should only be dissembling one instruction at a time here. If
553 * there is left over it usually indicates the front end has read more
554 * bytes than it needed.
556 char *plugin_disas(CPUState
*cpu
, uint64_t addr
, size_t size
)
560 GString
*ds
= g_string_set_size(&plugin_disas_output
, 0);
562 g_assert(ds
== &plugin_disas_output
);
564 initialize_debug_target(&s
, cpu
);
565 s
.info
.fprintf_func
= plugin_printf
;
566 s
.info
.buffer_vma
= addr
;
567 s
.info
.buffer_length
= size
;
568 s
.info
.print_address_func
= plugin_print_address
;
570 if (s
.info
.cap_arch
>= 0 && cap_disas_plugin(&s
.info
, addr
, size
)) {
571 return g_strdup(ds
->str
);
574 if (s
.info
.print_insn
== NULL
) {
575 s
.info
.print_insn
= print_insn_od_target
;
578 count
= s
.info
.print_insn(addr
, &s
.info
);
580 /* The decoder probably read more than it needed it's not critical */
582 warn_report("%s: %zu bytes left over", __func__
, size
- count
);
585 return g_strdup(ds
->str
);
588 /* Disassemble this for me please... (debugging). */
589 void disas(FILE *out
, void *code
, unsigned long size
)
595 initialize_debug_host(&s
);
596 s
.info
.fprintf_func
= fprintf
;
598 s
.info
.buffer
= code
;
599 s
.info
.buffer_vma
= (uintptr_t)code
;
600 s
.info
.buffer_length
= size
;
602 if (s
.info
.cap_arch
>= 0 && cap_disas_host(&s
.info
, code
, size
)) {
606 if (s
.info
.print_insn
== NULL
) {
607 s
.info
.print_insn
= print_insn_od_host
;
609 for (pc
= (uintptr_t)code
; size
> 0; pc
+= count
, size
-= count
) {
610 fprintf(out
, "0x%08" PRIxPTR
": ", pc
);
611 count
= s
.info
.print_insn(pc
, &s
.info
);
620 /* Look up symbol for debugging purpose. Returns "" if unknown. */
621 const char *lookup_symbol(target_ulong orig_addr
)
623 const char *symbol
= "";
626 for (s
= syminfos
; s
; s
= s
->next
) {
627 symbol
= s
->lookup_symbol(s
, orig_addr
);
628 if (symbol
[0] != '\0') {
636 #if !defined(CONFIG_USER_ONLY)
638 #include "monitor/monitor.h"
641 physical_read_memory(bfd_vma memaddr
, bfd_byte
*myaddr
, int length
,
642 struct disassemble_info
*info
)
644 CPUDebug
*s
= container_of(info
, CPUDebug
, info
);
647 res
= address_space_read(s
->cpu
->as
, memaddr
, MEMTXATTRS_UNSPECIFIED
,
649 return res
== MEMTX_OK
? 0 : EIO
;
652 /* Disassembler for the monitor. */
653 void monitor_disas(Monitor
*mon
, CPUState
*cpu
,
654 target_ulong pc
, int nb_insn
, int is_physical
)
659 initialize_debug_target(&s
, cpu
);
660 s
.info
.fprintf_func
= qemu_fprintf
;
662 s
.info
.read_memory_func
= physical_read_memory
;
664 s
.info
.buffer_vma
= pc
;
666 if (s
.info
.cap_arch
>= 0 && cap_disas_monitor(&s
.info
, pc
, nb_insn
)) {
670 if (!s
.info
.print_insn
) {
671 monitor_printf(mon
, "0x" TARGET_FMT_lx
672 ": Asm output not supported on this arch\n", pc
);
676 for(i
= 0; i
< nb_insn
; i
++) {
677 monitor_printf(mon
, "0x" TARGET_FMT_lx
": ", pc
);
678 count
= s
.info
.print_insn(pc
, &s
.info
);
679 monitor_printf(mon
, "\n");