/*
 * 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-or-later
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "semihosting/semihost.h"
#include "system/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 "/%" 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();
}
