Annotation of qemu/linux-user/uaccess.c, revision 1.1

1.1     ! root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.