File:  [Qemu by Fabrice Bellard] / qemu / linux-user / uaccess.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:22:51 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, qemu1001, qemu1000, qemu0151, qemu0150, qemu0141, qemu0140, qemu0130, qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, qemu0111, qemu0110, HEAD
qemu 0.11.0

    1: /* User memory access */
    2: #include <stdio.h>
    3: #include <string.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:  */
   11: abi_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: 
   26: abi_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  */
   42: abi_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: }

unix.superglobalmegacorp.com