qemu/bsd-user/uaccess.c
<<
>>
Prefs
   1/* User memory access */
   2#include "qemu/osdep.h"
   3#include "qemu/cutils.h"
   4
   5#include "qemu.h"
   6
   7/* copy_from_user() and copy_to_user() are usually used to copy data
   8 * buffers between the target and host.  These internally perform
   9 * locking/unlocking of the memory.
  10 */
  11abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
  12{
  13    abi_long ret = 0;
  14    void *ghptr;
  15
  16    if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) {
  17        memcpy(hptr, ghptr, len);
  18        unlock_user(ghptr, gaddr, 0);
  19    } else
  20        ret = -TARGET_EFAULT;
  21
  22    return ret;
  23}
  24
  25
  26abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
  27{
  28    abi_long ret = 0;
  29    void *ghptr;
  30
  31    if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) {
  32        memcpy(ghptr, hptr, len);
  33        unlock_user(ghptr, gaddr, len);
  34    } else
  35        ret = -TARGET_EFAULT;
  36
  37    return ret;
  38}
  39
  40/* Return the length of a string in target memory or -TARGET_EFAULT if
  41   access error  */
  42abi_long target_strlen(abi_ulong guest_addr1)
  43{
  44    uint8_t *ptr;
  45    abi_ulong guest_addr;
  46    int max_len, len;
  47
  48    guest_addr = guest_addr1;
  49    for(;;) {
  50        max_len = TARGET_PAGE_SIZE - (guest_addr & ~TARGET_PAGE_MASK);
  51        ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
  52        if (!ptr)
  53            return -TARGET_EFAULT;
  54        len = qemu_strnlen((const char *)ptr, max_len);
  55        unlock_user(ptr, guest_addr, 0);
  56        guest_addr += len;
  57        /* we don't allow wrapping or integer overflow */
  58        if (guest_addr == 0 ||
  59            (guest_addr - guest_addr1) > 0x7fffffff)
  60            return -TARGET_EFAULT;
  61        if (len != max_len)
  62            break;
  63    }
  64    return guest_addr - guest_addr1;
  65}
  66