/*
 * GDB Syscall Handling
 *
 * GDB can execute syscalls on the guests behalf, currently used by
 * the various semihosting extensions.
 *
 * Copyright (c) 2003-2005 Fabrice Bellard
 * Copyright (c) 2023 Linaro Ltd
 *
 * SPDX-License-Identifier: LGPL-2.0+
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "semihosting/semihost.h"
#include "sysemu/runstate.h"
#include "gdbstub/user.h"
#include "gdbstub/syscalls.h"
#include "gdbstub/commands.h"
#include "trace.h"
#include "internals.h"

/* Syscall specific state */
typedef struct {
    char syscall_buf[256];
    gdb_syscall_complete_cb current_syscall_cb;
} GDBSyscallState;

static GDBSyscallState gdbserver_syscall_state;

/*
 * Return true if there is a GDB currently connected to the stub
 * and attached to a CPU
 */
static bool gdb_attached(void)
{
    return gdbserver_state.init && gdbserver_state.c_cpu;
}

static enum {
    GDB_SYS_UNKNOWN,
    GDB_SYS_ENABLED,
    GDB_SYS_DISABLED,
} gdb_syscall_mode;

/* Decide if either remote gdb syscalls or native file IO should be used. */
int use_gdb_syscalls(void)
{
    SemihostingTarget target = semihosting_get_target();
    if (target == SEMIHOSTING_TARGET_NATIVE) {
        /* -semihosting-config target=native */
        return false;
    } else if (target == SEMIHOSTING_TARGET_GDB) {
        /* -semihosting-config target=gdb */
        return true;
    }

    /* -semihosting-config target=auto */
    /* On the first call check if gdb is connected and remember. */
    if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
        gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED;
    }
    return gdb_syscall_mode == GDB_SYS_ENABLED;
}

/* called when the stub detaches */
void gdb_disable_syscalls(void)
{
    gdb_syscall_mode = GDB_SYS_DISABLED;
}

void gdb_syscall_reset(void)
{
    gdbserver_syscall_state.current_syscall_cb = NULL;
}

bool gdb_handled_syscall(void)
{
    if (gdbserver_syscall_state.current_syscall_cb) {
        gdb_put_packet(gdbserver_syscall_state.syscall_buf);
        return true;
    }

    return false;
}

/*
 * Send a gdb syscall request.
 *  This accepts limited printf-style format specifiers, specifically:
 *   %x  - target_ulong argument printed in hex.
 *   %lx - 64-bit argument printed in hex.
 *   %s  - string pointer (target_ulong) and length (int) pair.
 */
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
{
    char *p, *p_end;
    va_list va;

    if (!gdb_attached()) {
        return;
    }

    gdbserver_syscall_state.current_syscall_cb = cb;
    va_start(va, fmt);

    p = gdbserver_syscall_state.syscall_buf;
    p_end = p + sizeof(gdbserver_syscall_state.syscall_buf);
    *(p++) = 'F';
    while (*fmt) {
        if (*fmt == '%') {
            uint64_t i64;
            uint32_t i32;

            fmt++;
            switch (*fmt++) {
            case 'x':
                i32 = va_arg(va, uint32_t);
                p += snprintf(p, p_end - p, "%" PRIx32, i32);
                break;
            case 'l':
                if (*(fmt++) != 'x') {
                    goto bad_format;
                }
                i64 = va_arg(va, uint64_t);
                p += snprintf(p, p_end - p, "%" PRIx64, i64);
                break;
            case 's':
                i64 = va_arg(va, uint64_t);
                i32 = va_arg(va, uint32_t);
                p += snprintf(p, p_end - p, "%" PRIx64 "/%x" PRIx32, i64, i32);
                break;
            default:
            bad_format:
                error_report("gdbstub: Bad syscall format string '%s'",
                             fmt - 1);
                break;
            }
        } else {
            *(p++) = *(fmt++);
        }
    }
    *p = 0;

    va_end(va);
    gdb_syscall_handling(gdbserver_syscall_state.syscall_buf);
}

/*
 * GDB Command Handlers
 */

void gdb_handle_file_io(GArray *params, void *user_ctx)
{
    if (params->len >= 1 && gdbserver_syscall_state.current_syscall_cb) {
        uint64_t ret;
        int err;

        ret = gdb_get_cmd_param(params, 0)->val_ull;
        if (params->len >= 2) {
            err = gdb_get_cmd_param(params, 1)->val_ull;
        } else {
            err = 0;
        }

        /* Convert GDB error numbers back to host error numbers. */
#define E(X)  case GDB_E##X: err = E##X; break
        switch (err) {
        case 0:
            break;
        E(PERM);
        E(NOENT);
        E(INTR);
        E(BADF);
        E(ACCES);
        E(FAULT);
        E(BUSY);
        E(EXIST);
        E(NODEV);
        E(NOTDIR);
        E(ISDIR);
        E(INVAL);
        E(NFILE);
        E(MFILE);
        E(FBIG);
        E(NOSPC);
        E(SPIPE);
        E(ROFS);
        E(NAMETOOLONG);
        default:
            err = EINVAL;
            break;
        }
#undef E

        gdbserver_syscall_state.current_syscall_cb(gdbserver_state.c_cpu,
                                                   ret, err);
        gdbserver_syscall_state.current_syscall_cb = NULL;
    }

    if (params->len >= 3 && gdb_get_cmd_param(params, 2)->opcode == (uint8_t)'C') {
        gdb_put_packet("T02");
        return;
    }

    gdb_continue();
}
