syscalls.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #ifndef _BITS_SYSCALLS_H
  2. #define _BITS_SYSCALLS_H
  3. #ifndef _SYSCALL_H
  4. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  5. #endif
  6. /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
  7. * header files. It also defines the traditional `SYS_<name>' macros for older
  8. * programs. */
  9. #include <bits/sysnum.h>
  10. #ifndef __ASSEMBLER__
  11. /* Define a macro which expands inline into the wrapper code for a system
  12. call. This use is for internal calls that do not need to handle errors
  13. normally. It will never touch errno.
  14. On powerpc a system call basically clobbers the same registers like a
  15. function call, with the exception of LR (which is needed for the
  16. "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
  17. an error return status). */
  18. #include <errno.h>
  19. #define SYS_ify(syscall_name) (__NR_##syscall_name)
  20. # undef INLINE_SYSCALL
  21. #if 1
  22. # define INLINE_SYSCALL(name, nr, args...) \
  23. ({ \
  24. INTERNAL_SYSCALL_DECL (sc_err); \
  25. long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
  26. if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  27. { \
  28. __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
  29. sc_ret = -1L; \
  30. } \
  31. sc_ret; \
  32. })
  33. #else
  34. # define INLINE_SYSCALL(name, nr, args...) \
  35. ({ \
  36. INTERNAL_SYSCALL_DECL (sc_err); \
  37. long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
  38. if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  39. { \
  40. sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\
  41. } \
  42. sc_ret; \
  43. })
  44. #endif
  45. /* Define a macro which expands inline into the wrapper code for a system
  46. call. This use is for internal calls that do not need to handle errors
  47. normally. It will never touch errno.
  48. On powerpc a system call basically clobbers the same registers like a
  49. function call, with the exception of LR (which is needed for the
  50. "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
  51. an error return status). */
  52. # undef INTERNAL_SYSCALL_DECL
  53. # define INTERNAL_SYSCALL_DECL(err) long int err
  54. # undef INTERNAL_SYSCALL
  55. # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
  56. ({ \
  57. register long int r0 __asm__ ("r0"); \
  58. register long int r3 __asm__ ("r3"); \
  59. register long int r4 __asm__ ("r4"); \
  60. register long int r5 __asm__ ("r5"); \
  61. register long int r6 __asm__ ("r6"); \
  62. register long int r7 __asm__ ("r7"); \
  63. register long int r8 __asm__ ("r8"); \
  64. register long int r9 __asm__ ("r9"); \
  65. register long int r10 __asm__ ("r10"); \
  66. register long int r11 __asm__ ("r11"); \
  67. register long int r12 __asm__ ("r12"); \
  68. LOADARGS_##nr(name, args); \
  69. __asm__ __volatile__ \
  70. ("sc \n\t" \
  71. "mfcr %0" \
  72. : "=&r" (r0), \
  73. "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
  74. "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
  75. : ASM_INPUT_##nr \
  76. : "cr0", "ctr", "memory"); \
  77. err = r0; \
  78. (int) r3; \
  79. })
  80. # define INTERNAL_SYSCALL(name, err, nr, args...) \
  81. INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
  82. # undef INTERNAL_SYSCALL_ERROR_P
  83. # define INTERNAL_SYSCALL_ERROR_P(val, err) \
  84. ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
  85. # undef INTERNAL_SYSCALL_ERRNO
  86. # define INTERNAL_SYSCALL_ERRNO(val, err) (val)
  87. # define LOADARGS_0(name, dummy) \
  88. r0 = (long int)name
  89. # define LOADARGS_1(name, __arg1) \
  90. LOADARGS_0(name, 0); \
  91. r3 = (long int)__arg1
  92. # define LOADARGS_2(name, __arg1, __arg2) \
  93. LOADARGS_1(name, __arg1); \
  94. r4 = (long int)__arg2
  95. # define LOADARGS_3(name, __arg1, __arg2, __arg3) \
  96. LOADARGS_2(name, __arg1, __arg2); \
  97. r5 = (long int)__arg3
  98. # define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
  99. LOADARGS_3(name, __arg1, __arg2, __arg3); \
  100. r6 = (long int)__arg4
  101. # define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
  102. LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
  103. r7 = (long int)__arg5
  104. # define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
  105. LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
  106. r8 = (long int)__arg6
  107. # define ASM_INPUT_0 "0" (r0)
  108. # define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
  109. # define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
  110. # define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
  111. # define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
  112. # define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
  113. # define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
  114. #undef _syscall0
  115. #define _syscall0(type,name) \
  116. type name(void){ \
  117. return (type) INLINE_SYSCALL(name, 0); \
  118. }
  119. #undef _syscall1
  120. #define _syscall1(type,name,type1,arg1) \
  121. type name(type1 arg1){ \
  122. return (type) INLINE_SYSCALL(name, 1, arg1); \
  123. }
  124. #undef _syscall2
  125. #define _syscall2(type,name,type1,arg1,type2,arg2) \
  126. type name(type1 arg1, type2 arg2){ \
  127. return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
  128. }
  129. #undef _syscall3
  130. #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
  131. type name(type1 arg1, type2 arg2, type3 arg3){ \
  132. return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
  133. }
  134. #undef _syscall4
  135. #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
  136. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){ \
  137. return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
  138. }
  139. #undef _syscall5
  140. #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
  141. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){ \
  142. return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
  143. }
  144. #undef _syscall6
  145. #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
  146. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){ \
  147. return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
  148. }
  149. #endif /* __ASSEMBLER__ */
  150. #endif /* _BITS_SYSCALLS_H */