/*
 * Syscall implementations for semihosting.
 *
 * Copyright (c) 2022 Linaro
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "gdbstub/syscalls.h"
#include "semihosting/guestfd.h"
#include "semihosting/syscalls.h"
#include "semihosting/console.h"
#ifdef CONFIG_USER_ONLY
#include "qemu.h"
#else
#include "semihosting/uaccess.h"
#endif


/*
 * Validate or compute the length of the string (including terminator).
 */
static int validate_strlen(CPUState *cs, vaddr str, uint64_t tlen)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char c;

    if (tlen == 0) {
        ssize_t slen = target_strlen(str);

        if (slen < 0) {
            return -EFAULT;
        }
        if (slen >= INT32_MAX) {
            return -ENAMETOOLONG;
        }
        return slen + 1;
    }
    if (tlen > INT32_MAX) {
        return -ENAMETOOLONG;
    }
    if (get_user_u8(c, str + tlen - 1)) {
        return -EFAULT;
    }
    if (c != 0) {
        return -EINVAL;
    }
    return tlen;
}

static int validate_lock_user_string(char **pstr, CPUState *cs,
                                     vaddr tstr, uint64_t tlen)
{
    int ret = validate_strlen(cs, tstr, tlen);
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *str = NULL;

    if (ret > 0) {
        str = lock_user(VERIFY_READ, tstr, ret, true);
        ret = str ? 0 : -EFAULT;
    }
    *pstr = str;
    return ret;
}

/*
 * TODO: Note that gdb always stores the stat structure big-endian.
 * So far, that's ok, as the only two targets using this are also
 * big-endian.  Until we do something with gdb, also produce the
 * same big-endian result from the host.
 */
static int copy_stat_to_user(CPUState *cs, vaddr addr,
                             const struct stat *s)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    struct gdb_stat *p;

    if (s->st_dev != (uint32_t)s->st_dev ||
        s->st_ino != (uint32_t)s->st_ino) {
        return -EOVERFLOW;
    }

    p = lock_user(VERIFY_WRITE, addr, sizeof(struct gdb_stat), 0);
    if (!p) {
        return -EFAULT;
    }

    p->gdb_st_dev = cpu_to_be32(s->st_dev);
    p->gdb_st_ino = cpu_to_be32(s->st_ino);
    p->gdb_st_mode = cpu_to_be32(s->st_mode);
    p->gdb_st_nlink = cpu_to_be32(s->st_nlink);
    p->gdb_st_uid = cpu_to_be32(s->st_uid);
    p->gdb_st_gid = cpu_to_be32(s->st_gid);
    p->gdb_st_rdev = cpu_to_be32(s->st_rdev);
    p->gdb_st_size = cpu_to_be64(s->st_size);
#ifdef _WIN32
    /* Windows stat is missing some fields.  */
    p->gdb_st_blksize = 0;
    p->gdb_st_blocks = 0;
#else
    p->gdb_st_blksize = cpu_to_be64(s->st_blksize);
    p->gdb_st_blocks = cpu_to_be64(s->st_blocks);
#endif
    p->gdb_st_atime = cpu_to_be32(s->st_atime);
    p->gdb_st_mtime = cpu_to_be32(s->st_mtime);
    p->gdb_st_ctime = cpu_to_be32(s->st_ctime);

    unlock_user(p, addr, sizeof(struct gdb_stat));
    return 0;
}

/*
 * GDB semihosting syscall implementations.
 */

static gdb_syscall_complete_cb gdb_open_complete;

static void gdb_open_cb(CPUState *cs, uint64_t ret, int err)
{
    if (!err) {
        int guestfd = alloc_guestfd();
        associate_guestfd(guestfd, ret);
        ret = guestfd;
    }
    gdb_open_complete(cs, ret, err);
}

