dl-syscalls.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* Copyright (C) 2003, 2004 Red Hat, Inc.
  2. * Contributed by Alexandre Oliva <aoliva@redhat.com>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. /* We can't use the real errno in ldso, since it has not yet
  7. * been dynamicly linked in yet. */
  8. #include "sys/syscall.h"
  9. extern int _dl_errno;
  10. #undef __set_errno
  11. #define __set_errno(X) {(_dl_errno) = (X);}
  12. #include <sys/mman.h>
  13. /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */
  14. #if DYNAMIC_LOADER_IN_SIMULATOR
  15. #define __NR___syscall_mmap2 __NR_mmap2
  16. static __inline__ _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
  17. size_t, len, int, prot, int, flags, int, fd, off_t, offset);
  18. /* Make sure we don't get another definition of _dl_mmap from the
  19. machine-independent code. */
  20. #undef __NR_mmap
  21. #undef __NR_mmap2
  22. /* This is always 12, even on architectures where PAGE_SHIFT != 12. */
  23. # ifndef MMAP2_PAGE_SHIFT
  24. # define MMAP2_PAGE_SHIFT 12
  25. # endif
  26. #include <bits/uClibc_page.h> /* for PAGE_SIZE */
  27. inline static void *_dl_memset(void*,int,size_t);
  28. inline static ssize_t _dl_pread(int fd, void *buf, size_t count, off_t offset);
  29. static __ptr_t
  30. _dl_mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
  31. {
  32. size_t plen = (len + PAGE_SIZE - 1) & -PAGE_SIZE;
  33. /* This is a hack to enable the dynamic loader to run within a
  34. simulator that doesn't support mmap, with a number of very ugly
  35. tricks. Also, it's not as useful as it sounds, since only dynamic
  36. executables without DT_NEEDED dependencies can be run. AFAIK, they
  37. can only be created with -pie. This trick suffices to enable the
  38. dynamic loader to obtain a blank page that it maps early in the
  39. bootstrap. */
  40. if ((flags & MAP_FIXED) == 0)
  41. {
  42. void *_dl_mmap_base = 0;
  43. __ptr_t *ret = 0;
  44. if (! _dl_mmap_base)
  45. {
  46. void *stack;
  47. __asm__ ("mov sp, %0" : "=r" (stack));
  48. _dl_mmap_base = (void *)(((long)stack + 2 * PAGE_SIZE) & -PAGE_SIZE);
  49. retry:
  50. if (((void **)_dl_mmap_base)[0] == _dl_mmap_base
  51. && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base
  52. && (((void **)_dl_mmap_base)[177]
  53. == ((void **)_dl_mmap_base)[771]))
  54. {
  55. while (((void**)_dl_mmap_base)[177])
  56. {
  57. _dl_mmap_base = ((void**)_dl_mmap_base)[177];
  58. if (!(((void **)_dl_mmap_base)[0] == _dl_mmap_base
  59. && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base
  60. && (((void **)_dl_mmap_base)[177]
  61. == ((void**)_dl_mmap_base)[771])))
  62. ((void(*)())0)();
  63. }
  64. }
  65. else
  66. {
  67. int i;
  68. for (i = 0; i < (int)PAGE_SIZE; i++)
  69. if (*(char*)(_dl_mmap_base + i))
  70. break;
  71. if (i != PAGE_SIZE)
  72. {
  73. _dl_mmap_base = (void*)((long)_dl_mmap_base + PAGE_SIZE);
  74. goto retry;
  75. }
  76. ((void**)_dl_mmap_base)[-1] =
  77. ((void**)_dl_mmap_base)[0] =
  78. ((void**)_dl_mmap_base)[1023] =
  79. _dl_mmap_base;
  80. }
  81. }
  82. if (_dl_mmap_base)
  83. {
  84. if (!(((void **)_dl_mmap_base)[0] == _dl_mmap_base
  85. && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base
  86. && (((void **)_dl_mmap_base)[177]
  87. == ((void**)_dl_mmap_base)[771])))
  88. ((void(*)())0)();
  89. ret = (__ptr_t)((char*)_dl_mmap_base + PAGE_SIZE);
  90. _dl_mmap_base =
  91. ((void**)_dl_mmap_base)[177] =
  92. ((void**)_dl_mmap_base)[771] =
  93. (char*)_dl_mmap_base + plen + PAGE_SIZE;
  94. ((void**)_dl_mmap_base)[0] =
  95. ((void**)_dl_mmap_base)[1023] =
  96. _dl_mmap_base;
  97. }
  98. if ((flags & MAP_ANONYMOUS) != 0)
  99. {
  100. _dl_memset (ret, 0, plen);
  101. return ret;
  102. }
  103. flags |= MAP_FIXED;
  104. addr = ret;
  105. }
  106. if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) {
  107. #if 0
  108. __set_errno (EINVAL);
  109. #endif
  110. return MAP_FAILED;
  111. }
  112. if ((flags & MAP_FIXED) != 0)
  113. {
  114. if (_dl_pread(fd, addr, len, offset) != (ssize_t)len)
  115. return (void*)MAP_FAILED;
  116. if (plen != len)
  117. _dl_memset (addr + len, 0, plen - len);
  118. return addr;
  119. }
  120. return(__syscall_mmap2(addr, len, prot, flags, fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
  121. }
  122. #endif
  123. #ifdef __NR_pread
  124. #ifdef DYNAMIC_LOADER_IN_SIMULATOR
  125. #include <unistd.h>
  126. #define __NR___syscall_lseek __NR_lseek
  127. inline static unsigned long _dl_read(int fd, const void *buf, unsigned long count);
  128. inline static _syscall3(__off_t, __syscall_lseek, int, fd, __off_t, offset,
  129. int, whence);
  130. inline static ssize_t
  131. _dl_pread(int fd, void *buf, size_t count, off_t offset)
  132. {
  133. __off_t orig = __syscall_lseek (fd, 0, SEEK_CUR);
  134. ssize_t ret;
  135. if (orig == -1)
  136. return -1;
  137. if (__syscall_lseek (fd, offset, SEEK_SET) != offset)
  138. return -1;
  139. ret = _dl_read (fd, buf, count);
  140. if (__syscall_lseek (fd, orig, SEEK_SET) != orig)
  141. ((void(*)())0)();
  142. return ret;
  143. }
  144. #else
  145. #define __NR___syscall_pread __NR_pread
  146. inline static _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
  147. size_t, count, off_t, offset_hi, off_t, offset_lo);
  148. inline static ssize_t
  149. _dl_pread(int fd, void *buf, size_t count, off_t offset)
  150. {
  151. return(__syscall_pread(fd,buf,count,__LONG_LONG_PAIR (offset >> 31, offset)));
  152. }
  153. #endif
  154. #endif