/*
 * gdb server stub - softmmu specific bits
 *
 * Debug integration depends on support from the individual
 * accelerators so most of this involves calling the ops helpers.
 *
 * Copyright (c) 2003-2005 Fabrice Bellard
 * Copyright (c) 2022 Linaro Ltd
 *
 * SPDX-License-Identifier: LGPL-2.0+
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
#include "exec/gdbstub.h"
#include "gdbstub/syscalls.h"
#include "exec/hwaddr.h"
#include "exec/tb-flush.h"
#include "sysemu/cpus.h"
#include "sysemu/runstate.h"
#include "sysemu/replay.h"
#include "hw/core/cpu.h"
#include "hw/cpu/cluster.h"
#include "hw/boards.h"
#include "chardev/char.h"
#include "chardev/char-fe.h"
#include "monitor/monitor.h"
#include "trace.h"
#include "internals.h"

/* System emulation specific state */
typedef struct {
    CharBackend chr;
    Chardev *mon_chr;
} GDBSystemState;

GDBSystemState gdbserver_system_state;

static void reset_gdbserver_state(void)
{
    g_free(gdbserver_state.processes);
    gdbserver_state.processes = NULL;
    gdbserver_state.process_num = 0;
    gdbserver_state.allow_stop_reply = false;
}

/*
 * Return the GDB index for a given vCPU state.
 *
 * In system mode GDB numbers CPUs from 1 as 0 is reserved as an "any
 * cpu" index.
 */
int gdb_get_cpu_index(CPUState *cpu)
{
    return cpu->cpu_index + 1;
}

/*
 * We check the status of the last message in the chardev receive code
 */
bool gdb_got_immediate_ack(void)
{
    return true;
}

/*
 * GDB Connection management. For system emulation we do all of this
 * via our existing Chardev infrastructure which allows us to support
 * network and unix sockets.
 */

void gdb_put_buffer(const uint8_t *buf, int len)
{
    /*
     * XXX this blocks entire thread. Rewrite to use
     * qemu_chr_fe_write and background I/O callbacks
     */
    qemu_chr_fe_write_all(&gdbserver_system_state.chr, buf, len);
}

static void gdb_chr_event(void *opaque, QEMUChrEvent event)
{
    int i;
    GDBState *s = (GDBState *) opaque;

    switch (event) {
    case CHR_EVENT_OPENED:
        /* Start with first process attached, others detached */
        for (i = 0; i < s->process_num; i++) {
            s->processes[i].attached = !i;
        }

        s->c_cpu = gdb_first_attached_cpu();
        s->g_cpu = s->c_cpu;

        vm_stop(RUN_STATE_PAUSED);
        replay_gdb_attached();
        break;
    default:
        break;
    }
}

/*
 * In softmmu mode we stop the VM and wait to send the syscall packet
 * until notification that the CPU has stopped. This must be done
 * because if the packet is sent now the reply from the syscall
 * request could be received while the CPU is still in the running
 * state, which can cause packets to be dropped and state transition
 * 'T' packets to be sent while the syscall is still being processed.
 */
void gdb_syscall_handling(const char *syscall_packet)
{
    vm_stop(RUN_STATE_DEBUG);
    qemu_cpu_kick(gdbserver_state.c_cpu);
}

