/*
 * gdbstub user-mode helper routines.
 *
 * We know for user-mode we are using TCG so we can call stuff directly.
 *
 * Copyright (c) 2003-2005 Fabrice Bellard
 * Copyright (c) 2022 Linaro Ltd
 *
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/cutils.h"
#include "qemu/sockets.h"
#include "exec/hwaddr.h"
#include "exec/tb-flush.h"
#include "exec/gdbstub.h"
#include "gdbstub/commands.h"
#include "gdbstub/syscalls.h"
#include "gdbstub/user.h"
#include "gdbstub/enums.h"
#include "hw/core/cpu.h"
#include "trace.h"
#include "internals.h"

#define GDB_NR_SYSCALLS 1024
typedef unsigned long GDBSyscallsMask[BITS_TO_LONGS(GDB_NR_SYSCALLS)];

/*
 * Forked child talks to its parent in order to let GDB enforce the
 * follow-fork-mode. This happens inside a start_exclusive() section, so that
 * the other threads, which may be forking too, do not interfere. The
 * implementation relies on GDB not sending $vCont until it has detached
 * either from the parent (follow-fork-mode child) or from the child
 * (follow-fork-mode parent).
 *
 * The parent and the child share the GDB socket; at any given time only one
 * of them is allowed to use it, as is reflected in the respective fork_state.
 * This is negotiated via the fork_sockets pair as a reaction to $Hg.
 *
 * Below is a short summary of the possible state transitions:
 *
 *     ENABLED                     : Terminal state.
 *     DISABLED                    : Terminal state.
 *     ACTIVE                      : Parent initial state.
 *     INACTIVE                    : Child initial state.
 *     ACTIVE       -> DEACTIVATING: On $Hg.
 *     ACTIVE       -> ENABLING    : On $D.
 *     ACTIVE       -> DISABLING   : On $D.
 *     ACTIVE       -> DISABLED    : On communication error.
 *     DEACTIVATING -> INACTIVE    : On gdb_read_byte() return.
 *     DEACTIVATING -> DISABLED    : On communication error.
 *     INACTIVE     -> ACTIVE      : On $Hg in the peer.
 *     INACTIVE     -> ENABLE      : On $D in the peer.
 *     INACTIVE     -> DISABLE     : On $D in the peer.
 *     INACTIVE     -> DISABLED    : On communication error.
 *     ENABLING     -> ENABLED     : On gdb_read_byte() return.
 *     ENABLING     -> DISABLED    : On communication error.
 *     DISABLING    -> DISABLED    : On gdb_read_byte() return.
 */
enum GDBForkState {
    /* Fully owning the GDB socket. */
    GDB_FORK_ENABLED,
    /* Working with the GDB socket; the peer is inactive. */
    GDB_FORK_ACTIVE,
    /* Handing off the GDB socket to the peer. */
    GDB_FORK_DEACTIVATING,
    /* The peer is working with the GDB socket. */
    GDB_FORK_INACTIVE,
    /* Asking the peer to close its GDB socket fd. */
    GDB_FORK_ENABLING,
    /* Asking the peer to take over, closing our GDB socket fd. */
    GDB_FORK_DISABLING,
    /* The peer has taken over, our GDB socket fd is closed. */
    GDB_FORK_DISABLED,
};

enum GDBForkMessage {
    GDB_FORK_ACTIVATE = 'a',
    GDB_FORK_ENABLE = 'e',
    GDB_FORK_DISABLE = 'd',
};

/* User-mode specific state */
typedef struct {
    int fd;
    char *socket_path;
    int running_state;
    /*
     * Store syscalls mask without memory allocation in order to avoid
     * implementing synchronization.
     */
    bool catch_all_syscalls;
    GDBSyscallsMask catch_syscalls_mask;
    bool fork_events;
    enum GDBForkState fork_state;
    int fork_sockets[2];
    pid_t fork_peer_pid, fork_peer_tid;
    uint8_t siginfo[MAX_SIGINFO_LENGTH];
    unsigned long siginfo_len;
} GDBUserState;

