]>
Commit | Line | Data |
---|---|---|
579a97f7 FB |
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 | ||
3dd98412 FB |
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) | |
579a97f7 | 43 | { |
3dd98412 FB |
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; | |
b55266b5 | 54 | len = qemu_strnlen((const char *)ptr, max_len); |
3dd98412 FB |
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; | |
579a97f7 | 65 | } |