static void gdb_open(CPUState *cs, gdb_syscall_complete_cb complete,
                     vaddr fname, uint64_t fname_len,
                     int gdb_flags, int mode)
{
    int len = validate_strlen(cs, fname, fname_len);
    if (len < 0) {
        complete(cs, -1, -len);
        return;
    }

    gdb_open_complete = complete;
    gdb_do_syscall(gdb_open_cb, "open,%s,%x,%x",
                   (vaddr)fname, (uint32_t)len,
                   (uint32_t)gdb_flags, (uint32_t)mode);
}

static void gdb_close(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf)
{
    gdb_do_syscall(complete, "close,%x", (uint32_t)gf->hostfd);
}

static void gdb_read(CPUState *cs, gdb_syscall_complete_cb complete,
                     GuestFD *gf, vaddr buf, uint64_t len)
{
    gdb_do_syscall(complete, "read,%x,%lx,%lx",
                   (uint32_t)gf->hostfd, (vaddr)buf, (uint64_t)len);
}

static void gdb_write(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf, vaddr buf, uint64_t len)
{
    gdb_do_syscall(complete, "write,%x,%lx,%lx",
                   (uint32_t)gf->hostfd, (vaddr)buf, (uint64_t)len);
}

static void gdb_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf, int64_t off, int gdb_whence)
{
    gdb_do_syscall(complete, "lseek,%x,%lx,%x",
                   (uint32_t)gf->hostfd, off, (uint32_t)gdb_whence);
}

static void gdb_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
                       GuestFD *gf)
{
    gdb_do_syscall(complete, "isatty,%x", (uint32_t)gf->hostfd);
}

static void gdb_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf, vaddr addr)
{
    gdb_do_syscall(complete, "fstat,%x,%lx",
                   (uint32_t)gf->hostfd, (vaddr)addr);
}

static void gdb_stat(CPUState *cs, gdb_syscall_complete_cb complete,
                     vaddr fname, uint64_t fname_len,
                     vaddr addr)
{
    int len = validate_strlen(cs, fname, fname_len);
    if (len < 0) {
        complete(cs, -1, -len);
        return;
    }

    gdb_do_syscall(complete, "stat,%s,%lx",
                   (vaddr)fname, (uint32_t)len, (vaddr)addr);
}

static void gdb_remove(CPUState *cs, gdb_syscall_complete_cb complete,
                       vaddr fname, uint64_t fname_len)
{
    int len = validate_strlen(cs, fname, fname_len);
    if (len < 0) {
        complete(cs, -1, -len);
        return;
    }

    gdb_do_syscall(complete, "unlink,%s", (vaddr)fname, (uint32_t)len);
}

static void gdb_rename(CPUState *cs, gdb_syscall_complete_cb complete,
                       vaddr oname, uint64_t oname_len,
                       vaddr nname, uint64_t nname_len)
{
    int olen, nlen;

    olen = validate_strlen(cs, oname, oname_len);
    if (olen < 0) {
        complete(cs, -1, -olen);
        return;
    }
    nlen = validate_strlen(cs, nname, nname_len);
    if (nlen < 0) {
        complete(cs, -1, -nlen);
        return;
    }

    gdb_do_syscall(complete, "rename,%s,%s",
                   (vaddr)oname, (uint32_t)olen,
                   (vaddr)nname, (uint32_t)nlen);
}

static void gdb_system(CPUState *cs, gdb_syscall_complete_cb complete,
                       vaddr cmd, uint64_t cmd_len)
{
    int len = validate_strlen(cs, cmd, cmd_len);
    if (len < 0) {
        complete(cs, -1, -len);
        return;
    }

    gdb_do_syscall(complete, "system,%s", (vaddr)cmd, (uint32_t)len);
}

static void gdb_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
                             vaddr tv_addr, vaddr tz_addr)
{
    gdb_do_syscall(complete, "gettimeofday,%lx,%lx",
                   (vaddr)tv_addr, (vaddr)tz_addr);
}

/*
 * Host semihosting syscall implementations.
 */

