syscalls.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /* Copyright (C) 1992,1997-2003,2004,2005,2006 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, write to the Free
  13. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA. */
  15. #ifndef _BITS_SYSCALLS_H
  16. #define _BITS_SYSCALLS_H
  17. #ifndef _SYSCALL_H
  18. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  19. #endif
  20. /* For Linux we can use the system call table in the header file
  21. /usr/include/asm/unistd.h
  22. of the kernel. But these symbols do not follow the SYS_* syntax
  23. so we have to redefine the `SYS_ify' macro here. */
  24. #undef SYS_ify
  25. #define SYS_ify(syscall_name) __NR_##syscall_name
  26. #ifndef __ASSEMBLER__
  27. # include <errno.h>
  28. # ifdef SHARED
  29. # define INLINE_VSYSCALL(name, nr, args...) \
  30. ({ \
  31. __label__ out; \
  32. __label__ iserr; \
  33. INTERNAL_SYSCALL_DECL (sc_err); \
  34. long int sc_ret; \
  35. \
  36. if (__vdso_##name != NULL) \
  37. { \
  38. sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \
  39. if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  40. goto out; \
  41. if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
  42. goto iserr; \
  43. } \
  44. \
  45. sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args); \
  46. if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  47. { \
  48. iserr: \
  49. __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
  50. sc_ret = -1L; \
  51. } \
  52. out: \
  53. sc_ret; \
  54. })
  55. # else
  56. # define INLINE_VSYSCALL(name, nr, args...) \
  57. INLINE_SYSCALL (name, nr, ##args)
  58. # endif
  59. # ifdef SHARED
  60. # define INTERNAL_VSYSCALL(name, err, nr, args...) \
  61. ({ \
  62. __label__ out; \
  63. long int v_ret; \
  64. \
  65. if (__vdso_##name != NULL) \
  66. { \
  67. v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
  68. if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
  69. || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
  70. goto out; \
  71. } \
  72. v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \
  73. out: \
  74. v_ret; \
  75. })
  76. # else
  77. # define INTERNAL_VSYSCALL(name, err, nr, args...) \
  78. INTERNAL_SYSCALL (name, err, nr, ##args)
  79. # endif
  80. # define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
  81. ({ \
  82. long int sc_ret = ENOSYS; \
  83. \
  84. if (__vdso_##name != NULL) \
  85. sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
  86. else \
  87. err = 1 << 28; \
  88. sc_ret; \
  89. })
  90. /* List of system calls which are supported as vsyscalls. */
  91. # define HAVE_CLOCK_GETRES_VSYSCALL 1
  92. # define HAVE_CLOCK_GETTIME_VSYSCALL 1
  93. /* Define a macro which expands inline into the wrapper code for a VDSO
  94. call. This use is for internal calls that do not need to handle errors
  95. normally. It will never touch errno.
  96. On powerpc a system call basically clobbers the same registers like a
  97. function call, with the exception of LR (which is needed for the
  98. "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
  99. an error return status). */
  100. # define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \
  101. ({ \
  102. register void *r0 __asm__ ("r0"); \
  103. register long int r3 __asm__ ("r3"); \
  104. register long int r4 __asm__ ("r4"); \
  105. register long int r5 __asm__ ("r5"); \
  106. register long int r6 __asm__ ("r6"); \
  107. register long int r7 __asm__ ("r7"); \
  108. register long int r8 __asm__ ("r8"); \
  109. register long int r9 __asm__ ("r9"); \
  110. register long int r10 __asm__ ("r10"); \
  111. register long int r11 __asm__ ("r11"); \
  112. register long int r12 __asm__ ("r12"); \
  113. LOADARGS_##nr (funcptr, args); \
  114. __asm__ __volatile__ \
  115. ("mtctr %0\n\t" \
  116. "bctrl\n\t" \
  117. "mfcr %0" \
  118. : "=&r" (r0), \
  119. "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
  120. "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
  121. : ASM_INPUT_##nr \
  122. : "cr0", "ctr", "lr", "memory"); \
  123. err = (long int) r0; \
  124. (int) r3; \
  125. })
  126. # undef INLINE_SYSCALL
  127. # define INLINE_SYSCALL(name, nr, args...) \
  128. ({ \
  129. INTERNAL_SYSCALL_DECL (sc_err); \
  130. long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
  131. if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  132. { \
  133. __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
  134. sc_ret = -1L; \
  135. } \
  136. sc_ret; \
  137. })
  138. /* Define a macro which expands inline into the wrapper code for a system
  139. call. This use is for internal calls that do not need to handle errors
  140. normally. It will never touch errno.
  141. On powerpc a system call basically clobbers the same registers like a
  142. function call, with the exception of LR (which is needed for the
  143. "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
  144. an error return status). */
  145. # undef INTERNAL_SYSCALL_DECL
  146. # define INTERNAL_SYSCALL_DECL(err) long int err
  147. # undef INTERNAL_SYSCALL
  148. # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
  149. ({ \
  150. register long int r0 __asm__ ("r0"); \
  151. register long int r3 __asm__ ("r3"); \
  152. register long int r4 __asm__ ("r4"); \
  153. register long int r5 __asm__ ("r5"); \
  154. register long int r6 __asm__ ("r6"); \
  155. register long int r7 __asm__ ("r7"); \
  156. register long int r8 __asm__ ("r8"); \
  157. register long int r9 __asm__ ("r9"); \
  158. register long int r10 __asm__ ("r10"); \
  159. register long int r11 __asm__ ("r11"); \
  160. register long int r12 __asm__ ("r12"); \
  161. LOADARGS_##nr(name, args); \
  162. __asm__ __volatile__ \
  163. ("sc \n\t" \
  164. "mfcr %0" \
  165. : "=&r" (r0), \
  166. "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
  167. "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
  168. : ASM_INPUT_##nr \
  169. : "cr0", "ctr", "memory"); \
  170. err = r0; \
  171. (int) r3; \
  172. })
  173. # define INTERNAL_SYSCALL(name, err, nr, args...) \
  174. INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
  175. # undef INTERNAL_SYSCALL_ERROR_P
  176. # define INTERNAL_SYSCALL_ERROR_P(val, err) \
  177. ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
  178. # undef INTERNAL_SYSCALL_ERRNO
  179. # define INTERNAL_SYSCALL_ERRNO(val, err) (val)
  180. extern void __illegally_sized_syscall_arg1(void);
  181. extern void __illegally_sized_syscall_arg2(void);
  182. extern void __illegally_sized_syscall_arg3(void);
  183. extern void __illegally_sized_syscall_arg4(void);
  184. extern void __illegally_sized_syscall_arg5(void);
  185. extern void __illegally_sized_syscall_arg6(void);
  186. # define LOADARGS_0(name, dummy) \
  187. r0 = name
  188. # define LOADARGS_1(name, __arg1) \
  189. long int arg1 = (long int) (__arg1); \
  190. LOADARGS_0(name, 0); \
  191. if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 4) \
  192. __illegally_sized_syscall_arg1 (); \
  193. r3 = arg1
  194. # define LOADARGS_2(name, __arg1, __arg2) \
  195. long int arg2 = (long int) (__arg2); \
  196. LOADARGS_1(name, __arg1); \
  197. if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 4) \
  198. __illegally_sized_syscall_arg2 (); \
  199. r4 = arg2
  200. # define LOADARGS_3(name, __arg1, __arg2, __arg3) \
  201. long int arg3 = (long int) (__arg3); \
  202. LOADARGS_2(name, __arg1, __arg2); \
  203. if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 4) \
  204. __illegally_sized_syscall_arg3 (); \
  205. r5 = arg3
  206. # define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
  207. long int arg4 = (long int) (__arg4); \
  208. LOADARGS_3(name, __arg1, __arg2, __arg3); \
  209. if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 4) \
  210. __illegally_sized_syscall_arg4 (); \
  211. r6 = arg4
  212. # define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
  213. long int arg5 = (long int) (__arg5); \
  214. LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
  215. if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 4) \
  216. __illegally_sized_syscall_arg5 (); \
  217. r7 = arg5
  218. # define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
  219. long int arg6 = (long int) (__arg6); \
  220. LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
  221. if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 4) \
  222. __illegally_sized_syscall_arg6 (); \
  223. r8 = arg6
  224. # define ASM_INPUT_0 "0" (r0)
  225. # define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
  226. # define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
  227. # define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
  228. # define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
  229. # define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
  230. # define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
  231. #undef _syscall0
  232. #define _syscall0(type,name) \
  233. type name(void) { \
  234. return (type) INLINE_SYSCALL(name, 0); \
  235. }
  236. #undef _syscall1
  237. #define _syscall1(type,name,type1,arg1) \
  238. type name(type1 arg1) { \
  239. return (type) INLINE_SYSCALL(name, 1, arg1); \
  240. }
  241. #undef _syscall2
  242. #define _syscall2(type,name,type1,arg1,type2,arg2) \
  243. type name(type1 arg1, type2 arg2) { \
  244. return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
  245. }
  246. #undef _syscall3
  247. #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
  248. type name(type1 arg1, type2 arg2, type3 arg3) { \
  249. return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
  250. }
  251. #undef _syscall4
  252. #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
  253. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
  254. return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
  255. }
  256. #undef _syscall5
  257. #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
  258. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
  259. return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
  260. }
  261. #undef _syscall6
  262. #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
  263. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \
  264. return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
  265. }
  266. #endif /* __ASSEMBLER__ */
  267. /* Pointer mangling support. */
  268. #if defined NOT_IN_libc && defined IS_IN_rtld
  269. /* We cannot use the thread descriptor because in ld.so we use setjmp
  270. earlier than the descriptor is initialized. */
  271. #else
  272. # ifdef __ASSEMBLER__
  273. # define PTR_MANGLE(reg, tmpreg) \
  274. lwz tmpreg,POINTER_GUARD(r2); \
  275. xor reg,tmpreg,reg
  276. # define PTR_MANGLE2(reg, tmpreg) \
  277. xor reg,tmpreg,reg
  278. # define PTR_MANGLE3(destreg, reg, tmpreg) \
  279. lwz tmpreg,POINTER_GUARD(r2); \
  280. xor destreg,tmpreg,reg
  281. # define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
  282. # define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
  283. # define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg)
  284. # else
  285. # define PTR_MANGLE(var) \
  286. (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
  287. # define PTR_DEMANGLE(var) PTR_MANGLE (var)
  288. # endif
  289. #endif
  290. #endif /* _BITS_SYSCALLS_H */