/*
 *  Semihosting support for systems modeled on the Arm "Angel"
 *  semihosting syscalls design. This includes Arm and RISC-V processors
 *
 *  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://github.com/ARM-software/abi-aa/blob/main/semihosting/semihosting.rst
 *
 *  RISC-V Semihosting is documented in:
 *     RISC-V Semihosting
 *     https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc
 */

#include "qemu/osdep.h"
#include "qemu/timer.h"
#include "exec/gdbstub.h"
#include "gdbstub/syscalls.h"
#include "semihosting/semihost.h"
#include "semihosting/console.h"
#include "semihosting/common-semi.h"
#include "semihosting/guestfd.h"
#include "semihosting/syscalls.h"

#ifdef CONFIG_USER_ONLY
#include "qemu.h"

#define COMMON_SEMI_HEAP_SIZE (128 * 1024 * 1024)
#else
#include "qemu/cutils.h"
#include "hw/loader.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_ISERROR     0x08
#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
#define TARGET_SYS_ELAPSED     0x30
#define TARGET_SYS_TICKFREQ    0x31

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

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

#ifndef CONFIG_USER_ONLY

/**
 * common_semi_find_bases: find information about ram and heap base
 *
 * This function attempts to provide meaningful numbers for RAM and
 * HEAP base addresses. The rambase is simply the lowest addressable
 * RAM position. For the heapbase we ask the loader to scan the
 * address space and the largest available gap by querying the "ROM"
 * regions.
 *
 * Returns: a structure with the numbers we need.
 */

typedef struct LayoutInfo {
    target_ulong rambase;
    size_t ramsize;
    hwaddr heapbase;
    hwaddr heaplimit;
} LayoutInfo;

static bool find_ram_cb(Int128 start, Int128 len, const MemoryRegion *mr,
                        hwaddr offset_in_region, void *opaque)
{
    LayoutInfo *info = (LayoutInfo *) opaque;
    uint64_t size = int128_get64(len);

    if (!mr->ram || mr->readonly) {
        return false;
    }

    if (size > info->ramsize) {
        info->rambase = int128_get64(start);
        info->ramsize = size;
    }

    /* search exhaustively for largest RAM */
    return false;
}

static LayoutInfo common_semi_find_bases(CPUState *cs)
{
    FlatView *fv;
    LayoutInfo info = { 0, 0, 0, 0 };

    RCU_READ_LOCK_GUARD();

    fv = address_space_to_flatview(cs->as);
    flatview_for_each_range(fv, find_ram_cb, &info);

    /*
     * If we have found the RAM lets iterate through the ROM blobs to
     * work out the best place for the remainder of RAM and split it
     * equally between stack and heap.
     */
    if (info.rambase || info.ramsize > 0) {
        RomGap gap = rom_find_largest_gap_between(info.rambase, info.ramsize);
        info.heapbase = gap.base;
        info.heaplimit = gap.base + gap.size;
    }

    return info;
}

#endif

#include "common-semi-target.h"

/*
 * Read the input value from the argument block; fail the semihosting
 * call if the memory read fails. Eventually we could use a generic
 * CPUState helper function here.
 * Note that GET_ARG() handles memory access errors by jumping to
 * do_fault, so must be used as the first thing done in handling a
 * semihosting call, to avoid accidentally leaking allocated resources.
 * SET_ARG(), since it unavoidably happens late, instead returns an
 * error indication (0 on success, non-0 for error) which the caller
 * should check.
 */

