/* General "disassemble this chunk" code.  Used for debugging. */
#include "qemu/osdep.h"
#include "disas/dis-asm.h"
#include "elf.h"
#include "qemu/qemu-print.h"

#include "disas/disas.h"
#include "disas/capstone.h"

typedef struct CPUDebug {
    struct disassemble_info info;
    CPUState *cpu;
} CPUDebug;

/* Filled in by elfload.c.  Simplistic, but will do for now. */
struct syminfo *syminfos = NULL;

/*
 * Get LENGTH bytes from info's buffer, at host address memaddr.
 * Transfer them to myaddr.
 */
static int host_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
                            struct disassemble_info *info)
{
    if (memaddr < info->buffer_vma
        || memaddr + length > info->buffer_vma + info->buffer_length) {
        /* Out of bounds.  Use EIO because GDB uses it.  */
        return EIO;
    }
    memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
    return 0;
}

/*
 * Get LENGTH bytes from info's buffer, at target address memaddr.
 * Transfer them to myaddr.
 */
static int target_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
                              struct disassemble_info *info)
{
    CPUDebug *s = container_of(info, CPUDebug, info);
    int r = cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
    return r ? EIO : 0;
}

/*
 * Print an error message.  We can assume that this is in response to
 * an error return from {host,target}_read_memory.
 */
static void perror_memory(int status, bfd_vma memaddr,
                          struct disassemble_info *info)
{
    if (status != EIO) {
        /* Can't happen.  */
        info->fprintf_func(info->stream, "Unknown error %d\n", status);
    } else {
        /* Address between memaddr and memaddr + len was out of bounds.  */
        info->fprintf_func(info->stream,
                           "Address 0x%" PRIx64 " is out of bounds.\n",
                           memaddr);
    }
}

/* Print address in hex. */
static void print_address(bfd_vma addr, struct disassemble_info *info)
{
    info->fprintf_func(info->stream, "0x%" PRIx64, addr);
}

/* Print address in hex, truncated to the width of a host virtual address. */
static void host_print_address(bfd_vma addr, struct disassemble_info *info)
{
    print_address((uintptr_t)addr, info);
}

/* Stub prevents some fruitless earching in optabs disassemblers. */
static int symbol_at_address(bfd_vma addr, struct disassemble_info *info)
{
    return 1;
}

static int print_insn_objdump(bfd_vma pc, disassemble_info *info,
                              const char *prefix)
{
    int i, n = info->buffer_length;
    uint8_t *buf = g_malloc(n);

    info->read_memory_func(pc, buf, n, info);

    for (i = 0; i < n; ++i) {
        if (i % 32 == 0) {
            info->fprintf_func(info->stream, "\n%s: ", prefix);
        }
        info->fprintf_func(info->stream, "%02x", buf[i]);
    }

    g_free(buf);
    return n;
}

static int print_insn_od_host(bfd_vma pc, disassemble_info *info)
{
    return print_insn_objdump(pc, info, "OBJD-H");
}

static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
{
    return print_insn_objdump(pc, info, "OBJD-T");
}

static void initialize_debug(CPUDebug *s)
{
    memset(s, 0, sizeof(*s));
    s->info.arch = bfd_arch_unknown;
    s->info.cap_arch = -1;
    s->info.cap_insn_unit = 4;
    s->info.cap_insn_split = 4;
    s->info.memory_error_func = perror_memory;
    s->info.symbol_at_address_func = symbol_at_address;
}

static void initialize_debug_target(CPUDebug *s, CPUState *cpu)
{
    initialize_debug(s);

    s->cpu = cpu;
    s->info.read_memory_func = target_read_memory;
    s->info.print_address_func = print_address;
#ifdef TARGET_WORDS_BIGENDIAN
    s->info.endian = BFD_ENDIAN_BIG;
#else
    s->info.endian = BFD_ENDIAN_LITTLE;
#endif

    CPUClass *cc = CPU_GET_CLASS(cpu);
    if (cc->disas_set_info) {
        cc->disas_set_info(cpu, &s->info);
    }
}

static void initialize_debug_host(CPUDebug *s)
{
    initialize_debug(s);

    s->info.read_memory_func = host_read_memory;
    s->info.print_address_func = host_print_address;
#ifdef HOST_WORDS_BIGENDIAN
    s->info.endian = BFD_ENDIAN_BIG;
#else
    s->info.endian = BFD_ENDIAN_LITTLE;
#endif
#if defined(CONFIG_TCG_INTERPRETER)
    s->info.print_insn = print_insn_tci;
#elif defined(__i386__)
    s->info.mach = bfd_mach_i386_i386;
    s->info.print_insn = print_insn_i386;
    s->info.cap_arch = CS_ARCH_X86;
    s->info.cap_mode = CS_MODE_32;
    s->info.cap_insn_unit = 1;
    s->info.cap_insn_split = 8;
#elif defined(__x86_64__)
    s->info.mach = bfd_mach_x86_64;
    s->info.print_insn = print_insn_i386;
    s->info.cap_arch = CS_ARCH_X86;
    s->info.cap_mode = CS_MODE_64;
    s->info.cap_insn_unit = 1;
    s->info.cap_insn_split = 8;
#elif defined(_ARCH_PPC)
    s->info.disassembler_options = (char *)"any";
    s->info.print_insn = print_insn_ppc;
    s->info.cap_arch = CS_ARCH_PPC;
# ifdef _ARCH_PPC64
    s->info.cap_mode = CS_MODE_64;
# endif
#elif defined(__riscv) && defined(CONFIG_RISCV_DIS)
#if defined(_ILP32) || (__riscv_xlen == 32)
    s->info.print_insn = print_insn_riscv32;
#elif defined(_LP64)
    s->info.print_insn = print_insn_riscv64;
#else
#error unsupported RISC-V ABI
#endif
#elif defined(__aarch64__)
    s->info.cap_arch = CS_ARCH_ARM64;
# ifdef CONFIG_ARM_A64_DIS
    s->info.print_insn = print_insn_arm_a64;
# endif
#elif defined(__alpha__)
    s->info.print_insn = print_insn_alpha;
#elif defined(__sparc__)
    s->info.print_insn = print_insn_sparc;
    s->info.mach = bfd_mach_sparc_v9b;
#elif defined(__arm__)
    /* TCG only generates code for arm mode.  */
    s->info.print_insn = print_insn_arm;
    s->info.cap_arch = CS_ARCH_ARM;
#elif defined(__MIPSEB__)
    s->info.print_insn = print_insn_big_mips;
#elif defined(__MIPSEL__)
    s->info.print_insn = print_insn_little_mips;
#elif defined(__m68k__)
    s->info.print_insn = print_insn_m68k;
#elif defined(__s390__)
    s->info.print_insn = print_insn_s390;
    s->info.cap_arch = CS_ARCH_SYSZ;
    s->info.cap_insn_unit = 2;
    s->info.cap_insn_split = 6;
#elif defined(__hppa__)
    s->info.print_insn = print_insn_hppa;
#endif
}