static GDBUserState gdbserver_user_state;

int gdb_get_char(void)
{
    uint8_t ch;
    int ret;

    for (;;) {
        ret = recv(gdbserver_user_state.fd, &ch, 1, 0);
        if (ret < 0) {
            if (errno == ECONNRESET) {
                gdbserver_user_state.fd = -1;
            }
            if (errno != EINTR) {
                return -1;
            }
        } else if (ret == 0) {
            close(gdbserver_user_state.fd);
            gdbserver_user_state.fd = -1;
            return -1;
        } else {
            break;
        }
    }
    return ch;
}

bool gdb_got_immediate_ack(void)
{
    int i;

    i = gdb_get_char();
    if (i < 0) {
        /* no response, continue anyway */
        return true;
    }

    if (i == '+') {
        /* received correctly, continue */
        return true;
    }

    /* anything else, including '-' then try again */
    return false;
}

void gdb_put_buffer(const uint8_t *buf, int len)
{
    int ret;

    while (len > 0) {
        ret = send(gdbserver_user_state.fd, buf, len, 0);
        if (ret < 0) {
            if (errno != EINTR) {
                return;
            }
        } else {
            buf += ret;
            len -= ret;
        }
    }
}

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

    if (!gdbserver_state.init) {
        return;
    }
    if (gdbserver_user_state.socket_path) {
        unlink(gdbserver_user_state.socket_path);
    }
    if (gdbserver_user_state.fd < 0) {
        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;
    }

}

void gdb_qemu_exit(int code)
{
    exit(code);
}

int gdb_handlesig(CPUState *cpu, int sig, const char *reason, void *siginfo,
                  int siginfo_len)
{
    char buf[256];
    int n;

    if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
        return sig;
    }

    if (siginfo) {
        /*
         * Save target-specific siginfo.
         *
         * siginfo size, i.e. siginfo_len, is asserted at compile-time to fit in
         * gdbserver_user_state.siginfo, usually in the source file calling
         * gdb_handlesig. See, for instance, {linux,bsd}-user/signal.c.
         */
        memcpy(gdbserver_user_state.siginfo, siginfo, siginfo_len);
        gdbserver_user_state.siginfo_len = siginfo_len;
    }

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

    if (sig != 0) {
        gdb_set_stop_cpu(cpu);
        if (gdbserver_state.allow_stop_reply) {
            g_string_printf(gdbserver_state.str_buf,
                            "T%02xthread:", gdb_target_signal_to_gdb(sig));
            gdb_append_thread_id(cpu, gdbserver_state.str_buf);
            g_string_append_c(gdbserver_state.str_buf, ';');
            if (reason) {
                g_string_append(gdbserver_state.str_buf, reason);
            }
            gdb_put_strbuf();
            gdbserver_state.allow_stop_reply = false;
        }
    }
    /*
     * gdb_put_packet() might have detected that the peer terminated the
     * connection.
     */
    if (gdbserver_user_state.fd < 0) {
        return sig;
    }

    sig = 0;
    gdbserver_state.state = RS_IDLE;
    gdbserver_user_state.running_state = 0;
    while (gdbserver_user_state.running_state == 0) {
        n = read(gdbserver_user_state.fd, buf, 256);
        if (n > 0) {
            int i;

            for (i = 0; i < n; i++) {
                gdb_read_byte(buf[i]);
            }
        } else {
            /*
             * XXX: Connection closed.  Should probably wait for another
             * connection before continuing.
             */
            if (n == 0) {
                close(gdbserver_user_state.fd);
            }
            gdbserver_user_state.fd = -1;
            return sig;
        }
    }
    sig = gdbserver_state.signal;
    gdbserver_state.signal = 0;
    return sig;
}

/* Tell the remote gdb that the process has exited due to SIG.  */
void gdb_signalled(CPUArchState *env, int sig)
{
    char buf[4];

    if (!gdbserver_state.init || gdbserver_user_state.fd < 0 ||
        !gdbserver_state.allow_stop_reply) {
        return;
    }

    snprintf(buf, sizeof(buf), "X%02x", gdb_target_signal_to_gdb(sig));
    gdb_put_packet(buf);
    gdbserver_state.allow_stop_reply = false;
}

