/*
 *  Semihosting support for systems modeled on the Arm "Angel"
 *  semihosting syscalls design.
 *
 *  Copyright (c) 2005, 2007 CodeSourcery.
 *  Copyright (c) 2019 Linaro
 *  Written by Paul Brook.
 *
 *  Copyright © 2020 by Keith Packard <keithp@keithp.com>
 *  Adapted for systems other than ARM, including RISC-V, by Keith Packard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 *  ARM Semihosting is documented in:
 *     Semihosting for AArch32 and AArch64 Release 2.0
 *     https://static.docs.arm.com/100863/0200/semihosting.pdf
 */

#include "qemu/osdep.h"

#include "cpu.h"
#include "hw/semihosting/semihost.h"
#include "hw/semihosting/console.h"
#include "qemu/log.h"
#ifdef CONFIG_USER_ONLY
#include "qemu.h"

#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
#else
#include "exec/gdbstub.h"
#include "qemu/cutils.h"
#include "hw/arm/boot.h"
#include "hw/boards.h"
#endif

#define TARGET_SYS_OPEN        0x01
#define TARGET_SYS_CLOSE       0x02
#define TARGET_SYS_WRITEC      0x03
#define TARGET_SYS_WRITE0      0x04
#define TARGET_SYS_WRITE       0x05
#define TARGET_SYS_READ        0x06
#define TARGET_SYS_READC       0x07
#define TARGET_SYS_ISTTY       0x09
#define TARGET_SYS_SEEK        0x0a
#define TARGET_SYS_FLEN        0x0c
#define TARGET_SYS_TMPNAM      0x0d
#define TARGET_SYS_REMOVE      0x0e
#define TARGET_SYS_RENAME      0x0f
#define TARGET_SYS_CLOCK       0x10
#define TARGET_SYS_TIME        0x11
#define TARGET_SYS_SYSTEM      0x12
#define TARGET_SYS_ERRNO       0x13
#define TARGET_SYS_GET_CMDLINE 0x15
#define TARGET_SYS_HEAPINFO    0x16
#define TARGET_SYS_EXIT        0x18
#define TARGET_SYS_SYNCCACHE   0x19
#define TARGET_SYS_EXIT_EXTENDED 0x20

/* ADP_Stopped_ApplicationExit is used for exit(0),
 * anything else is implemented as exit(1) */
#define ADP_Stopped_ApplicationExit     (0x20026)

#ifndef O_BINARY
#define O_BINARY 0
#endif

#define GDB_O_RDONLY  0x000
#define GDB_O_WRONLY  0x001
#define GDB_O_RDWR    0x002
#define GDB_O_APPEND  0x008
#define GDB_O_CREAT   0x200
#define GDB_O_TRUNC   0x400
#define GDB_O_BINARY  0

static int gdb_open_modeflags[12] = {
    GDB_O_RDONLY,
    GDB_O_RDONLY | GDB_O_BINARY,
    GDB_O_RDWR,
    GDB_O_RDWR | GDB_O_BINARY,
    GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC,
    GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
    GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC,
    GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
    GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND,
    GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY,
    GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND,
    GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY
};

static int open_modeflags[12] = {
    O_RDONLY,
    O_RDONLY | O_BINARY,
    O_RDWR,
    O_RDWR | O_BINARY,
    O_WRONLY | O_CREAT | O_TRUNC,
    O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
    O_RDWR | O_CREAT | O_TRUNC,
    O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
    O_WRONLY | O_CREAT | O_APPEND,
    O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
    O_RDWR | O_CREAT | O_APPEND,
    O_RDWR | O_CREAT | O_APPEND | O_BINARY
};

typedef enum GuestFDType {
    GuestFDUnused = 0,
    GuestFDHost = 1,
    GuestFDGDB = 2,
    GuestFDFeatureFile = 3,
} GuestFDType;

/*
 * Guest file descriptors are integer indexes into an array of
 * these structures (we will dynamically resize as necessary).
 */
typedef struct GuestFD {
    GuestFDType type;
    union {
        int hostfd;
        target_ulong featurefile_offset;
    };
} GuestFD;

static GArray *guestfd_array;