static void gdb_vm_state_change(void *opaque, bool running, RunState state)
{
    CPUState *cpu = gdbserver_state.c_cpu;
    g_autoptr(GString) buf = g_string_new(NULL);
    g_autoptr(GString) tid = g_string_new(NULL);
    const char *type;
    int ret;

    if (running || gdbserver_state.state == RS_INACTIVE) {
        return;
    }

    /* Is there a GDB syscall waiting to be sent?  */
    if (gdb_handled_syscall()) {
        return;
    }

    if (cpu == NULL) {
        /* No process attached */
        return;
    }

    if (!gdbserver_state.allow_stop_reply) {
        return;
    }

    gdb_append_thread_id(cpu, tid);

    switch (state) {
    case RUN_STATE_DEBUG:
        if (cpu->watchpoint_hit) {
            switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
            case BP_MEM_READ:
                type = "r";
                break;
            case BP_MEM_ACCESS:
                type = "a";
                break;
            default:
                type = "";
                break;
            }
            trace_gdbstub_hit_watchpoint(type,
                                         gdb_get_cpu_index(cpu),
                                         cpu->watchpoint_hit->vaddr);
            g_string_printf(buf, "T%02xthread:%s;%swatch:%" VADDR_PRIx ";",
                            GDB_SIGNAL_TRAP, tid->str, type,
                            cpu->watchpoint_hit->vaddr);
            cpu->watchpoint_hit = NULL;
            goto send_packet;
        } else {
            trace_gdbstub_hit_break();
        }
        tb_flush(cpu);
        ret = GDB_SIGNAL_TRAP;
        break;
    case RUN_STATE_PAUSED:
        trace_gdbstub_hit_paused();
        ret = GDB_SIGNAL_INT;
        break;
    case RUN_STATE_SHUTDOWN:
        trace_gdbstub_hit_shutdown();
        ret = GDB_SIGNAL_QUIT;
        break;
    case RUN_STATE_IO_ERROR:
        trace_gdbstub_hit_io_error();
        ret = GDB_SIGNAL_IO;
        break;
    case RUN_STATE_WATCHDOG:
        trace_gdbstub_hit_watchdog();
        ret = GDB_SIGNAL_ALRM;
        break;
    case RUN_STATE_INTERNAL_ERROR:
        trace_gdbstub_hit_internal_error();
        ret = GDB_SIGNAL_ABRT;
        break;
    case RUN_STATE_SAVE_VM:
    case RUN_STATE_RESTORE_VM:
        return;
    case RUN_STATE_FINISH_MIGRATE:
        ret = GDB_SIGNAL_XCPU;
        break;
    default:
        trace_gdbstub_hit_unknown(state);
        ret = GDB_SIGNAL_UNKNOWN;
        break;
    }
    gdb_set_stop_cpu(cpu);
    g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);

send_packet:
    gdb_put_packet(buf->str);
    gdbserver_state.allow_stop_reply = false;

    /* disable single step if it was enabled */
    cpu_single_step(cpu, 0);
}

#ifndef _WIN32
static void gdb_sigterm_handler(int signal)
{
    if (runstate_is_running()) {
        vm_stop(RUN_STATE_PAUSED);
    }
}
#endif

static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
{
    g_autoptr(GString) hex_buf = g_string_new("O");
    gdb_memtohex(hex_buf, buf, len);
    gdb_put_packet(hex_buf->str);
    return len;
}

static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
                             bool *be_opened, Error **errp)
{
    *be_opened = false;
}

static void char_gdb_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->internal = true;
    cc->open = gdb_monitor_open;
    cc->chr_write = gdb_monitor_write;
}

#define TYPE_CHARDEV_GDB "chardev-gdb"

static const TypeInfo char_gdb_type_info = {
    .name = TYPE_CHARDEV_GDB,
    .parent = TYPE_CHARDEV,
    .class_init = char_gdb_class_init,
};

static int gdb_chr_can_receive(void *opaque)
{
  /*
   * We can handle an arbitrarily large amount of data.
   * Pick the maximum packet size, which is as good as anything.
   */
  return MAX_PACKET_LENGTH;
}

static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
{
    int i;

    for (i = 0; i < size; i++) {
        gdb_read_byte(buf[i]);
    }
}

static int find_cpu_clusters(Object *child, void *opaque)
{
    if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
        GDBState *s = (GDBState *) opaque;
        CPUClusterState *cluster = CPU_CLUSTER(child);
        GDBProcess *process;

        s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);

        process = &s->processes[s->process_num - 1];

        /*
         * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
         * runtime, we enforce here that the machine does not use a cluster ID
         * that would lead to PID 0.
         */
        assert(cluster->cluster_id != UINT32_MAX);
        process->pid = cluster->cluster_id + 1;
        process->attached = false;
        process->target_xml[0] = '\0';

        return 0;
    }

    return object_child_foreach(child, find_cpu_clusters, opaque);
}