static void gdb_accept_init(int fd)
{
    gdb_init_gdbserver_state();
    gdb_create_default_process(&gdbserver_state);
    gdbserver_state.processes[0].attached = true;
    gdbserver_state.c_cpu = gdb_first_attached_cpu();
    gdbserver_state.g_cpu = gdbserver_state.c_cpu;
    gdbserver_user_state.fd = fd;
}

static bool gdb_accept_socket(int gdb_fd)
{
    int fd;

    for (;;) {
        fd = accept(gdb_fd, NULL, NULL);
        if (fd < 0 && errno != EINTR) {
            perror("accept socket");
            return false;
        } else if (fd >= 0) {
            qemu_set_cloexec(fd);
            break;
        }
    }

    gdb_accept_init(fd);
    return true;
}

static int gdbserver_open_socket(const char *path)
{
    struct sockaddr_un sockaddr = {};
    int fd, ret;

    fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("create socket");
        return -1;
    }

    sockaddr.sun_family = AF_UNIX;
    pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
    if (ret < 0) {
        perror("bind socket");
        close(fd);
        return -1;
    }
    ret = listen(fd, 1);
    if (ret < 0) {
        perror("listen socket");
        close(fd);
        return -1;
    }

    return fd;
}

static bool gdb_accept_tcp(int gdb_fd)
{
    struct sockaddr_in sockaddr = {};
    socklen_t len;
    int fd;

    for (;;) {
        len = sizeof(sockaddr);
        fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
        if (fd < 0 && errno != EINTR) {
            perror("accept");
            return false;
        } else if (fd >= 0) {
            qemu_set_cloexec(fd);
            break;
        }
    }

    /* set short latency */
    if (socket_set_nodelay(fd)) {
        perror("setsockopt");
        close(fd);
        return false;
    }

    gdb_accept_init(fd);
    return true;
}

static int gdbserver_open_port(int port)
{
    struct sockaddr_in sockaddr;
    int fd, ret;

    fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return -1;
    }
    qemu_set_cloexec(fd);

    socket_set_fast_reuse(fd);

    sockaddr.sin_family = AF_INET;
    sockaddr.sin_port = htons(port);
    sockaddr.sin_addr.s_addr = 0;
    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
    if (ret < 0) {
        perror("bind");
        close(fd);
        return -1;
    }
    ret = listen(fd, 1);
    if (ret < 0) {
        perror("listen");
        close(fd);
        return -1;
    }

    return fd;
}

int gdbserver_start(const char *port_or_path)
{
    int port = g_ascii_strtoull(port_or_path, NULL, 10);
    int gdb_fd;

    if (port > 0) {
        gdb_fd = gdbserver_open_port(port);
    } else {
        gdb_fd = gdbserver_open_socket(port_or_path);
    }

    if (gdb_fd < 0) {
        return -1;
    }

    if (port > 0 && gdb_accept_tcp(gdb_fd)) {
        return 0;
    } else if (gdb_accept_socket(gdb_fd)) {
        gdbserver_user_state.socket_path = g_strdup(port_or_path);
        return 0;
    }

    /* gone wrong */
    close(gdb_fd);
    return -1;
}

void gdbserver_fork_start(void)
{
    if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
        return;
    }
    if (!gdbserver_user_state.fork_events ||
            qemu_socketpair(AF_UNIX, SOCK_STREAM, 0,
                            gdbserver_user_state.fork_sockets) < 0) {
        gdbserver_user_state.fork_state = GDB_FORK_DISABLED;
        return;
    }
    gdbserver_user_state.fork_state = GDB_FORK_INACTIVE;
    gdbserver_user_state.fork_peer_pid = getpid();
    gdbserver_user_state.fork_peer_tid = qemu_get_thread_id();
}