/*
 * Allocate a new guest file descriptor and return it; if we
 * couldn't allocate a new fd then return -1.
 * This is a fairly simplistic implementation because we don't
 * expect that most semihosting guest programs will make very
 * heavy use of opening and closing fds.
 */
static int alloc_guestfd(void)
{
    guint i;

    if (!guestfd_array) {
        /* New entries zero-initialized, i.e. type GuestFDUnused */
        guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
    }

    /* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
    for (i = 1; i < guestfd_array->len; i++) {
        GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);

        if (gf->type == GuestFDUnused) {
            return i;
        }
    }

    /* All elements already in use: expand the array */
    g_array_set_size(guestfd_array, i + 1);
    return i;
}

/*
 * Look up the guestfd in the data structure; return NULL
 * for out of bounds, but don't check whether the slot is unused.
 * This is used internally by the other guestfd functions.
 */
static GuestFD *do_get_guestfd(int guestfd)
{
    if (!guestfd_array) {
        return NULL;
    }

    if (guestfd <= 0 || guestfd >= guestfd_array->len) {
        return NULL;
    }

    return &g_array_index(guestfd_array, GuestFD, guestfd);
}

/*
 * Associate the specified guest fd (which must have been
 * allocated via alloc_fd() and not previously used) with
 * the specified host/gdb fd.
 */
static void associate_guestfd(int guestfd, int hostfd)
{
    GuestFD *gf = do_get_guestfd(guestfd);

    assert(gf);
    gf->type = use_gdb_syscalls() ? GuestFDGDB : GuestFDHost;
    gf->hostfd = hostfd;
}

/*
 * Deallocate the specified guest file descriptor. This doesn't
 * close the host fd, it merely undoes the work of alloc_fd().
 */
static void dealloc_guestfd(int guestfd)
{
    GuestFD *gf = do_get_guestfd(guestfd);

    assert(gf);
    gf->type = GuestFDUnused;
}

/*
 * Given a guest file descriptor, get the associated struct.
 * If the fd is not valid, return NULL. This is the function
 * used by the various semihosting calls to validate a handle
 * from the guest.
 * Note: calling alloc_guestfd() or dealloc_guestfd() will
 * invalidate any GuestFD* obtained by calling this function.
 */
static GuestFD *get_guestfd(int guestfd)
{
    GuestFD *gf = do_get_guestfd(guestfd);

    if (!gf || gf->type == GuestFDUnused) {
        return NULL;
    }
    return gf;
}

/*
 * The semihosting API has no concept of its errno being thread-safe,
 * as the API design predates SMP CPUs and was intended as a simple
 * real-hardware set of debug functionality. For QEMU, we make the
 * errno be per-thread in linux-user mode; in softmmu it is a simple
 * global, and we assume that the guest takes care of avoiding any races.
 */
#ifndef CONFIG_USER_ONLY
static target_ulong syscall_err;

#include "exec/softmmu-semi.h"
#endif

static inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code)
{
    if (code == (uint32_t)-1) {
#ifdef CONFIG_USER_ONLY
        CPUState *cs = env_cpu(env);
        TaskState *ts = cs->opaque;

        ts->swi_errno = errno;
#else
        syscall_err = errno;
#endif
    }
    return code;
}

static inline uint32_t get_swi_errno(CPUARMState *env)
{
#ifdef CONFIG_USER_ONLY
    CPUState *cs = env_cpu(env);
    TaskState *ts = cs->opaque;

    return ts->swi_errno;
#else
    return syscall_err;
#endif
}

static target_ulong arm_semi_syscall_len;

static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    target_ulong reg0 = is_a64(env) ? env->xregs[0] : env->regs[0];

    if (ret == (target_ulong)-1) {
        errno = err;
        set_swi_errno(env, -1);
        reg0 = ret;
    } else {
        /* Fixup syscalls that use nonstardard return conventions.  */
        switch (reg0) {
        case TARGET_SYS_WRITE:
        case TARGET_SYS_READ:
            reg0 = arm_semi_syscall_len - ret;
            break;
        case TARGET_SYS_SEEK:
            reg0 = 0;
            break;
        default:
            reg0 = ret;
            break;
        }
    }
    if (is_a64(env)) {
        env->xregs[0] = reg0;
    } else {
        env->regs[0] = reg0;
    }
}