static void host_open(CPUState *cs, gdb_syscall_complete_cb complete,
                      vaddr fname, uint64_t fname_len,
                      int gdb_flags, int mode)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *p;
    int ret, host_flags = O_BINARY;

    ret = validate_lock_user_string(&p, cs, fname, fname_len);
    if (ret < 0) {
        complete(cs, -1, -ret);
        return;
    }

    if (gdb_flags & GDB_O_WRONLY) {
        host_flags |= O_WRONLY;
    } else if (gdb_flags & GDB_O_RDWR) {
        host_flags |= O_RDWR;
    } else {
        host_flags |= O_RDONLY;
    }
    if (gdb_flags & GDB_O_CREAT) {
        host_flags |= O_CREAT;
    }
    if (gdb_flags & GDB_O_TRUNC) {
        host_flags |= O_TRUNC;
    }
    if (gdb_flags & GDB_O_EXCL) {
        host_flags |= O_EXCL;
    }

    ret = open(p, host_flags, mode);
    if (ret < 0) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to open %s\n", __func__, p);
        complete(cs, -1, errno);
    } else {
        int guestfd = alloc_guestfd();
        associate_guestfd(guestfd, ret);
        complete(cs, guestfd, 0);
    }
    unlock_user(p, fname, 0);
}

static void host_close(CPUState *cs, gdb_syscall_complete_cb complete,
                       GuestFD *gf)
{
    /*
     * Only close the underlying host fd if it's one we opened on behalf
     * of the guest in SYS_OPEN.
     */
    if (gf->hostfd != STDIN_FILENO &&
        gf->hostfd != STDOUT_FILENO &&
        gf->hostfd != STDERR_FILENO &&
        close(gf->hostfd) < 0) {
        complete(cs, -1, errno);
    } else {
        complete(cs, 0, 0);
    }
}

static void host_read(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf, vaddr buf, uint64_t len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    void *ptr = lock_user(VERIFY_WRITE, buf, len, 0);
    ssize_t ret;

    if (!ptr) {
        complete(cs, -1, EFAULT);
        return;
    }
    ret = RETRY_ON_EINTR(read(gf->hostfd, ptr, len));
    if (ret == -1) {
        unlock_user(ptr, buf, 0);
        complete(cs, -1, errno);
    } else {
        unlock_user(ptr, buf, ret);
        complete(cs, ret, 0);
    }
}

static void host_write(CPUState *cs, gdb_syscall_complete_cb complete,
                       GuestFD *gf, vaddr buf, uint64_t len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    void *ptr = lock_user(VERIFY_READ, buf, len, 1);
    ssize_t ret;

    if (!ptr) {
        complete(cs, -1, EFAULT);
        return;
    }
    ret = write(gf->hostfd, ptr, len);
    unlock_user(ptr, buf, 0);
    complete(cs, ret, ret == -1 ? errno : 0);
}

static void host_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
                       GuestFD *gf, int64_t off, int whence)
{
    /* So far, all hosts use the same values. */
    QEMU_BUILD_BUG_ON(GDB_SEEK_SET != SEEK_SET);
    QEMU_BUILD_BUG_ON(GDB_SEEK_CUR != SEEK_CUR);
    QEMU_BUILD_BUG_ON(GDB_SEEK_END != SEEK_END);

    off_t ret = off;
    int err = 0;

    if (ret == off) {
        ret = lseek(gf->hostfd, ret, whence);
        if (ret == -1) {
            err = errno;
        }
    } else {
        ret = -1;
        err = EINVAL;
    }
    complete(cs, ret, err);
}

static void host_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
                        GuestFD *gf)
{
    int ret = isatty(gf->hostfd);
    complete(cs, ret, ret ? 0 : errno);
}

static void host_flen(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf)
{
    struct stat buf;

    if (fstat(gf->hostfd, &buf) < 0) {
        complete(cs, -1, errno);
    } else {
        complete(cs, buf.st_size, 0);
    }
}

static void host_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
                       GuestFD *gf, vaddr addr)
{
    struct stat buf;
    int ret;

    ret = fstat(gf->hostfd, &buf);
    if (ret) {
        complete(cs, -1, errno);
        return;
    }
    ret = copy_stat_to_user(cs, addr, &buf);
    complete(cs, ret ? -1 : 0, ret ? -ret : 0);
}