static void disable_gdbstub(CPUState *thread_cpu)
{
    CPUState *cpu;

    close(gdbserver_user_state.fd);
    gdbserver_user_state.fd = -1;
    CPU_FOREACH(cpu) {
        cpu_breakpoint_remove_all(cpu, BP_GDB);
        /* no cpu_watchpoint_remove_all for user-mode */
        cpu_single_step(cpu, 0);
    }
    tb_flush(thread_cpu);
}

void gdbserver_fork_end(CPUState *cpu, pid_t pid)
{
    char b;
    int fd;

    if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
        return;
    }

    if (pid == -1) {
        if (gdbserver_user_state.fork_state != GDB_FORK_DISABLED) {
            g_assert(gdbserver_user_state.fork_state == GDB_FORK_INACTIVE);
            close(gdbserver_user_state.fork_sockets[0]);
            close(gdbserver_user_state.fork_sockets[1]);
        }
        return;
    }

    if (gdbserver_user_state.fork_state == GDB_FORK_DISABLED) {
        if (pid == 0) {
            disable_gdbstub(cpu);
        }
        return;
    }

    if (pid == 0) {
        close(gdbserver_user_state.fork_sockets[0]);
        fd = gdbserver_user_state.fork_sockets[1];
        g_assert(gdbserver_state.process_num == 1);
        g_assert(gdbserver_state.processes[0].pid ==
                     gdbserver_user_state.fork_peer_pid);
        g_assert(gdbserver_state.processes[0].attached);
        gdbserver_state.processes[0].pid = getpid();
    } else {
        close(gdbserver_user_state.fork_sockets[1]);
        fd = gdbserver_user_state.fork_sockets[0];
        gdbserver_user_state.fork_state = GDB_FORK_ACTIVE;
        gdbserver_user_state.fork_peer_pid = pid;
        gdbserver_user_state.fork_peer_tid = pid;

        if (!gdbserver_state.allow_stop_reply) {
            goto fail;
        }
        g_string_printf(gdbserver_state.str_buf,
                        "T%02xfork:p%02x.%02x;thread:p%02x.%02x;",
                        gdb_target_signal_to_gdb(gdb_target_sigtrap()),
                        pid, pid, (int)getpid(), qemu_get_thread_id());
        gdb_put_strbuf();
    }

    gdbserver_state.state = RS_IDLE;
    gdbserver_state.allow_stop_reply = false;
    gdbserver_user_state.running_state = 0;
    for (;;) {
        switch (gdbserver_user_state.fork_state) {
        case GDB_FORK_ENABLED:
            if (gdbserver_user_state.running_state) {
                close(fd);
                return;
            }
            QEMU_FALLTHROUGH;
        case GDB_FORK_ACTIVE:
            if (read(gdbserver_user_state.fd, &b, 1) != 1) {
                goto fail;
            }
            gdb_read_byte(b);
            break;
        case GDB_FORK_DEACTIVATING:
            b = GDB_FORK_ACTIVATE;
            if (write(fd, &b, 1) != 1) {
                goto fail;
            }
            gdbserver_user_state.fork_state = GDB_FORK_INACTIVE;
            break;
        case GDB_FORK_INACTIVE:
            if (read(fd, &b, 1) != 1) {
                goto fail;
            }
            switch (b) {
            case GDB_FORK_ACTIVATE:
                gdbserver_user_state.fork_state = GDB_FORK_ACTIVE;
                break;
            case GDB_FORK_ENABLE:
                gdbserver_user_state.fork_state = GDB_FORK_ENABLED;
                break;
            case GDB_FORK_DISABLE:
                gdbserver_user_state.fork_state = GDB_FORK_DISABLED;
                break;
            default:
                g_assert_not_reached();
            }
            break;
        case GDB_FORK_ENABLING:
            b = GDB_FORK_DISABLE;
            if (write(fd, &b, 1) != 1) {
                goto fail;
            }
            gdbserver_user_state.fork_state = GDB_FORK_ENABLED;
            break;
        case GDB_FORK_DISABLING:
            b = GDB_FORK_ENABLE;
            if (write(fd, &b, 1) != 1) {
                goto fail;
            }
            gdbserver_user_state.fork_state = GDB_FORK_DISABLED;
            break;
        case GDB_FORK_DISABLED:
            close(fd);
            disable_gdbstub(cpu);
            return;
        default:
            g_assert_not_reached();
        }
    }