static target_ulong arm_flen_buf(ARMCPU *cpu)
{
    /* Return an address in target memory of 64 bytes where the remote
     * gdb should write its stat struct. (The format of this structure
     * is defined by GDB's remote protocol and is not target-specific.)
     * We put this on the guest's stack just below SP.
     */
    CPUARMState *env = &cpu->env;
    target_ulong sp;

    if (is_a64(env)) {
        sp = env->xregs[31];
    } else {
        sp = env->regs[13];
    }

    return sp - 64;
}

static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    /* The size is always stored in big-endian order, extract
       the value. We assume the size always fit in 32 bits.  */
    uint32_t size;
    cpu_memory_rw_debug(cs, arm_flen_buf(cpu) + 32, (uint8_t *)&size, 4, 0);
    size = be32_to_cpu(size);
    if (is_a64(env)) {
        env->xregs[0] = size;
    } else {
        env->regs[0] = size;
    }
    errno = err;
    set_swi_errno(env, -1);
}

static int arm_semi_open_guestfd;

static void arm_semi_open_cb(CPUState *cs, target_ulong ret, target_ulong err)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    if (ret == (target_ulong)-1) {
        errno = err;
        set_swi_errno(env, -1);
        dealloc_guestfd(arm_semi_open_guestfd);
    } else {
        associate_guestfd(arm_semi_open_guestfd, ret);
        ret = arm_semi_open_guestfd;
    }

    if (is_a64(env)) {
        env->xregs[0] = ret;
    } else {
        env->regs[0] = ret;
    }
}

static target_ulong arm_gdb_syscall(ARMCPU *cpu, gdb_syscall_complete_cb cb,
                                    const char *fmt, ...)
{
    va_list va;
    CPUARMState *env = &cpu->env;

    va_start(va, fmt);
    gdb_do_syscallv(cb, fmt, va);
    va_end(va);

    /*
     * FIXME: in softmmu mode, the gdbstub will schedule our callback
     * to occur, but will not actually call it to complete the syscall
     * until after this function has returned and we are back in the
     * CPU main loop. Therefore callers to this function must not
     * do anything with its return value, because it is not necessarily
     * the result of the syscall, but could just be the old value of X0.
     * The only thing safe to do with this is that the callers of
     * do_common_semihosting() will write it straight back into X0.
     * (In linux-user mode, the callback will have happened before
     * gdb_do_syscallv() returns.)
     *
     * We should tidy this up so neither this function nor
     * do_common_semihosting() return a value, so the mistake of
     * doing something with the return value is not possible to make.
     */

    return is_a64(env) ? env->xregs[0] : env->regs[0];
}

/*
 * Types for functions implementing various semihosting calls
 * for specific types of guest file descriptor. These must all
 * do the work and return the required return value for the guest,
 * setting the guest errno if appropriate.
 */
typedef uint32_t sys_closefn(ARMCPU *cpu, GuestFD *gf);
typedef uint32_t sys_writefn(ARMCPU *cpu, GuestFD *gf,
                             target_ulong buf, uint32_t len);
typedef uint32_t sys_readfn(ARMCPU *cpu, GuestFD *gf,
                            target_ulong buf, uint32_t len);
typedef uint32_t sys_isattyfn(ARMCPU *cpu, GuestFD *gf);
typedef uint32_t sys_seekfn(ARMCPU *cpu, GuestFD *gf,
                            target_ulong offset);
typedef uint32_t sys_flenfn(ARMCPU *cpu, GuestFD *gf);

static uint32_t host_closefn(ARMCPU *cpu, GuestFD *gf)
{
    CPUARMState *env = &cpu->env;

    /*
     * 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) {
        return 0;
    }
    return set_swi_errno(env, close(gf->hostfd));
}

static uint32_t host_writefn(ARMCPU *cpu, GuestFD *gf,
                             target_ulong buf, uint32_t len)
{
    uint32_t ret;
    CPUARMState *env = &cpu->env;
    char *s = lock_user(VERIFY_READ, buf, len, 1);
    if (!s) {
        /* Return bytes not written on error */
        return len;
    }
    ret = set_swi_errno(env, write(gf->hostfd, s, len));
    unlock_user(s, buf, 0);
    if (ret == (uint32_t)-1) {
        ret = 0;
    }
    /* Return bytes not written */
    return len - ret;
}