/* Disassemble this for me please... (debugging).  */
void target_disas(FILE *out, CPUState *cpu, target_ulong code,
                  target_ulong size)
{
    target_ulong pc;
    int count;
    CPUDebug s;

    initialize_debug_target(&s, cpu);
    s.info.fprintf_func = fprintf;
    s.info.stream = out;
    s.info.buffer_vma = code;
    s.info.buffer_length = size;

    if (s.info.cap_arch >= 0 && cap_disas_target(&s.info, code, size)) {
        return;
    }

    if (s.info.print_insn == NULL) {
        s.info.print_insn = print_insn_od_target;
    }

    for (pc = code; size > 0; pc += count, size -= count) {
	fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
	count = s.info.print_insn(pc, &s.info);
	fprintf(out, "\n");
	if (count < 0)
	    break;
        if (size < count) {
            fprintf(out,
                    "Disassembler disagrees with translator over instruction "
                    "decoding\n"
                    "Please report this to qemu-devel@nongnu.org\n");
            break;
        }
    }
}

static int plugin_printf(FILE *stream, const char *fmt, ...)
{
    /* We abuse the FILE parameter to pass a GString. */
    GString *s = (GString *)stream;
    int initial_len = s->len;
    va_list va;

    va_start(va, fmt);
    g_string_append_vprintf(s, fmt, va);
    va_end(va);

    return s->len - initial_len;
}

static void plugin_print_address(bfd_vma addr, struct disassemble_info *info)
{
    /* does nothing */
}


/*
 * We should only be dissembling one instruction at a time here. If
 * there is left over it usually indicates the front end has read more
 * bytes than it needed.
 */
char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
{
    CPUDebug s;
    GString *ds = g_string_new(NULL);

    initialize_debug_target(&s, cpu);
    s.info.fprintf_func = plugin_printf;
    s.info.stream = (FILE *)ds;  /* abuse this slot */
    s.info.buffer_vma = addr;
    s.info.buffer_length = size;
    s.info.print_address_func = plugin_print_address;

    if (s.info.cap_arch >= 0 && cap_disas_plugin(&s.info, addr, size)) {
        ; /* done */
    } else if (s.info.print_insn) {
        s.info.print_insn(addr, &s.info);
    } else {
        ; /* cannot disassemble -- return empty string */
    }

    /* Return the buffer, freeing the GString container.  */
    return g_string_free(ds, false);
}

/* Disassemble this for me please... (debugging). */
void disas(FILE *out, const void *code, unsigned long size)
{
    uintptr_t pc;
    int count;
    CPUDebug s;

    initialize_debug_host(&s);
    s.info.fprintf_func = fprintf;
    s.info.stream = out;
    s.info.buffer = code;
    s.info.buffer_vma = (uintptr_t)code;
    s.info.buffer_length = size;

    if (s.info.cap_arch >= 0 && cap_disas_host(&s.info, code, size)) {
        return;
    }

    if (s.info.print_insn == NULL) {
        s.info.print_insn = print_insn_od_host;
    }
    for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
        fprintf(out, "0x%08" PRIxPTR ":  ", pc);
        count = s.info.print_insn(pc, &s.info);
        fprintf(out, "\n");
        if (count < 0) {
            break;
        }
    }

}

/* Look up symbol for debugging purpose.  Returns "" if unknown. */
const char *lookup_symbol(target_ulong orig_addr)
{
    const char *symbol = "";
    struct syminfo *s;

    for (s = syminfos; s; s = s->next) {
        symbol = s->lookup_symbol(s, orig_addr);
        if (symbol[0] != '\0') {
            break;
        }
    }

    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,
                   target_ulong pc, int nb_insn, int is_physical)
{
    int count, i;
    CPUDebug s;

    initialize_debug_target(&s, cpu);
    s.info.fprintf_func = qemu_fprintf;
    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)) {
        return;
    }

    if (!s.info.print_insn) {
        monitor_printf(mon, "0x" TARGET_FMT_lx
                       ": Asm output not supported on this arch\n", pc);
        return;
    }

    for(i = 0; i < nb_insn; i++) {
	monitor_printf(mon, "0x" TARGET_FMT_lx ":  ", pc);
        count = s.info.print_insn(pc, &s.info);
	monitor_printf(mon, "\n");
	if (count < 0)
	    break;
        pc += count;
    }
}
#endif