fail:
    close(fd);
    if (pid == 0) {
        disable_gdbstub(cpu);
    }
}

void gdb_handle_query_supported_user(const char *gdb_supported)
{
    if (strstr(gdb_supported, "fork-events+")) {
        gdbserver_user_state.fork_events = true;
    }
    g_string_append(gdbserver_state.str_buf, ";fork-events+");
}

bool gdb_handle_set_thread_user(uint32_t pid, uint32_t tid)
{
    if (gdbserver_user_state.fork_state == GDB_FORK_ACTIVE &&
            pid == gdbserver_user_state.fork_peer_pid &&
            tid == gdbserver_user_state.fork_peer_tid) {
        gdbserver_user_state.fork_state = GDB_FORK_DEACTIVATING;
        gdb_put_packet("OK");
        return true;
    }
    return false;
}

bool gdb_handle_detach_user(uint32_t pid)
{
    bool enable;

    if (gdbserver_user_state.fork_state == GDB_FORK_ACTIVE) {
        enable = pid == gdbserver_user_state.fork_peer_pid;
        if (enable || pid == getpid()) {
            gdbserver_user_state.fork_state = enable ? GDB_FORK_ENABLING :
                                                       GDB_FORK_DISABLING;
            gdb_put_packet("OK");
            return true;
        }
    }
    return false;
}

/*
 * Execution state helpers
 */

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

void gdb_continue(void)
{
    gdbserver_user_state.running_state = 1;
    trace_gdbstub_op_continue();
}

/*
 * Resume execution, for user-mode emulation it's equivalent to
 * gdb_continue.
 */
int gdb_continue_partial(char *newstates)
{
    CPUState *cpu;
    int res = 0;
    /*
     * This is not exactly accurate, but it's an improvement compared to the
     * previous situation, where only one CPU would be single-stepped.
     */
    CPU_FOREACH(cpu) {
        if (newstates[cpu->cpu_index] == 's') {
            trace_gdbstub_op_stepping(cpu->cpu_index);
            cpu_single_step(cpu, gdbserver_state.sstep_flags);
        }
    }
    gdbserver_user_state.running_state = 1;
    return res;
}

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

    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)
{
    CPUState *cpu;
    unsigned int max_cpus = 1;

    CPU_FOREACH(cpu) {
        max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
    }

    return max_cpus;
}

/* replay not supported for user-mode */
bool gdb_can_reverse(void)
{
    return false;
}

/*
 * Break/Watch point helpers
 */

bool gdb_supports_guest_debug(void)
{
    /* user-mode == TCG == supported */
    return true;
}

int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
{
    CPUState *cpu;
    int err = 0;

    switch (type) {
    case GDB_BREAKPOINT_SW:
    case GDB_BREAKPOINT_HW:
        CPU_FOREACH(cpu) {
            err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
            if (err) {
                break;
            }
        }
        return err;
    default:
        /* user-mode doesn't support watchpoints */
        return -ENOSYS;
    }
}

int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
{
    CPUState *cpu;
    int err = 0;

    switch (type) {
    case GDB_BREAKPOINT_SW:
    case GDB_BREAKPOINT_HW:
        CPU_FOREACH(cpu) {
            err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
            if (err) {
                break;
            }
        }
        return err;
    default:
        /* user-mode doesn't support watchpoints */
        return -ENOSYS;
    }
}

void gdb_breakpoint_remove_all(CPUState *cs)
{
    cpu_breakpoint_remove_all(cs, BP_GDB);
}

/*
 * For user-mode syscall support we send the system call immediately
 * and then return control to gdb for it to process the syscall request.
 * Since the protocol requires that gdb hands control back to us
 * using a "here are the results" F packet, we don't need to check
 * gdb_handlesig's return value (which is the signal to deliver if
 * execution was resumed via a continue packet).
 */