static int pid_order(const void *a, const void *b)
{
    GDBProcess *pa = (GDBProcess *) a;
    GDBProcess *pb = (GDBProcess *) b;

    if (pa->pid < pb->pid) {
        return -1;
    } else if (pa->pid > pb->pid) {
        return 1;
    } else {
        return 0;
    }
}

static void create_processes(GDBState *s)
{
    object_child_foreach(object_get_root(), find_cpu_clusters, s);

    if (gdbserver_state.processes) {
        /* Sort by PID */
        qsort(gdbserver_state.processes,
              gdbserver_state.process_num,
              sizeof(gdbserver_state.processes[0]),
              pid_order);
    }

    gdb_create_default_process(s);
}

int gdbserver_start(const char *device)
{
    Chardev *chr = NULL;
    Chardev *mon_chr;
    g_autoptr(GString) cs = g_string_new(device);

    if (!first_cpu) {
        error_report("gdbstub: meaningless to attach gdb to a "
                     "machine without any CPU.");
        return -1;
    }

    if (!gdb_supports_guest_debug()) {
        error_report("gdbstub: current accelerator doesn't "
                     "support guest debugging");
        return -1;
    }

    if (cs->len == 0) {
        return -1;
    }

    trace_gdbstub_op_start(cs->str);

    if (g_strcmp0(cs->str, "none") != 0) {
        if (g_str_has_prefix(cs->str, "tcp:")) {
            /* enforce required TCP attributes */
            g_string_append_printf(cs, ",wait=off,nodelay=on,server=on");
        }
#ifndef _WIN32
        else if (strcmp(device, "stdio") == 0) {
            struct sigaction act;

            memset(&act, 0, sizeof(act));
            act.sa_handler = gdb_sigterm_handler;
            sigaction(SIGINT, &act, NULL);
        }
#endif
        /*
         * FIXME: it's a bit weird to allow using a mux chardev here
         * and implicitly setup a monitor. We may want to break this.
         */
        chr = qemu_chr_new_noreplay("gdb", cs->str, true, NULL);
        if (!chr) {
            return -1;
        }
    }

    if (!gdbserver_state.init) {
        gdb_init_gdbserver_state();

        qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);

        /* Initialize a monitor terminal for gdb */
        mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
                                   NULL, NULL, &error_abort);
        monitor_init_hmp(mon_chr, false, &error_abort);
    } else {
        qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
        mon_chr = gdbserver_system_state.mon_chr;
        reset_gdbserver_state();
    }

    create_processes(&gdbserver_state);

    if (chr) {
        qemu_chr_fe_init(&gdbserver_system_state.chr, chr, &error_abort);
        qemu_chr_fe_set_handlers(&gdbserver_system_state.chr,
                                 gdb_chr_can_receive,
                                 gdb_chr_receive, gdb_chr_event,
                                 NULL, &gdbserver_state, NULL, true);
    }
    gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
    gdbserver_system_state.mon_chr = mon_chr;
    gdb_syscall_reset();

    return 0;
}

static void register_types(void)
{
    type_register_static(&char_gdb_type_info);
}

type_init(register_types);

/* Tell the remote gdb that the process has exited.  */
void gdb_exit(int code)
{
    char buf[4];

    if (!gdbserver_state.init) {
        return;
    }

    trace_gdbstub_op_exiting((uint8_t)code);

    if (gdbserver_state.allow_stop_reply) {
        snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
        gdb_put_packet(buf);
        gdbserver_state.allow_stop_reply = false;
    }

    qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
}

/*
 * Memory access
 */
static int phy_memory_mode;

int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
                               uint8_t *buf, int len, bool is_write)
{
    CPUClass *cc;

    if (phy_memory_mode) {
        if (is_write) {
            cpu_physical_memory_write(addr, buf, len);
        } else {
            cpu_physical_memory_read(addr, buf, len);
        }
        return 0;
    }

    cc = CPU_GET_CLASS(cpu);
    if (cc->memory_rw_debug) {
        return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
    }

    return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
}

/*
 * cpu helpers
 */

unsigned int gdb_get_max_cpus(void)
{
    MachineState *ms = MACHINE(qdev_get_machine());
    return ms->smp.max_cpus;
}

