(linenum→info "unix/slp.c:2238")

qemu/0.9.1/linux-user/uaccess.c

    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: /* XXX: use host strnlen if available ? */
   41: static int qemu_strnlen(const char *s, int max_len)
   42: {
   43:     int i;
   44:     for(i = 0; i < max_len; i++) {
   45:         if (s[i] == '\0')
   46:             break;
   47:     }
   48:     return i;
   49: }
   50: 
   51: /* Return the length of a string in target memory or -TARGET_EFAULT if
   52:    access error  */
   53: abi_long target_strlen(abi_ulong guest_addr1)
   54: {
   55:     uint8_t *ptr;
   56:     abi_ulong guest_addr;
   57:     int max_len, len;
   58: 
   59:     guest_addr = guest_addr1;
   60:     for(;;) {
   61:         max_len = TARGET_PAGE_SIZE - (guest_addr & ~TARGET_PAGE_MASK);
   62:         ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
   63:         if (!ptr)
   64:             return -TARGET_EFAULT;
   65:         len = qemu_strnlen(ptr, max_len);
   66:         unlock_user(ptr, guest_addr, 0);
   67:         guest_addr += len;
   68:         /* we don't allow wrapping or integer overflow */
   69:         if (guest_addr == 0 || 
   70:             (guest_addr - guest_addr1) > 0x7fffffff)
   71:             return -TARGET_EFAULT;
   72:         if (len != max_len)
   73:             break;
   74:     }
   75:     return guest_addr - guest_addr1;
   76: }
Syntax (Markdown)