static uint32_t host_readfn(ARMCPU *cpu, GuestFD *gf,
                            target_ulong buf, uint32_t len)
{
    uint32_t ret;
    CPUARMState *env = &cpu->env;
    char *s = lock_user(VERIFY_WRITE, buf, len, 0);
    if (!s) {
        /* return bytes not read */
        return len;
    }
    do {
        ret = set_swi_errno(env, read(gf->hostfd, s, len));
    } while (ret == -1 && errno == EINTR);
    unlock_user(s, buf, len);
    if (ret == (uint32_t)-1) {
        ret = 0;
    }
    /* Return bytes not read */
    return len - ret;
}

static uint32_t host_isattyfn(ARMCPU *cpu, GuestFD *gf)
{
    return isatty(gf->hostfd);
}

static uint32_t host_seekfn(ARMCPU *cpu, GuestFD *gf, target_ulong offset)
{
    CPUARMState *env = &cpu->env;
    uint32_t ret = set_swi_errno(env, lseek(gf->hostfd, offset, SEEK_SET));
    if (ret == (uint32_t)-1) {
        return -1;
    }
    return 0;
}

static uint32_t host_flenfn(ARMCPU *cpu, GuestFD *gf)
{
    CPUARMState *env = &cpu->env;
    struct stat buf;
    uint32_t ret = set_swi_errno(env, fstat(gf->hostfd, &buf));
    if (ret == (uint32_t)-1) {
        return -1;
    }
    return buf.st_size;
}

static uint32_t gdb_closefn(ARMCPU *cpu, GuestFD *gf)
{
    return arm_gdb_syscall(cpu, arm_semi_cb, "close,%x", gf->hostfd);
}

static uint32_t gdb_writefn(ARMCPU *cpu, GuestFD *gf,
                            target_ulong buf, uint32_t len)
{
    arm_semi_syscall_len = len;
    return arm_gdb_syscall(cpu, arm_semi_cb, "write,%x,%x,%x",
                           gf->hostfd, buf, len);
}

static uint32_t gdb_readfn(ARMCPU *cpu, GuestFD *gf,
                           target_ulong buf, uint32_t len)
{
    arm_semi_syscall_len = len;
    return arm_gdb_syscall(cpu, arm_semi_cb, "read,%x,%x,%x",
                           gf->hostfd, buf, len);
}

static uint32_t gdb_isattyfn(ARMCPU *cpu, GuestFD *gf)
{
    return arm_gdb_syscall(cpu, arm_semi_cb, "isatty,%x", gf->hostfd);
}

static uint32_t gdb_seekfn(ARMCPU *cpu, GuestFD *gf, target_ulong offset)
{
    return arm_gdb_syscall(cpu, arm_semi_cb, "lseek,%x,%x,0",
                           gf->hostfd, offset);
}

static uint32_t gdb_flenfn(ARMCPU *cpu, GuestFD *gf)
{
    return arm_gdb_syscall(cpu, arm_semi_flen_cb, "fstat,%x,%x",
                           gf->hostfd, arm_flen_buf(cpu));
}

#define SHFB_MAGIC_0 0x53
#define SHFB_MAGIC_1 0x48
#define SHFB_MAGIC_2 0x46
#define SHFB_MAGIC_3 0x42

/* Feature bits reportable in feature byte 0 */
#define SH_EXT_EXIT_EXTENDED (1 << 0)
#define SH_EXT_STDOUT_STDERR (1 << 1)

static const uint8_t featurefile_data[] = {
    SHFB_MAGIC_0,
    SHFB_MAGIC_1,
    SHFB_MAGIC_2,
    SHFB_MAGIC_3,
    SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
};

static void init_featurefile_guestfd(int guestfd)
{
    GuestFD *gf = do_get_guestfd(guestfd);

    assert(gf);
    gf->type = GuestFDFeatureFile;
    gf->featurefile_offset = 0;
}

static uint32_t featurefile_closefn(ARMCPU *cpu, GuestFD *gf)
{
    /* Nothing to do */
    return 0;
}

