|
|
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: /* 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;
1.1.1.2 root 54: len = qemu_strnlen((const char *)ptr, max_len);
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.