static void host_stat(CPUState *cs, gdb_syscall_complete_cb complete,
                      vaddr fname, uint64_t fname_len,
                      vaddr addr)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    struct stat buf;
    char *name;
    int ret, err;

    ret = validate_lock_user_string(&name, cs, fname, fname_len);
    if (ret < 0) {
        complete(cs, -1, -ret);
        return;
    }

    ret = stat(name, &buf);
    if (ret) {
        err = errno;
    } else {
        ret = copy_stat_to_user(cs, addr, &buf);
        err = 0;
        if (ret < 0) {
            err = -ret;
            ret = -1;
        }
    }
    unlock_user(name, fname, 0);
    complete(cs, ret, err);
}

static void host_remove(CPUState *cs, gdb_syscall_complete_cb complete,
                        vaddr fname, uint64_t fname_len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *p;
    int ret;

    ret = validate_lock_user_string(&p, cs, fname, fname_len);
    if (ret < 0) {
        complete(cs, -1, -ret);
        return;
    }

    ret = remove(p);
    unlock_user(p, fname, 0);
    complete(cs, ret, ret ? errno : 0);
}

static void host_rename(CPUState *cs, gdb_syscall_complete_cb complete,
                        vaddr oname, uint64_t oname_len,
                        vaddr nname, uint64_t nname_len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *ostr, *nstr;
    int ret;

    ret = validate_lock_user_string(&ostr, cs, oname, oname_len);
    if (ret < 0) {
        complete(cs, -1, -ret);
        return;
    }
    ret = validate_lock_user_string(&nstr, cs, nname, nname_len);
    if (ret < 0) {
        unlock_user(ostr, oname, 0);
        complete(cs, -1, -ret);
        return;
    }

    ret = rename(ostr, nstr);
    unlock_user(ostr, oname, 0);
    unlock_user(nstr, nname, 0);
    complete(cs, ret, ret ? errno : 0);
}

static void host_system(CPUState *cs, gdb_syscall_complete_cb complete,
                        vaddr cmd, uint64_t cmd_len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *p;
    int ret;

    ret = validate_lock_user_string(&p, cs, cmd, cmd_len);
    if (ret < 0) {
        complete(cs, -1, -ret);
        return;
    }

    ret = system(p);
    unlock_user(p, cmd, 0);
    complete(cs, ret, ret == -1 ? errno : 0);
}

static void host_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
                              vaddr tv_addr, vaddr tz_addr)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    struct gdb_timeval *p;
    int64_t rt;

    /* GDB fails on non-null TZ, so be consistent. */
    if (tz_addr != 0) {
        complete(cs, -1, EINVAL);
        return;
    }

    p = lock_user(VERIFY_WRITE, tv_addr, sizeof(struct gdb_timeval), 0);
    if (!p) {
        complete(cs, -1, EFAULT);
        return;
    }

    /* TODO: Like stat, gdb always produces big-endian results; match it. */
    rt = g_get_real_time();
    p->tv_sec = cpu_to_be32(rt / G_USEC_PER_SEC);
    p->tv_usec = cpu_to_be64(rt % G_USEC_PER_SEC);
    unlock_user(p, tv_addr, sizeof(struct gdb_timeval));
}

#ifndef CONFIG_USER_ONLY
static void host_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
                          GuestFD *gf, GIOCondition cond, int timeout)
{
    /*
     * Since this is only used by xtensa in system mode, and stdio is
     * handled through GuestFDConsole, and there are no semihosting
     * system calls for sockets and the like, that means this descriptor
     * must be a normal file.  Normal files never block and are thus
     * always ready.
     */
    complete(cs, cond & (G_IO_IN | G_IO_OUT), 0);
}
#endif

/*
 * Static file semihosting syscall implementations.
 */