static uint32_t featurefile_writefn(ARMCPU *cpu, GuestFD *gf,
                                    target_ulong buf, uint32_t len)
{
    /* This fd can never be open for writing */
    CPUARMState *env = &cpu->env;

    errno = EBADF;
    return set_swi_errno(env, -1);
}

static uint32_t featurefile_readfn(ARMCPU *cpu, GuestFD *gf,
                                   target_ulong buf, uint32_t len)
{
    uint32_t i;
#ifndef CONFIG_USER_ONLY
    CPUARMState *env = &cpu->env;
#endif
    char *s;

    s = lock_user(VERIFY_WRITE, buf, len, 0);
    if (!s) {
        return len;
    }

    for (i = 0; i < len; i++) {
        if (gf->featurefile_offset >= sizeof(featurefile_data)) {
            break;
        }
        s[i] = featurefile_data[gf->featurefile_offset];
        gf->featurefile_offset++;
    }

    unlock_user(s, buf, len);

    /* Return number of bytes not read */
    return len - i;
}

static uint32_t featurefile_isattyfn(ARMCPU *cpu, GuestFD *gf)
{
    return 0;
}

static uint32_t featurefile_seekfn(ARMCPU *cpu, GuestFD *gf,
                                   target_ulong offset)
{
    gf->featurefile_offset = offset;
    return 0;
}

static uint32_t featurefile_flenfn(ARMCPU *cpu, GuestFD *gf)
{
    return sizeof(featurefile_data);
}

typedef struct GuestFDFunctions {
    sys_closefn *closefn;
    sys_writefn *writefn;
    sys_readfn *readfn;
    sys_isattyfn *isattyfn;
    sys_seekfn *seekfn;
    sys_flenfn *flenfn;
} GuestFDFunctions;

static const GuestFDFunctions guestfd_fns[] = {
    [GuestFDHost] = {
        .closefn = host_closefn,
        .writefn = host_writefn,
        .readfn = host_readfn,
        .isattyfn = host_isattyfn,
        .seekfn = host_seekfn,
        .flenfn = host_flenfn,
    },
    [GuestFDGDB] = {
        .closefn = gdb_closefn,
        .writefn = gdb_writefn,
        .readfn = gdb_readfn,
        .isattyfn = gdb_isattyfn,
        .seekfn = gdb_seekfn,
        .flenfn = gdb_flenfn,
    },
    [GuestFDFeatureFile] = {
        .closefn = featurefile_closefn,
        .writefn = featurefile_writefn,
        .readfn = featurefile_readfn,
        .isattyfn = featurefile_isattyfn,
        .seekfn = featurefile_seekfn,
        .flenfn = featurefile_flenfn,
    },
};

/* Read the input value from the argument block; fail the semihosting
 * call if the memory read fails.
 */