#define GET_ARG(n) do {                                 \
    if (is_64bit_semihosting(env)) {                    \
        if (get_user_u64(arg ## n, args + (n) * 8)) {   \
            goto do_fault;                              \
        }                                               \
    } else {                                            \
        if (get_user_u32(arg ## n, args + (n) * 4)) {   \
            goto do_fault;                              \
        }                                               \
    }                                                   \
} while (0)

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


/*
 * 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 "semihosting/softmmu-uaccess.h"
#endif

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

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

static void common_semi_cb(CPUState *cs, uint64_t ret, int err)
{
    if (err) {
#ifdef CONFIG_USER_ONLY
        TaskState *ts = cs->opaque;
        ts->swi_errno = err;
#else
        syscall_err = err;
#endif
    }
    common_semi_set_ret(cs, ret);
}

/*
 * Use 0xdeadbeef as the return value when there isn't a defined
 * return value for the call.
 */
static void common_semi_dead_cb(CPUState *cs, uint64_t ret, int err)
{
    common_semi_set_ret(cs, 0xdeadbeef);
}

/*
 * SYS_READ and SYS_WRITE always return the number of bytes not read/written.
 * There is no error condition, other than returning the original length.
 */
static void common_semi_rw_cb(CPUState *cs, uint64_t ret, int err)
{
    /* Recover the original length from the third argument. */
    CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
    target_ulong args = common_semi_arg(cs, 1);
    target_ulong arg2;
    GET_ARG(2);

    if (err) {
 do_fault:
        ret = 0; /* error: no bytes transmitted */
    }
    common_semi_set_ret(cs, arg2 - ret);
}

/*
 * Convert from Posix ret+errno to Arm SYS_ISTTY return values.
 * With gdbstub, err is only ever set for protocol errors to EIO.
 */
static void common_semi_istty_cb(CPUState *cs, uint64_t ret, int err)
{
    if (err) {
        ret = (err == ENOTTY ? 0 : -1);
    }
    common_semi_cb(cs, ret, err);
}

/*
 * SYS_SEEK returns 0 on success, not the resulting offset.
 */
static void common_semi_seek_cb(CPUState *cs, uint64_t ret, int err)
{
    if (!err) {
        ret = 0;
    }
    common_semi_cb(cs, ret, err);
}

/*
 * 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.
 */
static target_ulong common_semi_flen_buf(CPUState *cs)
{
    target_ulong sp = common_semi_stack_bottom(cs);
    return sp - 64;
}

static void
common_semi_flen_fstat_cb(CPUState *cs, uint64_t ret, int err)
{
    if (!err) {
        /* The size is always stored in big-endian order, extract the value. */
        uint64_t size;
        if (cpu_memory_rw_debug(cs, common_semi_flen_buf(cs) +
                                offsetof(struct gdb_stat, gdb_st_size),
                                &size, 8, 0)) {
            ret = -1, err = EFAULT;
        } else {
            size = be64_to_cpu(size);
            if (ret != size) {
                ret = -1, err = EOVERFLOW;
            }
        }
    }
    common_semi_cb(cs, ret, err);
}

static void
common_semi_readc_cb(CPUState *cs, uint64_t ret, int err)
{
    if (!err) {
        CPUArchState *env G_GNUC_UNUSED = cpu_env(cs);
        uint8_t ch;

        if (get_user_u8(ch, common_semi_stack_bottom(cs) - 1)) {
            ret = -1, err = EFAULT;
        } else {
            ret = ch;
        }
    }
    common_semi_cb(cs, ret, err);
}

#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 */
};

/*
 * 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.
 */
