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

#include "qemu/osdep.h"
#include "cpu.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/softmmu-uaccess.h"
#endif


/*
 * Validate or compute the length of the string (including terminator).
 */
static int validate_strlen(CPUState *cs, target_ulong str, target_ulong tlen)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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,
                                     target_ulong tstr, target_ulong tlen)
{
    int ret = validate_strlen(cs, tstr, tlen);
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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, target_ulong addr,
                             const struct stat *s)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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,
                     target_ulong fname, target_ulong 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",
                   (uint64_t)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, target_ulong buf, target_ulong len)
{
    gdb_do_syscall(complete, "read,%x,%lx,%lx",
                   (uint32_t)gf->hostfd, (uint64_t)buf, (uint64_t)len);
}

static void gdb_write(CPUState *cs, gdb_syscall_complete_cb complete,
                      GuestFD *gf, target_ulong buf, target_ulong len)
{
    gdb_do_syscall(complete, "write,%x,%lx,%lx",
                   (uint32_t)gf->hostfd, (uint64_t)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, target_ulong addr)
{
    gdb_do_syscall(complete, "fstat,%x,%lx",
                   (uint32_t)gf->hostfd, (uint64_t)addr);
}

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

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

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

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

static void gdb_rename(CPUState *cs, gdb_syscall_complete_cb complete,
                       target_ulong oname, target_ulong oname_len,
                       target_ulong nname, target_ulong 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",
                   (uint64_t)oname, (uint32_t)olen,
                   (uint64_t)nname, (uint32_t)nlen);
}

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

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

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

/*
 * Host semihosting syscall implementations.
 */

static void host_open(CPUState *cs, gdb_syscall_complete_cb complete,
                      target_ulong fname, target_ulong fname_len,
                      int gdb_flags, int mode)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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) {
        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, target_ulong buf, target_ulong len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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, target_ulong buf, target_ulong len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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, target_ulong 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,
                      target_ulong fname, target_ulong fname_len,
                      target_ulong addr)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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,
                        target_ulong fname, target_ulong fname_len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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,
                        target_ulong oname, target_ulong oname_len,
                        target_ulong nname, target_ulong nname_len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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,
                        target_ulong cmd, target_ulong cmd_len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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,
                              target_ulong tv_addr, target_ulong tz_addr)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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, target_ulong buf, target_ulong len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    target_ulong 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, target_ulong buf, target_ulong len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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, target_ulong buf, target_ulong len)
{
    CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
    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, target_ulong 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,
                       target_ulong fname, target_ulong 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, target_ulong buf, target_ulong 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, target_ulong buf, target_ulong 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, target_ulong buf, target_ulong 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, target_ulong buf, target_ulong 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,
                       target_ulong 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, target_ulong 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,
                       target_ulong fname, target_ulong fname_len,
                       target_ulong 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,
                         target_ulong fname, target_ulong 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,
                         target_ulong oname, target_ulong oname_len,
                         target_ulong nname, target_ulong 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,
                         target_ulong cmd, target_ulong 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,
                               target_ulong tv_addr, target_ulong 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
