/*
 * Helper routines to provide target memory access for semihosting
 * syscalls in system emulation mode.
 *
 * Copyright (c) 2007 CodeSourcery.
 *
 * This code is licensed under the GPL
 */

#include "qemu/osdep.h"
#include "accel/tcg/cpu-mmu-index.h"
#include "accel/tcg/probe.h"
#include "exec/target_page.h"
#include "exec/tlb-flags.h"
#include "semihosting/uaccess.h"

void *uaccess_lock_user(CPUArchState *env, vaddr addr,
                        size_t len, bool copy)
{
    void *p = malloc(len);
    if (p && copy) {
        if (cpu_memory_rw_debug(env_cpu(env), addr, p, len, 0)) {
            free(p);
            p = NULL;
        }
    }
    return p;
}

ssize_t uaccess_strlen_user(CPUArchState *env, vaddr addr)
{
    int mmu_idx = cpu_mmu_index(env_cpu(env), false);
    size_t len = 0;

    while (1) {
        size_t left_in_page;
        int flags;
        void *h;

        /* Find the number of bytes remaining in the page. */
        left_in_page = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);

        flags = probe_access_flags(env, addr, 0, MMU_DATA_LOAD,
                                   mmu_idx, true, &h, 0);
        if (flags & TLB_INVALID_MASK) {
            return -1;
        }
        if (flags & TLB_MMIO) {
            do {
                uint8_t c;
                if (cpu_memory_rw_debug(env_cpu(env), addr, &c, 1, 0)) {
                    return -1;
                }
                if (c == 0) {
                    return len;
                }
                addr++;
                len++;
                if (len > INT32_MAX) {
                    return -1;
                }
            } while (--left_in_page != 0);
        } else {
            char *p = memchr(h, 0, left_in_page);
            if (p) {
                len += p - (char *)h;
                return len <= INT32_MAX ? (ssize_t)len : -1;
            }
            addr += left_in_page;
            len += left_in_page;
            if (len > INT32_MAX) {
                return -1;
            }
        }
    }
}

char *uaccess_lock_user_string(CPUArchState *env, vaddr addr)
{
    ssize_t len = uaccess_strlen_user(env, addr);
    if (len < 0) {
        return NULL;
    }
    return uaccess_lock_user(env, addr, len + 1, true);
}

void uaccess_unlock_user(CPUArchState *env, void *p,
                         vaddr addr, size_t len)
{
    if (len) {
        cpu_memory_rw_debug(env_cpu(env), addr, p, len, 1);
    }
    free(p);
}
