sysdep.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* Copyright (C) 1991-2019 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, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <sysdeps/generic/sysdep.h>
  15. #include <sys/syscall.h>
  16. #define HAVE_SYSCALLS
  17. /* Note that using a `PASTE' macro loses. */
  18. #define SYSCALL__(name, args) PSEUDO (__##name, name, args)
  19. #define SYSCALL(name, args) PSEUDO (name, name, args)
  20. #define __SYSCALL_CONCAT_X(a,b) a##b
  21. #define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X (a, b)
  22. #define __INTERNAL_SYSCALL0(name, err) \
  23. INTERNAL_SYSCALL (name, err, 0)
  24. #define __INTERNAL_SYSCALL1(name, err, a1) \
  25. INTERNAL_SYSCALL (name, err, 1, a1)
  26. #define __INTERNAL_SYSCALL2(name, err, a1, a2) \
  27. INTERNAL_SYSCALL (name, err, 2, a1, a2)
  28. #define __INTERNAL_SYSCALL3(name, err, a1, a2, a3) \
  29. INTERNAL_SYSCALL (name, err, 3, a1, a2, a3)
  30. #define __INTERNAL_SYSCALL4(name, err, a1, a2, a3, a4) \
  31. INTERNAL_SYSCALL (name, err, 4, a1, a2, a3, a4)
  32. #define __INTERNAL_SYSCALL5(name, err, a1, a2, a3, a4, a5) \
  33. INTERNAL_SYSCALL (name, err, 5, a1, a2, a3, a4, a5)
  34. #define __INTERNAL_SYSCALL6(name, err, a1, a2, a3, a4, a5, a6) \
  35. INTERNAL_SYSCALL (name, err, 6, a1, a2, a3, a4, a5, a6)
  36. #define __INTERNAL_SYSCALL7(name, err, a1, a2, a3, a4, a5, a6, a7) \
  37. INTERNAL_SYSCALL (name, err, 7, a1, a2, a3, a4, a5, a6, a7)
  38. #define __INTERNAL_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,o,...) o
  39. #define __INTERNAL_SYSCALL_NARGS(...) \
  40. __INTERNAL_SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
  41. #define __INTERNAL_SYSCALL_DISP(b,...) \
  42. __SYSCALL_CONCAT (b,__INTERNAL_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
  43. /* Issue a syscall defined by syscall number plus any other argument required.
  44. It is similar to INTERNAL_SYSCALL macro, but without the need to pass the
  45. expected argument number as second parameter. */
  46. #define INTERNAL_SYSCALL_CALL(...) \
  47. __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL, __VA_ARGS__)
  48. #define __INLINE_SYSCALL0(name) \
  49. INLINE_SYSCALL (name, 0)
  50. #define __INLINE_SYSCALL1(name, a1) \
  51. INLINE_SYSCALL (name, 1, a1)
  52. #define __INLINE_SYSCALL2(name, a1, a2) \
  53. INLINE_SYSCALL (name, 2, a1, a2)
  54. #define __INLINE_SYSCALL3(name, a1, a2, a3) \
  55. INLINE_SYSCALL (name, 3, a1, a2, a3)
  56. #define __INLINE_SYSCALL4(name, a1, a2, a3, a4) \
  57. INLINE_SYSCALL (name, 4, a1, a2, a3, a4)
  58. #define __INLINE_SYSCALL5(name, a1, a2, a3, a4, a5) \
  59. INLINE_SYSCALL (name, 5, a1, a2, a3, a4, a5)
  60. #define __INLINE_SYSCALL6(name, a1, a2, a3, a4, a5, a6) \
  61. INLINE_SYSCALL (name, 6, a1, a2, a3, a4, a5, a6)
  62. #define __INLINE_SYSCALL7(name, a1, a2, a3, a4, a5, a6, a7) \
  63. INLINE_SYSCALL (name, 7, a1, a2, a3, a4, a5, a6, a7)
  64. #define __INLINE_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
  65. #define __INLINE_SYSCALL_NARGS(...) \
  66. __INLINE_SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
  67. #define __INLINE_SYSCALL_DISP(b,...) \
  68. __SYSCALL_CONCAT (b,__INLINE_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
  69. /* Issue a syscall defined by syscall number plus any other argument
  70. required. Any error will be handled using arch defined macros and errno
  71. will be set accordingly.
  72. It is similar to INLINE_SYSCALL macro, but without the need to pass the
  73. expected argument number as second parameter. */
  74. #define INLINE_SYSCALL_CALL(...) \
  75. __INLINE_SYSCALL_DISP (__INLINE_SYSCALL, __VA_ARGS__)
  76. #define SYSCALL_CANCEL(...) \
  77. ({ \
  78. long int sc_ret; \
  79. if (SINGLE_THREAD_P) \
  80. sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__); \
  81. else \
  82. { \
  83. int sc_cancel_oldtype = LIBC_CANCEL_ASYNC (); \
  84. sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__); \
  85. LIBC_CANCEL_RESET (sc_cancel_oldtype); \
  86. } \
  87. sc_ret; \
  88. })
  89. /* Issue a syscall defined by syscall number plus any other argument
  90. required. Any error will be returned unmodified (including errno). */
  91. #define INTERNAL_SYSCALL_CANCEL(...) \
  92. ({ \
  93. long int sc_ret; \
  94. if (SINGLE_THREAD_P) \
  95. sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__); \
  96. else \
  97. { \
  98. int sc_cancel_oldtype = LIBC_CANCEL_ASYNC (); \
  99. sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__); \
  100. LIBC_CANCEL_RESET (sc_cancel_oldtype); \
  101. } \
  102. sc_ret; \
  103. })
  104. /* Machine-dependent sysdep.h files are expected to define the macro
  105. PSEUDO (function_name, syscall_name) to emit assembly code to define the
  106. C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
  107. r0 and r1 are the system call outputs. MOVE(x, y) should be defined as
  108. an instruction such that "MOVE(r1, r0)" works. ret should be defined
  109. as the return instruction. */
  110. #ifndef SYS_ify
  111. #define SYS_ify(syscall_name) SYS_##syscall_name
  112. #endif
  113. /* Terminate a system call named SYM. This is used on some platforms
  114. to generate correct debugging information. */
  115. #ifndef PSEUDO_END
  116. #define PSEUDO_END(sym)
  117. #endif
  118. #ifndef PSEUDO_END_NOERRNO
  119. #define PSEUDO_END_NOERRNO(sym) PSEUDO_END(sym)
  120. #endif
  121. #ifndef PSEUDO_END_ERRVAL
  122. #define PSEUDO_END_ERRVAL(sym) PSEUDO_END(sym)
  123. #endif
  124. /* Wrappers around system calls should normally inline the system call code.
  125. But sometimes it is not possible or implemented and we use this code. */
  126. #ifndef INLINE_SYSCALL
  127. #define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
  128. #endif