void do_common_semihosting(CPUState *cs)
{
    CPUArchState *env = cpu_env(cs);
    target_ulong args;
    target_ulong arg0, arg1, arg2, arg3;
    target_ulong ul_ret;
    char * s;
    int nr;
    int64_t elapsed;

    nr = common_semi_arg(cs, 0) & 0xffffffffU;
    args = common_semi_arg(cs, 1);

    switch (nr) {
    case TARGET_SYS_OPEN:
    {
        int ret, err = 0;
        int hostfd;

        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        s = lock_user_string(arg0);
        if (!s) {
            goto do_fault;
        }
        if (arg1 >= 12) {
            unlock_user(s, arg0, 0);
            common_semi_cb(cs, -1, EINVAL);
            break;
        }

        if (strcmp(s, ":tt") == 0) {
            /*
             * We implement SH_EXT_STDOUT_STDERR, so:
             *  open for read == stdin
             *  open for write == stdout
             *  open for append == stderr
             */
            if (arg1 < 4) {
                hostfd = STDIN_FILENO;
            } else if (arg1 < 8) {
                hostfd = STDOUT_FILENO;
            } else {
                hostfd = STDERR_FILENO;
            }
            ret = alloc_guestfd();
            associate_guestfd(ret, hostfd);
        } else if (strcmp(s, ":semihosting-features") == 0) {
            /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
            if (arg1 != 0 && arg1 != 1) {
                ret = -1;
                err = EACCES;
            } else {
                ret = alloc_guestfd();
                staticfile_guestfd(ret, featurefile_data,
                                   sizeof(featurefile_data));
            }
        } else {
            unlock_user(s, arg0, 0);
            semihost_sys_open(cs, common_semi_cb, arg0, arg2 + 1,
                              gdb_open_modeflags[arg1], 0644);
            break;
        }
        unlock_user(s, arg0, 0);
        common_semi_cb(cs, ret, err);
        break;
    }

    case TARGET_SYS_CLOSE:
        GET_ARG(0);
        semihost_sys_close(cs, common_semi_cb, arg0);
        break;

    case TARGET_SYS_WRITEC:
        /*
         * FIXME: the byte to be written is in a target_ulong slot,
         * which means this is wrong for a big-endian guest.
         */
        semihost_sys_write_gf(cs, common_semi_dead_cb,
                              &console_out_gf, args, 1);
        break;

    case TARGET_SYS_WRITE0:
        {
            ssize_t len = target_strlen(args);
            if (len < 0) {
                common_semi_dead_cb(cs, -1, EFAULT);
            } else {
                semihost_sys_write_gf(cs, common_semi_dead_cb,
                                      &console_out_gf, args, len);
            }
        }
        break;

    case TARGET_SYS_WRITE:
        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        semihost_sys_write(cs, common_semi_rw_cb, arg0, arg1, arg2);
        break;

    case TARGET_SYS_READ:
        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        semihost_sys_read(cs, common_semi_rw_cb, arg0, arg1, arg2);
        break;

    case TARGET_SYS_READC:
        semihost_sys_read_gf(cs, common_semi_readc_cb, &console_in_gf,
                             common_semi_stack_bottom(cs) - 1, 1);
        break;

    case TARGET_SYS_ISERROR:
        GET_ARG(0);
        common_semi_set_ret(cs, (target_long)arg0 < 0);
        break;

    case TARGET_SYS_ISTTY:
        GET_ARG(0);
        semihost_sys_isatty(cs, common_semi_istty_cb, arg0);
        break;

    case TARGET_SYS_SEEK:
        GET_ARG(0);
        GET_ARG(1);
        semihost_sys_lseek(cs, common_semi_seek_cb, arg0, arg1, GDB_SEEK_SET);
        break;

    case TARGET_SYS_FLEN:
        GET_ARG(0);
        semihost_sys_flen(cs, common_semi_flen_fstat_cb, common_semi_cb,
                          arg0, common_semi_flen_buf(cs));
        break;

    case TARGET_SYS_TMPNAM:
    {
        int len;
        char *p;

        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        len = asprintf(&s, "%s/qemu-%x%02x", g_get_tmp_dir(),
                       getpid(), (int)arg1 & 0xff);
        if (len < 0) {
            common_semi_set_ret(cs, -1);
            break;
        }

        /* Allow for trailing NUL */
        len++;
        /* Make sure there's enough space in the buffer */
        if (len > arg2) {
            free(s);
            common_semi_set_ret(cs, -1);
            break;
        }
        p = lock_user(VERIFY_WRITE, arg0, len, 0);
        if (!p) {
            free(s);
            goto do_fault;
        }
        memcpy(p, s, len);
        unlock_user(p, arg0, len);
        free(s);
        common_semi_set_ret(cs, 0);
        break;
    }

    case TARGET_SYS_REMOVE:
        GET_ARG(0);
        GET_ARG(1);
        semihost_sys_remove(cs, common_semi_cb, arg0, arg1 + 1);
        break;

    case TARGET_SYS_RENAME:
        GET_ARG(0);
        GET_ARG(1);
        GET_ARG(2);
        GET_ARG(3);
        semihost_sys_rename(cs, common_semi_cb, arg0, arg1 + 1, arg2, arg3 + 1);
        break;

    case TARGET_SYS_CLOCK:
        common_semi_set_ret(cs, clock() / (CLOCKS_PER_SEC / 100));
        break;

    case TARGET_SYS_TIME:
        ul_ret = time(NULL);
        common_semi_cb(cs, ul_ret, ul_ret == -1 ? errno : 0);
        break;

    case TARGET_SYS_SYSTEM:
        GET_ARG(0);
        GET_ARG(1);
        semihost_sys_system(cs, common_semi_cb, arg0, arg1 + 1);
        break;

    case TARGET_SYS_ERRNO:
        common_semi_set_ret(cs, get_swi_errno(cs));
        break;

    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->env_strings - ts->info->arg_strings;
            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.  */
                common_semi_cb(cs, -1, E2BIG);
                break;
            }

            /* Adjust the command-line length.  */
            if (SET_ARG(1, output_size - 1)) {
                /* Couldn't write back to argument block */
                goto do_fault;
            }

            /* Lock the buffer on the ARM side.  */
            output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0);
            if (!output_buffer) {
                goto do_fault;
            }

            /* 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_strings,
                               output_size)) {
                unlock_user(output_buffer, arg0, 0);
                goto do_fault;
            }

            /* 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);
            common_semi_cb(cs, status, 0);
        }
        break;

    case TARGET_SYS_HEAPINFO:
        {
            target_ulong retvals[4];
            int i;
#ifdef CONFIG_USER_ONLY
            TaskState *ts = cs->opaque;
            target_ulong limit;
#else
            LayoutInfo info = common_semi_find_bases(cs);
#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 + COMMON_SEMI_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
            retvals[0] = info.heapbase;  /* Heap Base */
            retvals[1] = info.heaplimit; /* Heap Limit */
            retvals[2] = info.heaplimit; /* Stack base */
            retvals[3] = info.heapbase;  /* Stack limit.  */