static void staticfile_read(CPUState *cs, gdb_syscall_complete_cb complete,
                            GuestFD *gf, vaddr buf, uint64_t len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    uint64_t rest = gf->staticfile.len - gf->staticfile.off;
    void *ptr;

    if (len > rest) {
        len = rest;
    }
    ptr = lock_user(VERIFY_WRITE, buf, len, 0);
    if (!ptr) {
        complete(cs, -1, EFAULT);
        return;
    }
    memcpy(ptr, gf->staticfile.data + gf->staticfile.off, len);
    gf->staticfile.off += len;
    unlock_user(ptr, buf, len);
    complete(cs, len, 0);
}

static void staticfile_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
                             GuestFD *gf, int64_t off, int gdb_whence)
{
    int64_t ret;

    switch (gdb_whence) {
    case GDB_SEEK_SET:
        ret = off;
        break;
    case GDB_SEEK_CUR:
        ret = gf->staticfile.off + off;
        break;
    case GDB_SEEK_END:
        ret = gf->staticfile.len + off;
        break;
    default:
        ret = -1;
        break;
    }
    if (ret >= 0 && ret <= gf->staticfile.len) {
        gf->staticfile.off = ret;
        complete(cs, ret, 0);
    } else {
        complete(cs, -1, EINVAL);
    }
}

static void staticfile_flen(CPUState *cs, gdb_syscall_complete_cb complete,
                            GuestFD *gf)
{
    complete(cs, gf->staticfile.len, 0);
}

/*
 * Console semihosting syscall implementations.
 */

static void console_read(CPUState *cs, gdb_syscall_complete_cb complete,
                         GuestFD *gf, vaddr buf, uint64_t len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *ptr;
    int ret;

    ptr = lock_user(VERIFY_WRITE, buf, len, 0);
    if (!ptr) {
        complete(cs, -1, EFAULT);
        return;
    }
    ret = qemu_semihosting_console_read(cs, ptr, len);
    unlock_user(ptr, buf, ret);
    complete(cs, ret, 0);
}

static void console_write(CPUState *cs, gdb_syscall_complete_cb complete,
                          GuestFD *gf, vaddr buf, uint64_t len)
{
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    char *ptr = lock_user(VERIFY_READ, buf, len, 1);
    int ret;

    if (!ptr) {
        complete(cs, -1, EFAULT);
        return;
    }
    ret = qemu_semihosting_console_write(ptr, len);
    unlock_user(ptr, buf, 0);
    complete(cs, ret ? ret : -1, ret ? 0 : EIO);
}

static void console_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
                          GuestFD *gf, vaddr addr)
{
    static const struct stat tty_buf = {
        .st_mode = 020666,  /* S_IFCHR, ugo+rw */
        .st_rdev = 5,       /* makedev(5, 0) -- linux /dev/tty */
    };
    int ret;

    ret = copy_stat_to_user(cs, addr, &tty_buf);
    complete(cs, ret ? -1 : 0, ret ? -ret : 0);
}

#ifndef CONFIG_USER_ONLY
static void console_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
                             GuestFD *gf, GIOCondition cond, int timeout)
{
    /* The semihosting console does not support urgent data or errors. */
    cond &= G_IO_IN | G_IO_OUT;

    /*
     * Since qemu_semihosting_console_write never blocks, we can
     * consider output always ready -- leave G_IO_OUT alone.
     * All that remains is to conditionally signal input ready.
     * Since output ready causes an immediate return, only block
     * for G_IO_IN alone.
     *
     * TODO: Implement proper timeout.  For now, only support
     * indefinite wait or immediate poll.
     */
    if (cond == G_IO_IN && timeout < 0) {
        qemu_semihosting_console_block_until_ready(cs);
        /* We returned -- input must be ready. */
    } else if ((cond & G_IO_IN) && !qemu_semihosting_console_ready()) {
        cond &= ~G_IO_IN;
    }

    complete(cs, cond, 0);
}
#endif

/*
 * Syscall entry points.
 */

void semihost_sys_open(CPUState *cs, gdb_syscall_complete_cb complete,
                       vaddr fname, uint64_t fname_len,
                       int gdb_flags, int mode)
{
    if (use_gdb_syscalls()) {
        gdb_open(cs, complete, fname, fname_len, gdb_flags, mode);
    } else {
        host_open(cs, complete, fname, fname_len, gdb_flags, mode);
    }
}