void gdb_syscall_handling(const char *syscall_packet)
{
    gdb_put_packet(syscall_packet);
    gdb_handlesig(gdbserver_state.c_cpu, 0, NULL, NULL, 0);
}

static bool should_catch_syscall(int num)
{
    if (gdbserver_user_state.catch_all_syscalls) {
        return true;
    }
    if (num < 0 || num >= GDB_NR_SYSCALLS) {
        return false;
    }
    return test_bit(num, gdbserver_user_state.catch_syscalls_mask);
}

void gdb_syscall_entry(CPUState *cs, int num)
{
    if (should_catch_syscall(num)) {
        g_autofree char *reason = g_strdup_printf("syscall_entry:%x;", num);
        gdb_handlesig(cs, gdb_target_sigtrap(), reason, NULL, 0);
    }
}

void gdb_syscall_return(CPUState *cs, int num)
{
    if (should_catch_syscall(num)) {
        g_autofree char *reason = g_strdup_printf("syscall_return:%x;", num);
        gdb_handlesig(cs, gdb_target_sigtrap(), reason, NULL, 0);
    }
}

void gdb_handle_set_catch_syscalls(GArray *params, void *user_ctx)
{
    const char *param = gdb_get_cmd_param(params, 0)->data;
    GDBSyscallsMask catch_syscalls_mask;
    bool catch_all_syscalls;
    unsigned int num;
    const char *p;

    /* "0" means not catching any syscalls. */
    if (strcmp(param, "0") == 0) {
        gdbserver_user_state.catch_all_syscalls = false;
        memset(gdbserver_user_state.catch_syscalls_mask, 0,
               sizeof(gdbserver_user_state.catch_syscalls_mask));
        gdb_put_packet("OK");
        return;
    }

    /* "1" means catching all syscalls. */
    if (strcmp(param, "1") == 0) {
        gdbserver_user_state.catch_all_syscalls = true;
        gdb_put_packet("OK");
        return;
    }

    /*
     * "1;..." means catching only the specified syscalls.
     * The syscall list must not be empty.
     */
    if (param[0] == '1' && param[1] == ';') {
        catch_all_syscalls = false;
        memset(catch_syscalls_mask, 0, sizeof(catch_syscalls_mask));
        for (p = &param[2];; p++) {
            if (qemu_strtoui(p, &p, 16, &num) || (*p && *p != ';')) {
                goto err;
            }
            if (num >= GDB_NR_SYSCALLS) {
                /*
                 * Fall back to reporting all syscalls. Reporting extra
                 * syscalls is inefficient, but the spec explicitly allows it.
                 * Keep parsing in case there is a syntax error ahead.
                 */
                catch_all_syscalls = true;
            } else {
                set_bit(num, catch_syscalls_mask);
            }
            if (!*p) {
                break;
            }
        }
        gdbserver_user_state.catch_all_syscalls = catch_all_syscalls;
        if (!catch_all_syscalls) {
            memcpy(gdbserver_user_state.catch_syscalls_mask,
                   catch_syscalls_mask, sizeof(catch_syscalls_mask));
        }
        gdb_put_packet("OK");
        return;
    }

err:
    gdb_put_packet("E00");
}

void gdb_handle_query_xfer_siginfo(GArray *params, void *user_ctx)
{
    unsigned long offset, len;
    uint8_t *siginfo_offset;

    offset = gdb_get_cmd_param(params, 0)->val_ul;
    len = gdb_get_cmd_param(params, 1)->val_ul;

    if (offset + len > gdbserver_user_state.siginfo_len) {
        /* Invalid offset and/or requested length. */
        gdb_put_packet("E01");
        return;
    }

    siginfo_offset = (uint8_t *)gdbserver_user_state.siginfo + offset;

    /* Reply */
    g_string_assign(gdbserver_state.str_buf, "l");
    gdb_memtox(gdbserver_state.str_buf, (const char *)siginfo_offset, len);
    gdb_put_packet_binary(gdbserver_state.str_buf->str,
                          gdbserver_state.str_buf->len, true);
}