#define GET_ARG(n) do {                                 \
    if (is_a64(env)) {                                  \
        if (get_user_u64(arg ## n, args + (n) * 8)) {   \
            errno = EFAULT;                             \
            return set_swi_errno(env, -1);              \
        }                                               \
    } else {                                            \
        if (get_user_u32(arg ## n, args + (n) * 4)) {   \
            errno = EFAULT;                             \
            return set_swi_errno(env, -1);              \
        }                                               \
    }                                                   \
} while (0)

#define SET_ARG(n, val)                                 \
    (is_a64(env) ?                                      \
     put_user_u64(val, args + (n) * 8) :                \
     put_user_u32(val, args + (n) * 4))

/*
 * Do a semihosting call.
 *
 * The specification always says that the "return register" either
 * returns a specific value or is corrupted, so we don't need to
 * report to our caller whether we are returning a value or trying to
 * leave the register unchanged. We use 0xdeadbeef as the return value
 * when there isn't a defined return value for the call.
 */
target_ulong do_common_semihosting(CPUState *cs)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    target_ulong args;
    target_ulong arg0, arg1, arg2, arg3;
    char * s;
    int nr;
    uint32_t ret;
    uint32_t len;
    GuestFD *gf;

    if (is_a64(env)) {
        /* Note that the syscall number is in W0, not X0 */
        nr = env->xregs[0] & 0xffffffffU;
        args = env->xregs[1];
    } else {
        nr = env->regs[0];
        args = env->regs[1];
    }

    switch (nr) {
    case TARGET_SYS_OPEN:
    {
        int guestfd;

        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        s = lock_user_string(arg0);
        if (!s) {
            errno = EFAULT;
            return set_swi_errno(env, -1);
        }
        if (arg1 >= 12) {
            unlock_user(s, arg0, 0);
            errno = EINVAL;
            return set_swi_errno(env, -1);
        }

        guestfd = alloc_guestfd();
        if (guestfd < 0) {
            unlock_user(s, arg0, 0);
            errno = EMFILE;
            return set_swi_errno(env, -1);
        }

        if (strcmp(s, ":tt") == 0) {
            int result_fileno;

            /*
             * We implement SH_EXT_STDOUT_STDERR, so:
             *  open for read == stdin
             *  open for write == stdout
             *  open for append == stderr
             */
            if (arg1 < 4) {
                result_fileno = STDIN_FILENO;
            } else if (arg1 < 8) {
                result_fileno = STDOUT_FILENO;
            } else {
                result_fileno = STDERR_FILENO;
            }
            associate_guestfd(guestfd, result_fileno);
            unlock_user(s, arg0, 0);
            return guestfd;
        }
        if (strcmp(s, ":semihosting-features") == 0) {
            unlock_user(s, arg0, 0);
            /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
            if (arg1 != 0 && arg1 != 1) {
                dealloc_guestfd(guestfd);
                errno = EACCES;
                return set_swi_errno(env, -1);
            }
            init_featurefile_guestfd(guestfd);
            return guestfd;
        }

        if (use_gdb_syscalls()) {
            arm_semi_open_guestfd = guestfd;
            ret = arm_gdb_syscall(cpu, arm_semi_open_cb, "open,%s,%x,1a4", arg0,
                                  (int)arg2 + 1, gdb_open_modeflags[arg1]);
        } else {
            ret = set_swi_errno(env, open(s, open_modeflags[arg1], 0644));
            if (ret == (uint32_t)-1) {
                dealloc_guestfd(guestfd);
            } else {
                associate_guestfd(guestfd, ret);
                ret = guestfd;
            }
        }
        unlock_user(s, arg0, 0);
        return ret;
    }
    case TARGET_SYS_CLOSE:
        GET_ARG(0);

        gf = get_guestfd(arg0);
        if (!gf) {
            errno = EBADF;
            return set_swi_errno(env, -1);
        }

        ret = guestfd_fns[gf->type].closefn(cpu, gf);
        dealloc_guestfd(arg0);
        return ret;
    case TARGET_SYS_WRITEC:
        qemu_semihosting_console_outc(env, args);
        return 0xdeadbeef;
    case TARGET_SYS_WRITE0:
        return qemu_semihosting_console_outs(env, args);
    case TARGET_SYS_WRITE:
        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        len = arg2;

        gf = get_guestfd(arg0);
        if (!gf) {
            errno = EBADF;
            return set_swi_errno(env, -1);
        }

        return guestfd_fns[gf->type].writefn(cpu, gf, arg1, len);
    case TARGET_SYS_READ:
        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        len = arg2;

        gf = get_guestfd(arg0);
        if (!gf) {
            errno = EBADF;
            return set_swi_errno(env, -1);
        }

        return guestfd_fns[gf->type].readfn(cpu, gf, arg1, len);
    case TARGET_SYS_READC:
        return qemu_semihosting_console_inc(env);
    case TARGET_SYS_ISTTY:
        GET_ARG(0);

        gf = get_guestfd(arg0);
        if (!gf) {
            errno = EBADF;
            return set_swi_errno(env, -1);
        }

        return guestfd_fns[gf->type].isattyfn(cpu, gf);
    case TARGET_SYS_SEEK:
        GET_ARG(0);
        GET_ARG(1);

        gf = get_guestfd(arg0);
        if (!gf) {
            errno = EBADF;
            return set_swi_errno(env, -1);
        }

        return guestfd_fns[gf->type].seekfn(cpu, gf, arg1);
    case TARGET_SYS_FLEN:
        GET_ARG(0);

        gf = get_guestfd(arg0);
        if (!gf) {
            errno = EBADF;
            return set_swi_errno(env, -1);
        }

        return guestfd_fns[gf->type].flenfn(cpu, gf);
    case TARGET_SYS_TMPNAM:
        qemu_log_mask(LOG_UNIMP, "%s: SYS_TMPNAM not implemented", __func__);
        return -1;
    case TARGET_SYS_REMOVE:
        GET_ARG(0);
        GET_ARG(1);
        if (use_gdb_syscalls()) {
            ret = arm_gdb_syscall(cpu, arm_semi_cb, "unlink,%s",
                                  arg0, (int)arg1 + 1);
        } else {
            s = lock_user_string(arg0);
            if (!s) {
                errno = EFAULT;
                return set_swi_errno(env, -1);
            }
            ret =  set_swi_errno(env, remove(s));
            unlock_user(s, arg0, 0);
        }
        return ret;
    case TARGET_SYS_RENAME:
        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        GET_ARG(3);
        if (use_gdb_syscalls()) {
            return arm_gdb_syscall(cpu, arm_semi_cb, "rename,%s,%s",
                                   arg0, (int)arg1 + 1, arg2, (int)arg3 + 1);
        } else {
            char *s2;
            s = lock_user_string(arg0);
            s2 = lock_user_string(arg2);
            if (!s || !s2) {
                errno = EFAULT;
                ret = set_swi_errno(env, -1);
            } else {
                ret = set_swi_errno(env, rename(s, s2));
            }
            if (s2)
                unlock_user(s2, arg2, 0);
            if (s)
                unlock_user(s, arg0, 0);
            return ret;
        }
    case TARGET_SYS_CLOCK:
        return clock() / (CLOCKS_PER_SEC / 100);
    case TARGET_SYS_TIME:
        return set_swi_errno(env, time(NULL));
    case TARGET_SYS_SYSTEM:
        GET_ARG(0);
        GET_ARG(1);
        if (use_gdb_syscalls()) {
            return arm_gdb_syscall(cpu, arm_semi_cb, "system,%s",
                                   arg0, (int)arg1 + 1);
        } else {
            s = lock_user_string(arg0);
            if (!s) {
                errno = EFAULT;
                return set_swi_errno(env, -1);
            }
            ret = set_swi_errno(env, system(s));
            unlock_user(s, arg0, 0);
            return ret;
        }
    case TARGET_SYS_ERRNO:
        return get_swi_errno(env);
    case TARGET_SYS_GET_CMDLINE:
        {
            /* Build a command-line from the original argv.
             *
             * The inputs are:
             *     * arg0, pointer to a buffer of at least the size
             *               specified in arg1.
             *     * arg1, size of the buffer pointed to by arg0 in
             *               bytes.
             *
             * The outputs are:
             *     * arg0, pointer to null-terminated string of the
             *               command line.
             *     * arg1, length of the string pointed to by arg0.
             */

            char *output_buffer;
            size_t input_size;
            size_t output_size;
            int status = 0;
#if !defined(CONFIG_USER_ONLY)
            const char *cmdline;
#else
            TaskState *ts = cs->opaque;
#endif
            GET_ARG(0);
            GET_ARG(1);
            input_size = arg1;
            /* Compute the size of the output string.  */
#if !defined(CONFIG_USER_ONLY)
            cmdline = semihosting_get_cmdline();
            if (cmdline == NULL) {
                cmdline = ""; /* Default to an empty line. */
            }
            output_size = strlen(cmdline) + 1; /* Count terminating 0. */
#else
            unsigned int i;

            output_size = ts->info->arg_end - ts->info->arg_start;
            if (!output_size) {
                /*
                 * We special-case the "empty command line" case (argc==0).
                 * Just provide the terminating 0.
                 */
                output_size = 1;
            }
#endif

            if (output_size > input_size) {
                /* Not enough space to store command-line arguments.  */
                errno = E2BIG;
                return set_swi_errno(env, -1);
            }

            /* Adjust the command-line length.  */
            if (SET_ARG(1, output_size - 1)) {
                /* Couldn't write back to argument block */
                errno = EFAULT;
                return set_swi_errno(env, -1);
            }

            /* Lock the buffer on the ARM side.  */
            output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0);
            if (!output_buffer) {
                errno = EFAULT;
                return set_swi_errno(env, -1);
            }

            /* Copy the command-line arguments.  */
#if !defined(CONFIG_USER_ONLY)
            pstrcpy(output_buffer, output_size, cmdline);
#else
            if (output_size == 1) {
                /* Empty command-line.  */
                output_buffer[0] = '\0';
                goto out;
            }

            if (copy_from_user(output_buffer, ts->info->arg_start,
                               output_size)) {
                errno = EFAULT;
                status = set_swi_errno(env, -1);
                goto out;
            }

            /* Separate arguments by white spaces.  */
            for (i = 0; i < output_size - 1; i++) {
                if (output_buffer[i] == 0) {
                    output_buffer[i] = ' ';
                }
            }
        out:
#endif
            /* Unlock the buffer on the ARM side.  */
            unlock_user(output_buffer, arg0, output_size);

            return status;
        }
    case TARGET_SYS_HEAPINFO:
        {
            target_ulong retvals[4];
            target_ulong limit;
            int i;
#ifdef CONFIG_USER_ONLY
            TaskState *ts = cs->opaque;
#else
            const struct arm_boot_info *info = env->boot_info;
            target_ulong rambase = info->loader_start;
#endif

            GET_ARG(0);

#ifdef CONFIG_USER_ONLY
            /*
             * Some C libraries assume the heap immediately follows .bss, so
             * allocate it using sbrk.
             */
            if (!ts->heap_limit) {
                abi_ulong ret;

                ts->heap_base = do_brk(0);
                limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
                /* Try a big heap, and reduce the size if that fails.  */
                for (;;) {
                    ret = do_brk(limit);
                    if (ret >= limit) {
                        break;
                    }
                    limit = (ts->heap_base >> 1) + (limit >> 1);
                }
                ts->heap_limit = limit;
            }

            retvals[0] = ts->heap_base;
            retvals[1] = ts->heap_limit;
            retvals[2] = ts->stack_base;
            retvals[3] = 0; /* Stack limit.  */
#else
            limit = current_machine->ram_size;
            /* TODO: Make this use the limit of the loaded application.  */
            retvals[0] = rambase + limit / 2;
            retvals[1] = rambase + limit;
            retvals[2] = rambase + limit; /* Stack base */
            retvals[3] = rambase; /* Stack limit.  */
#endif

            for (i = 0; i < ARRAY_SIZE(retvals); i++) {
                bool fail;

                if (is_a64(env)) {
                    fail = put_user_u64(retvals[i], arg0 + i * 8);
                } else {
                    fail = put_user_u32(retvals[i], arg0 + i * 4);
                }

                if (fail) {
                    /* Couldn't write back to argument block */
                    errno = EFAULT;
                    return set_swi_errno(env, -1);
                }
            }
            return 0;
        }
    case TARGET_SYS_EXIT:
    case TARGET_SYS_EXIT_EXTENDED:
        if (nr == TARGET_SYS_EXIT_EXTENDED || is_a64(env)) {
            /*
             * The A64 version of SYS_EXIT takes a parameter block,
             * so the application-exit type can return a subcode which
             * is the exit status code from the application.
             * SYS_EXIT_EXTENDED is an a new-in-v2.0 optional function
             * which allows A32/T32 guests to also provide a status code.
             */
            GET_ARG(0);
            GET_ARG(1);

            if (arg0 == ADP_Stopped_ApplicationExit) {
                ret = arg1;
            } else {
                ret = 1;
            }
        } else {
            /*
             * The A32/T32 version of SYS_EXIT specifies only
             * Stopped_ApplicationExit as normal exit, but does not
             * allow the guest to specify the exit status code.
             * Everything else is considered an error.
             */
            ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
        }
        gdb_exit(ret);
        exit(ret);
    case TARGET_SYS_SYNCCACHE:
        /*
         * Clean the D-cache and invalidate the I-cache for the specified
         * virtual address range. This is a nop for us since we don't
         * implement caches. This is only present on A64.
         */
        if (is_a64(env)) {
            return 0;
        }
        /* fall through -- invalid for A32/T32 */
    default:
        fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
        cpu_dump_state(cs, stderr, 0);
        abort();
    }
}