void semihost_sys_close(CPUState *cs, gdb_syscall_complete_cb complete, int fd)
{
    GuestFD *gf = get_guestfd(fd);

    if (!gf) {
        complete(cs, -1, EBADF);
        return;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_close(cs, complete, gf);
        break;
    case GuestFDHost:
        host_close(cs, complete, gf);
        break;
    case GuestFDStatic:
    case GuestFDConsole:
        complete(cs, 0, 0);
        break;
    default:
        g_assert_not_reached();
    }
    dealloc_guestfd(fd);
}

void semihost_sys_read_gf(CPUState *cs, gdb_syscall_complete_cb complete,
                          GuestFD *gf, vaddr buf, uint64_t len)
{
    /*
     * Bound length for 64-bit guests on 32-bit hosts, not overflowing ssize_t.
     * Note the Linux kernel does this with MAX_RW_COUNT, so it's not a bad
     * idea to do this unconditionally.
     */
    if (len > INT32_MAX) {
        len = INT32_MAX;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_read(cs, complete, gf, buf, len);
        break;
    case GuestFDHost:
        host_read(cs, complete, gf, buf, len);
        break;
    case GuestFDStatic:
        staticfile_read(cs, complete, gf, buf, len);
        break;
    case GuestFDConsole:
        console_read(cs, complete, gf, buf, len);
        break;
    default:
        g_assert_not_reached();
    }
}

void semihost_sys_read(CPUState *cs, gdb_syscall_complete_cb complete,
                       int fd, vaddr buf, uint64_t len)
{
    GuestFD *gf = get_guestfd(fd);

    if (gf) {
        semihost_sys_read_gf(cs, complete, gf, buf, len);
    } else {
        complete(cs, -1, EBADF);
    }
}

void semihost_sys_write_gf(CPUState *cs, gdb_syscall_complete_cb complete,
                           GuestFD *gf, vaddr buf, uint64_t len)
{
    /*
     * Bound length for 64-bit guests on 32-bit hosts, not overflowing ssize_t.
     * Note the Linux kernel does this with MAX_RW_COUNT, so it's not a bad
     * idea to do this unconditionally.
     */
    if (len > INT32_MAX) {
        len = INT32_MAX;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_write(cs, complete, gf, buf, len);
        break;
    case GuestFDHost:
        host_write(cs, complete, gf, buf, len);
        break;
    case GuestFDConsole:
        console_write(cs, complete, gf, buf, len);
        break;
    case GuestFDStatic:
        /* Static files are never open for writing: EBADF. */
        complete(cs, -1, EBADF);
        break;
    default:
        g_assert_not_reached();
    }
}

void semihost_sys_write(CPUState *cs, gdb_syscall_complete_cb complete,
                        int fd, vaddr buf, uint64_t len)
{
    GuestFD *gf = get_guestfd(fd);

    if (gf) {
        semihost_sys_write_gf(cs, complete, gf, buf, len);
    } else {
        complete(cs, -1, EBADF);
    }
}

void semihost_sys_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
                        int fd, int64_t off, int gdb_whence)
{
    GuestFD *gf = get_guestfd(fd);

    if (!gf) {
        complete(cs, -1, EBADF);
        return;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_lseek(cs, complete, gf, off, gdb_whence);
        return;
    case GuestFDHost:
        host_lseek(cs, complete, gf, off, gdb_whence);
        break;
    case GuestFDStatic:
        staticfile_lseek(cs, complete, gf, off, gdb_whence);
        break;
    case GuestFDConsole:
        complete(cs, -1, ESPIPE);
        break;
    default:
        g_assert_not_reached();
    }
}

