18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* General "disassemble this chunk" code.  Used for debugging. */
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "config.h"
3cc33b2d8035092608c7cba4154e9c44452727e1bDavid 'Digit' Turner#include "disas/bfd.h"
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "elf.h"
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h"
8cc33b2d8035092608c7cba4154e9c44452727e1bDavid 'Digit' Turner#include "disas/disas.h"
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
100dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnertypedef struct CPUDebug {
110dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    struct disassemble_info info;
12e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turner    CPUArchState *env;
130dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner} CPUDebug;
140dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Filled in by elfload.c.  Simplistic, but will do for now. */
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct syminfo *syminfos = NULL;
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Get LENGTH bytes from info's buffer, at target address memaddr.
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Transfer them to myaddr.  */
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerbuffer_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   struct disassemble_info *info)
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (memaddr < info->buffer_vma
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        || memaddr + length > info->buffer_vma + info->buffer_length)
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Out of bounds.  Use EIO because GDB uses it.  */
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return EIO;
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Get LENGTH bytes from info's buffer, at target address memaddr.
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Transfer them to myaddr.  */
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttarget_read_memory (bfd_vma memaddr,
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    bfd_byte *myaddr,
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int length,
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    struct disassemble_info *info)
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
400dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    CPUDebug *s = container_of(info, CPUDebug, info);
410dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
42aaef275467ba13162d52ef6f690fd97f9733eb58David 'Digit' Turner    cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Print an error message.  We can assume that this is in response to
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   an error return from buffer_read_memory.  */
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerperror_memory (int status, bfd_vma memaddr, struct disassemble_info *info)
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (status != EIO)
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Can't happen.  */
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  else
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Actually, address between memaddr and memaddr + len was
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       out of bounds.  */
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (*info->fprintf_func) (info->stream,
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			   "Address 0x%" PRIx64 " is out of bounds.\n", memaddr);
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
610dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner/* This could be in a separate file, to save minuscule amounts of space
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   in statically linked executables.  */
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Just print the address is hex.  This is included for completeness even
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   though both GDB and objdump provide their own (to print symbolic
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   addresses).  */
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnergeneric_print_address (bfd_vma addr, struct disassemble_info *info)
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
740dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner/* Print address in hex, truncated to the width of a target virtual address. */
750dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnerstatic void
760dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnergeneric_print_target_address(bfd_vma addr, struct disassemble_info *info)
770dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner{
780dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    uint64_t mask = ~0ULL >> (64 - TARGET_VIRT_ADDR_SPACE_BITS);
790dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    generic_print_address(addr & mask, info);
800dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner}
810dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
820dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner/* Print address in hex, truncated to the width of a host virtual address. */
830dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnerstatic void
840dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnergeneric_print_host_address(bfd_vma addr, struct disassemble_info *info)
850dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner{
860dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    uint64_t mask = ~0ULL >> (64 - (sizeof(void *) * 8));
870dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    generic_print_address(addr & mask, info);
880dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner}
890dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Just return the given address.  */
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnergeneric_symbol_at_address (bfd_vma addr, struct disassemble_info *info)
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return 1;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9875fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turnerbfd_vma bfd_getl64 (const bfd_byte *addr)
9975fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner{
10075fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  unsigned long long v;
10175fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner
10275fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v = (unsigned long long) addr[0];
10375fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[1] << 8;
10475fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[2] << 16;
10575fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[3] << 24;
10675fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[4] << 32;
10775fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[5] << 40;
10875fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[6] << 48;
10975fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  v |= (unsigned long long) addr[7] << 56;
11075fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner  return (bfd_vma) v;
11175fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner}
11275fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbfd_vma bfd_getl32 (const bfd_byte *addr)
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  unsigned long v;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v = (unsigned long) addr[0];
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[1] << 8;
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[2] << 16;
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[3] << 24;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return (bfd_vma) v;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbfd_vma bfd_getb32 (const bfd_byte *addr)
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  unsigned long v;
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v = (unsigned long) addr[0] << 24;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[1] << 16;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[2] << 8;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[3];
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return (bfd_vma) v;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbfd_vma bfd_getl16 (const bfd_byte *addr)
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  unsigned long v;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v = (unsigned long) addr[0];
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[1] << 8;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return (bfd_vma) v;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbfd_vma bfd_getb16 (const bfd_byte *addr)
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  unsigned long v;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v = (unsigned long) addr[0] << 24;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  v |= (unsigned long) addr[1] << 16;
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return (bfd_vma) v;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_ARM
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectprint_insn_thumb1(bfd_vma pc, disassemble_info *info)
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return print_insn_arm(pc | 1, info);
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1610dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnerstatic int print_insn_objdump(bfd_vma pc, disassemble_info *info,
1620dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner                              const char *prefix)
1630dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner{
1640dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    int i, n = info->buffer_length;
1650dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    uint8_t *buf = g_malloc(n);
1660dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
1670dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    info->read_memory_func(pc, buf, n, info);
1680dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
1690dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    for (i = 0; i < n; ++i) {
1700dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        if (i % 32 == 0) {
1710dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner            info->fprintf_func(info->stream, "\n%s: ", prefix);
1720dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        }
1730dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        info->fprintf_func(info->stream, "%02x", buf[i]);
1740dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
1750dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
1760dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    g_free(buf);
1770dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    return n;
1780dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner}
1790dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
1800dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnerstatic int print_insn_od_host(bfd_vma pc, disassemble_info *info)
1810dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner{
1820dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    return print_insn_objdump(pc, info, "OBJD-H");
1830dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner}
1840dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
1850dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turnerstatic int print_insn_od_target(bfd_vma pc, disassemble_info *info)
1860dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner{
1870dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    return print_insn_objdump(pc, info, "OBJD-T");
1880dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner}
1890dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Disassemble this for me please... (debugging). 'flags' has the following
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   values:
1920dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    i386 - 1 means 16 bit code, 2 means 64 bit code
1930dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    arm  - bit 0 = thumb, bit 1 = reverse endian
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ppc  - nonzero means little endian
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    other targets - unused
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
197e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnervoid target_disas(FILE *out, CPUArchState *env, target_ulong code,
1980dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner                  target_ulong size, int flags)
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong pc;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int count;
2020dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    CPUDebug s;
2030dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2050dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2070dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.env = env;
2080dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.read_memory_func = target_read_memory;
2090dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.buffer_vma = code;
2100dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.buffer_length = size;
2110dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.print_address_func = generic_print_target_address;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_WORDS_BIGENDIAN
2140dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.endian = BFD_ENDIAN_BIG;
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2160dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.endian = BFD_ENDIAN_LITTLE;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
2190dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (flags == 2) {
2200dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_x86_64;
2210dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    } else if (flags == 1) {
2220dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_i386_i8086;
2230dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    } else {
2240dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_i386_i386;
2250dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_i386;
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
2280dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (flags & 1) {
2290dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        print_insn = print_insn_thumb1;
2300dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    } else {
2310dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        print_insn = print_insn_arm;
2320dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
2330dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (flags & 2) {
2340dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#ifdef TARGET_WORDS_BIGENDIAN
2350dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.endian = BFD_ENDIAN_LITTLE;
2360dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#else
2370dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.endian = BFD_ENDIAN_BIG;
2380dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#endif
2390dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_sparc;
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_SPARC64
2430dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_sparc_v9b;
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
2460dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (flags >> 16) {
2470dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.endian = BFD_ENDIAN_LITTLE;
2480dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (flags & 0xFFFF) {
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* If we have a precise definitions of the instructions set, use it */
2510dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = flags & 0xFFFF;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_PPC64
2540dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_ppc64;
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2560dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_ppc;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2590dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.disassembler_options = (char *)"any";
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_ppc;
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_m68k;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_WORDS_BIGENDIAN
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_big_mips;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_little_mips;
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
2700dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_sh4;
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_sh;
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
2730dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_alpha_ev6;
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_alpha;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
2769f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner    if (flags != 32) {
2770dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_cris_v0_v10;
2789f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner        print_insn = print_insn_crisv10;
2799f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner    } else {
2800dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_cris_v32;
2810dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        print_insn = print_insn_crisv32;
2829f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner    }
2839f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner#elif defined(TARGET_S390X)
2840dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_s390_64;
2859f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner    print_insn = print_insn_s390;
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(TARGET_MICROBLAZE)
2870dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_arch_microblaze;
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    print_insn = print_insn_microblaze;
2890dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#elif defined(TARGET_MOXIE)
2900dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_arch_moxie;
2910dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    print_insn = print_insn_moxie;
2920dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#elif defined(TARGET_LM32)
2930dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_lm32;
2940dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    print_insn = print_insn_lm32;
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2960dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (print_insn == NULL) {
2970dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        print_insn = print_insn_od_target;
2980dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (pc = code; size > 0; pc += count, size -= count) {
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
3020dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner	count = print_insn(pc, &s.info);
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int i;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint8_t b;
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(out, " {");
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < count; i++) {
3090dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner                target_read_memory(pc + i, &b, 1, &s.info);
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(out, " %02x", b);
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(out, " }");
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	fprintf(out, "\n");
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (count < 0)
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    break;
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (size < count) {
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(out,
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "Disassembler disagrees with translator over instruction "
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "decoding\n"
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "Please report this to qemu-devel@nongnu.org\n");
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Disassemble this for me please... (debugging). */
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid disas(FILE *out, void *code, unsigned long size)
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3310dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    uintptr_t pc;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int count;
3330dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    CPUDebug s;
3340dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3360dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
3370dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.print_address_func = generic_print_host_address;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3390dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.buffer = code;
3400dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.buffer_vma = (uintptr_t)code;
3410dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.buffer_length = size;
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34320894ae3fa98f82da925fbeb72e616eef509758aDavid 'Digit' Turner#ifdef HOST_WORDS_BIGENDIAN
3440dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.endian = BFD_ENDIAN_BIG;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3460dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.endian = BFD_ENDIAN_LITTLE;
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3480dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER)
3490dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    print_insn = print_insn_tci;
3500dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#elif defined(__i386__)
3510dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_i386_i386;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_i386;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__x86_64__)
3540dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_x86_64;
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_i386;
3565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(_ARCH_PPC)
3570dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.disassembler_options = (char *)"any";
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_ppc;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__alpha__)
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_alpha;
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__sparc__)
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_sparc;
3630dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_sparc_v9b;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__arm__)
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_arm;
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__MIPSEB__)
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_big_mips;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__MIPSEL__)
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_little_mips;
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__m68k__)
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_m68k;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__s390__)
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_s390;
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__hppa__)
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_hppa;
37675fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner#elif defined(__ia64__)
37775fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner    print_insn = print_insn_ia64;
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3790dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (print_insn == NULL) {
3800dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        print_insn = print_insn_od_host;
3810dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
3820dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
3830dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        fprintf(out, "0x%08" PRIxPTR ":  ", pc);
3840dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        count = print_insn(pc, &s.info);
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	fprintf(out, "\n");
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (count < 0)
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    break;
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Look up symbol for debugging purpose.  Returns "" if unknown. */
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *lookup_symbol(target_ulong orig_addr)
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *symbol = "";
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct syminfo *s;
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (s = syminfos; s; s = s->next) {
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        symbol = s->lookup_symbol(s, orig_addr);
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (symbol[0] != '\0') {
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return symbol;
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(CONFIG_USER_ONLY)
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4096af6765e2f3bc930d0dce21d752bea570a1b1362David 'Digit' Turner#include "monitor/monitor.h"
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int monitor_disas_is_physical;
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectmonitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     struct disassemble_info *info)
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4170dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    CPUDebug *s = container_of(info, CPUDebug, info);
4180dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (monitor_disas_is_physical) {
4209f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner        cpu_physical_memory_read(memaddr, myaddr, length);
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
422aaef275467ba13162d52ef6f690fd97f9733eb58David 'Digit' Turner        cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr,myaddr, length, 0);
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4279f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turnerstatic int GCC_FMT_ATTR(2, 3)
4289f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turnermonitor_fprintf(FILE *stream, const char *fmt, ...)
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_list ap;
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(ap, fmt);
4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_vprintf((Monitor *)stream, fmt, ap);
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(ap);
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
437e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnervoid monitor_disas(Monitor *mon, CPUArchState *env,
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   target_ulong pc, int nb_insn, int is_physical, int flags)
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int count, i;
4410dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    CPUDebug s;
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int (*print_insn)(bfd_vma pc, disassemble_info *info);
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4440dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    INIT_DISASSEMBLE_INFO(s.info, (FILE *)mon, monitor_fprintf);
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4460dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.env = env;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    monitor_disas_is_physical = is_physical;
4480dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.read_memory_func = monitor_read_memory;
4490dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.print_address_func = generic_print_target_address;
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4510dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.buffer_vma = pc;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_WORDS_BIGENDIAN
4540dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.endian = BFD_ENDIAN_BIG;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4560dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.endian = BFD_ENDIAN_LITTLE;
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
4590dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    if (flags == 2) {
4600dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_x86_64;
4610dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    } else if (flags == 1) {
4620dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_i386_i8086;
4630dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    } else {
4640dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        s.info.mach = bfd_mach_i386_i386;
4650dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    }
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_i386;
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_arm;
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_alpha;
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_sparc;
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_SPARC64
4740dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_sparc_v9b;
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_PPC64
4780dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_ppc64;
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4800dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_ppc;
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_ppc;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_m68k;
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_WORDS_BIGENDIAN
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_big_mips;
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    print_insn = print_insn_little_mips;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
49175fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner#elif defined(TARGET_SH4)
4920dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_sh4;
49375fb4a08de4abce11ee7cf81bcddd5193eb0438dDavid Turner    print_insn = print_insn_sh;
4949f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner#elif defined(TARGET_S390X)
4950dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_s390_64;
4969f6401125dc88f4ae22cdd34c65bf1d4d57ca7e1David 'Digit' Turner    print_insn = print_insn_s390;
4970dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#elif defined(TARGET_MOXIE)
4980dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_arch_moxie;
4990dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    print_insn = print_insn_moxie;
5000dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner#elif defined(TARGET_LM32)
5010dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    s.info.mach = bfd_mach_lm32;
5020dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner    print_insn = print_insn_lm32;
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_printf(mon, "0x" TARGET_FMT_lx
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   ": Asm output not supported on this arch\n", pc);
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return;
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_insn; i++) {
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	monitor_printf(mon, "0x" TARGET_FMT_lx ":  ", pc);
5110dc43a9a7d4ed798d2c53792fe30a907f81d7615David 'Digit' Turner        count = print_insn(pc, &s.info);
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	monitor_printf(mon, "\n");
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (count < 0)
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    break;
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pc += count;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
519