#endif

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

                if (is_64bit_semihosting(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 */
                    goto do_fault;
                }
            }
            common_semi_set_ret(cs, 0);
        }
        break;

    case TARGET_SYS_EXIT:
    case TARGET_SYS_EXIT_EXTENDED:
    {
        uint32_t ret;

        if (common_semi_sys_exit_extended(cs, nr)) {
            /*
             * 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_ELAPSED:
        elapsed = get_clock() - clock_start;
        if (sizeof(target_ulong) == 8) {
            if (SET_ARG(0, elapsed)) {
                goto do_fault;
            }
        } else {
            if (SET_ARG(0, (uint32_t) elapsed) ||
                SET_ARG(1, (uint32_t) (elapsed >> 32))) {
                goto do_fault;
            }
        }
        common_semi_set_ret(cs, 0);
        break;

    case TARGET_SYS_TICKFREQ:
        /* qemu always uses nsec */
        common_semi_set_ret(cs, 1000000000);
        break;

    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 (common_semi_has_synccache(env)) {
            common_semi_set_ret(cs, 0);
            break;
        }
        /* fall through */
    default:
        fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
        cpu_dump_state(cs, stderr, 0);
        abort();

    do_fault:
        common_semi_cb(cs, -1, EFAULT);
        break;
    }
}
