2
0

uaccess.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /* User memory access */
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "qemu.h"
  5. /* copy_from_user() and copy_to_user() are usually used to copy data
  6. * buffers between the target and host. These internally perform
  7. * locking/unlocking of the memory.
  8. */
  9. abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
  10. {
  11. abi_long ret = 0;
  12. void *ghptr;
  13. if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) {
  14. memcpy(hptr, ghptr, len);
  15. unlock_user(ghptr, gaddr, 0);
  16. } else
  17. ret = -TARGET_EFAULT;
  18. return ret;
  19. }
  20. abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
  21. {
  22. abi_long ret = 0;
  23. void *ghptr;
  24. if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) {
  25. memcpy(ghptr, hptr, len);
  26. unlock_user(ghptr, gaddr, len);
  27. } else
  28. ret = -TARGET_EFAULT;
  29. return ret;
  30. }
  31. /* XXX: use host strnlen if available ? */
  32. static int qemu_strnlen(const char *s, int max_len)
  33. {
  34. int i;
  35. for(i = 0; i < max_len; i++) {
  36. if (s[i] == '\0')
  37. break;
  38. }
  39. return i;
  40. }
  41. /* Return the length of a string in target memory or -TARGET_EFAULT if
  42. access error */
  43. abi_long target_strlen(abi_ulong guest_addr1)
  44. {
  45. uint8_t *ptr;
  46. abi_ulong guest_addr;
  47. int max_len, len;
  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(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. }