mmap64.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. /* Massivly hacked up for uClibc by Erik Andersen */
  7. #include <_lfs_64.h>
  8. #include <stdint.h>
  9. #include <sys/syscall.h>
  10. #include <errno.h>
  11. #include <sys/mman.h>
  12. #ifndef __NR_mmap2
  13. /*
  14. * This version is a stub that just chops off everything at the mmap 32 bit
  15. * mmap() address space... You will probably need to add in an arch specific
  16. * implementation to override this as there is not a generic way for me to
  17. * implement this particular syscall if your arch lacks _syscall6...
  18. *
  19. */
  20. void *mmap64(void *addr, size_t len, int prot, int flags, int fd, __off64_t offset)
  21. {
  22. if (offset != (off_t) offset ||
  23. (offset + len) != (off_t) (offset + len)) {
  24. __set_errno(EINVAL);
  25. return MAP_FAILED;
  26. }
  27. return mmap(addr, len, prot, flags, fd, (off_t) offset);
  28. }
  29. #else
  30. # include <bits/uClibc_page.h>
  31. /* Some architectures always use 12 as page shift for mmap2() even though the
  32. * real PAGE_SHIFT != 12. Other architectures use the same value as
  33. * PAGE_SHIFT...
  34. */
  35. # ifndef MMAP2_PAGE_SHIFT
  36. # define MMAP2_PAGE_SHIFT 12
  37. # endif
  38. void *mmap64(void *addr, size_t len, int prot, int flags, int fd, __off64_t offset)
  39. {
  40. /*
  41. * Some arches check the size in INLINE_SYSCALL() and barf if it's
  42. * too big (i.e. a 64bit value getting truncated to 32bit).
  43. */
  44. # if __WORDSIZE == 32
  45. uint32_t sysoff;
  46. # else
  47. uint64_t sysoff;
  48. # endif
  49. if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) {
  50. __set_errno(EINVAL);
  51. return MAP_FAILED;
  52. }
  53. /*
  54. * We know __off64_t is always a signed 64-bit type, but need things
  55. * to be unsigned before doing the shift. If it isn't, we might
  56. * sign extend things and pass in the wrong value. So cast it to
  57. * an unsigned 64-bit value before doing the shift.
  58. */
  59. sysoff = (uint64_t)offset >> MMAP2_PAGE_SHIFT;
  60. return (void*) INLINE_SYSCALL(mmap2, 6, addr, len, prot, flags, fd, sysoff);
  61. }
  62. #endif