Add a check in 'softmmu-uaccess.h' that the header is only include in system emulation, and rename it as 'uaccess.h'. Rename the API methods: - softmmu_[un]lock_user*() -> uaccess_[un]lock_user*() - softmmu_strlen_user() -> uaccess_strlen_user(). Update a pair of comments. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20231004090629.37473-9-philmd@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * 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 "exec/exec-all.h"
 | 
						|
#include "semihosting/uaccess.h"
 | 
						|
 | 
						|
void *uaccess_lock_user(CPUArchState *env, target_ulong addr,
 | 
						|
                        target_ulong 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, target_ulong addr)
 | 
						|
{
 | 
						|
    int mmu_idx = cpu_mmu_index(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, target_ulong 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,
 | 
						|
                         target_ulong addr, target_ulong len)
 | 
						|
{
 | 
						|
    if (len) {
 | 
						|
        cpu_memory_rw_debug(env_cpu(env), addr, p, len, 1);
 | 
						|
    }
 | 
						|
    free(p);
 | 
						|
}
 |