1 /* 2 * Helper routines to provide target memory access for semihosting 3 * syscalls in system emulation mode. 4 * 5 * Copyright (c) 2007 CodeSourcery. 6 * 7 * This code is licensed under the GPL 8 */ 9 10 #include "qemu/osdep.h" 11 #include "exec/cpu-all.h" 12 #include "accel/tcg/cpu-mmu-index.h" 13 #include "exec/exec-all.h" 14 #include "semihosting/uaccess.h" 15 16 void *uaccess_lock_user(CPUArchState *env, target_ulong addr, 17 target_ulong len, bool copy) 18 { 19 void *p = malloc(len); 20 if (p && copy) { 21 if (cpu_memory_rw_debug(env_cpu(env), addr, p, len, 0)) { 22 free(p); 23 p = NULL; 24 } 25 } 26 return p; 27 } 28 29 ssize_t uaccess_strlen_user(CPUArchState *env, target_ulong addr) 30 { 31 int mmu_idx = cpu_mmu_index(env_cpu(env), false); 32 size_t len = 0; 33 34 while (1) { 35 size_t left_in_page; 36 int flags; 37 void *h; 38 39 /* Find the number of bytes remaining in the page. */ 40 left_in_page = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 41 42 flags = probe_access_flags(env, addr, 0, MMU_DATA_LOAD, 43 mmu_idx, true, &h, 0); 44 if (flags & TLB_INVALID_MASK) { 45 return -1; 46 } 47 if (flags & TLB_MMIO) { 48 do { 49 uint8_t c; 50 if (cpu_memory_rw_debug(env_cpu(env), addr, &c, 1, 0)) { 51 return -1; 52 } 53 if (c == 0) { 54 return len; 55 } 56 addr++; 57 len++; 58 if (len > INT32_MAX) { 59 return -1; 60 } 61 } while (--left_in_page != 0); 62 } else { 63 char *p = memchr(h, 0, left_in_page); 64 if (p) { 65 len += p - (char *)h; 66 return len <= INT32_MAX ? (ssize_t)len : -1; 67 } 68 addr += left_in_page; 69 len += left_in_page; 70 if (len > INT32_MAX) { 71 return -1; 72 } 73 } 74 } 75 } 76 77 char *uaccess_lock_user_string(CPUArchState *env, target_ulong addr) 78 { 79 ssize_t len = uaccess_strlen_user(env, addr); 80 if (len < 0) { 81 return NULL; 82 } 83 return uaccess_lock_user(env, addr, len + 1, true); 84 } 85 86 void uaccess_unlock_user(CPUArchState *env, void *p, 87 target_ulong addr, target_ulong len) 88 { 89 if (len) { 90 cpu_memory_rw_debug(env_cpu(env), addr, p, len, 1); 91 } 92 free(p); 93 } 94