void semihost_sys_isatty(CPUState *cs, gdb_syscall_complete_cb complete, int fd)
{
    GuestFD *gf = get_guestfd(fd);

    if (!gf) {
        complete(cs, 0, EBADF);
        return;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_isatty(cs, complete, gf);
        break;
    case GuestFDHost:
        host_isatty(cs, complete, gf);
        break;
    case GuestFDStatic:
        complete(cs, 0, ENOTTY);
        break;
    case GuestFDConsole:
        complete(cs, 1, 0);
        break;
    default:
        g_assert_not_reached();
    }
}

void semihost_sys_flen(CPUState *cs, gdb_syscall_complete_cb fstat_cb,
                       gdb_syscall_complete_cb flen_cb, int fd,
                       vaddr fstat_addr)
{
    GuestFD *gf = get_guestfd(fd);

    if (!gf) {
        flen_cb(cs, -1, EBADF);
        return;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_fstat(cs, fstat_cb, gf, fstat_addr);
        break;
    case GuestFDHost:
        host_flen(cs, flen_cb, gf);
        break;
    case GuestFDStatic:
        staticfile_flen(cs, flen_cb, gf);
        break;
    case GuestFDConsole:
    default:
        g_assert_not_reached();
    }
}

void semihost_sys_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
                        int fd, vaddr addr)
{
    GuestFD *gf = get_guestfd(fd);

    if (!gf) {
        complete(cs, -1, EBADF);
        return;
    }
    switch (gf->type) {
    case GuestFDGDB:
        gdb_fstat(cs, complete, gf, addr);
        break;
    case GuestFDHost:
        host_fstat(cs, complete, gf, addr);
        break;
    case GuestFDConsole:
        console_fstat(cs, complete, gf, addr);
        break;
    case GuestFDStatic:
    default:
        g_assert_not_reached();
    }
}

void semihost_sys_stat(CPUState *cs, gdb_syscall_complete_cb complete,
                       vaddr fname, uint64_t fname_len,
                       vaddr addr)
{
    if (use_gdb_syscalls()) {
        gdb_stat(cs, complete, fname, fname_len, addr);
    } else {
        host_stat(cs, complete, fname, fname_len, addr);
    }
}

void semihost_sys_remove(CPUState *cs, gdb_syscall_complete_cb complete,
                         vaddr fname, uint64_t fname_len)
{
    if (use_gdb_syscalls()) {
        gdb_remove(cs, complete, fname, fname_len);
    } else {
        host_remove(cs, complete, fname, fname_len);
    }
}

void semihost_sys_rename(CPUState *cs, gdb_syscall_complete_cb complete,
                         vaddr oname, uint64_t oname_len,
                         vaddr nname, uint64_t nname_len)
{
    if (use_gdb_syscalls()) {
        gdb_rename(cs, complete, oname, oname_len, nname, nname_len);
    } else {
        host_rename(cs, complete, oname, oname_len, nname, nname_len);
    }
}

void semihost_sys_system(CPUState *cs, gdb_syscall_complete_cb complete,
                         vaddr cmd, uint64_t cmd_len)
{
    if (use_gdb_syscalls()) {
        gdb_system(cs, complete, cmd, cmd_len);
    } else {
        host_system(cs, complete, cmd, cmd_len);
    }
}

void semihost_sys_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
                               vaddr tv_addr, vaddr tz_addr)
{
    if (use_gdb_syscalls()) {
        gdb_gettimeofday(cs, complete, tv_addr, tz_addr);
    } else {
        host_gettimeofday(cs, complete, tv_addr, tz_addr);
    }
}

#ifndef CONFIG_USER_ONLY
void semihost_sys_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
                           int fd, GIOCondition cond, int timeout)
{
    GuestFD *gf = get_guestfd(fd);

    if (!gf) {
        complete(cs, G_IO_NVAL, 1);
        return;
    }
    switch (gf->type) {
    case GuestFDGDB:
        complete(cs, G_IO_NVAL, 1);
        break;
    case GuestFDHost:
        host_poll_one(cs, complete, gf, cond, timeout);
        break;
    case GuestFDConsole:
        console_poll_one(cs, complete, gf, cond, timeout);
        break;
    case GuestFDStatic:
    default:
        g_assert_not_reached();
    }
}
#endif