bool gdb_can_reverse(void)
{
    return replay_mode == REPLAY_MODE_PLAY;
}

/*
 * Softmmu specific command helpers
 */

void gdb_handle_query_qemu_phy_mem_mode(GArray *params,
                                        void *user_ctx)
{
    g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
    gdb_put_strbuf();
}

void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
{
    if (!params->len) {
        gdb_put_packet("E22");
        return;
    }

    if (!get_param(params, 0)->val_ul) {
        phy_memory_mode = 0;
    } else {
        phy_memory_mode = 1;
    }
    gdb_put_packet("OK");
}

void gdb_handle_query_rcmd(GArray *params, void *user_ctx)
{
    const guint8 zero = 0;
    int len;

    if (!params->len) {
        gdb_put_packet("E22");
        return;
    }

    len = strlen(get_param(params, 0)->data);
    if (len % 2) {
        gdb_put_packet("E01");
        return;
    }

    g_assert(gdbserver_state.mem_buf->len == 0);
    len = len / 2;
    gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
    g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
    qemu_chr_be_write(gdbserver_system_state.mon_chr,
                      gdbserver_state.mem_buf->data,
                      gdbserver_state.mem_buf->len);
    gdb_put_packet("OK");
}

/*
 * Execution state helpers
 */

void gdb_handle_query_attached(GArray *params, void *user_ctx)
{
    gdb_put_packet("1");
}

void gdb_continue(void)
{
    if (!runstate_needs_reset()) {
        trace_gdbstub_op_continue();
        vm_start();
    }
}

/*
 * Resume execution, per CPU actions.
 */
int gdb_continue_partial(char *newstates)
{
    CPUState *cpu;
    int res = 0;
    int flag = 0;

    if (!runstate_needs_reset()) {
        bool step_requested = false;
        CPU_FOREACH(cpu) {
            if (newstates[cpu->cpu_index] == 's') {
                step_requested = true;
                break;
            }
        }

        if (vm_prepare_start(step_requested)) {
            return 0;
        }

        CPU_FOREACH(cpu) {
            switch (newstates[cpu->cpu_index]) {
            case 0:
            case 1:
                break; /* nothing to do here */
            case 's':
                trace_gdbstub_op_stepping(cpu->cpu_index);
                cpu_single_step(cpu, gdbserver_state.sstep_flags);
                cpu_resume(cpu);
                flag = 1;
                break;
            case 'c':
                trace_gdbstub_op_continue_cpu(cpu->cpu_index);
                cpu_resume(cpu);
                flag = 1;
                break;
            default:
                res = -1;
                break;
            }
        }
    }
    if (flag) {
        qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
    }
    return res;
}

/*
 * Signal Handling - in system mode we only need SIGINT and SIGTRAP; other
 * signals are not yet supported.
 */

enum {
    TARGET_SIGINT = 2,
    TARGET_SIGTRAP = 5
};

int gdb_signal_to_target(int sig)
{
    switch (sig) {
    case 2:
        return TARGET_SIGINT;
    case 5:
        return TARGET_SIGTRAP;
    default:
        return -1;
    }
}

/*
 * Break/Watch point helpers
 */

bool gdb_supports_guest_debug(void)
{
    const AccelOpsClass *ops = cpus_get_accel();
    if (ops->supports_guest_debug) {
        return ops->supports_guest_debug();
    }
    return false;
}

int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
{
    const AccelOpsClass *ops = cpus_get_accel();
    if (ops->insert_breakpoint) {
        return ops->insert_breakpoint(cs, type, addr, len);
    }
    return -ENOSYS;
}

int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
{
    const AccelOpsClass *ops = cpus_get_accel();
    if (ops->remove_breakpoint) {
        return ops->remove_breakpoint(cs, type, addr, len);
    }
    return -ENOSYS;
}

void gdb_breakpoint_remove_all(CPUState *cs)
{
    const AccelOpsClass *ops = cpus_get_accel();
    if (ops->remove_all_breakpoints) {
        ops->remove_all_breakpoints(cs);
    }
}
