syscalls.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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. #include <sgidefs.h>
  7. #ifndef __ASSEMBLER__
  8. #include <errno.h>
  9. /*
  10. * Import from:
  11. * glibc-ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
  12. * glibc-ports/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
  13. * glibc-ports/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
  14. */
  15. /* Define a macro which expands into the inline wrapper code for a system
  16. call. */
  17. #define INLINE_SYSCALL(name, nr, args...) \
  18. ({ INTERNAL_SYSCALL_DECL(err); \
  19. long result_var = INTERNAL_SYSCALL(name, err, nr, args); \
  20. if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \
  21. { \
  22. __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
  23. result_var = -1L; \
  24. } \
  25. result_var; })
  26. #define INLINE_SYSCALL_NOERR_NCS(name, nr, args...) \
  27. ({ \
  28. INTERNAL_SYSCALL_DECL(err); \
  29. long res = INTERNAL_SYSCALL_NCS(name, err, nr, args); \
  30. if (unlikely(INTERNAL_SYSCALL_ERROR_P(res, err))) { \
  31. res = -res; \
  32. } \
  33. res; \
  34. })
  35. #define INTERNAL_SYSCALL_DECL(err) long err attribute_unused
  36. #define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err))
  37. #define INTERNAL_SYSCALL_ERRNO(val, err) (val)
  38. #define INTERNAL_SYSCALL(name, err, nr, args...) \
  39. internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \
  40. "i" (SYS_ify (name)), err, args)
  41. #define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
  42. internal_syscall##nr (= number, , "r" (__v0), err, args)
  43. #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABI64
  44. # define ARG_TYPE long
  45. #else
  46. # define ARG_TYPE long long
  47. #endif
  48. #define internal_syscall0(ncs_init, cs_init, input, err, dummy...) \
  49. ({ \
  50. long _sys_result; \
  51. \
  52. { \
  53. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  54. register ARG_TYPE __a3 __asm__("$7"); \
  55. __asm__ __volatile__ ( \
  56. ".set\tnoreorder\n\t" \
  57. cs_init \
  58. "syscall\n\t" \
  59. ".set reorder" \
  60. : "=r" (__v0), "=r" (__a3) \
  61. : input \
  62. : __SYSCALL_CLOBBERS); \
  63. err = __a3; \
  64. _sys_result = __v0; \
  65. } \
  66. _sys_result; \
  67. })
  68. #define internal_syscall1(ncs_init, cs_init, input, err, arg1) \
  69. ({ \
  70. long _sys_result; \
  71. \
  72. { \
  73. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  74. register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
  75. register ARG_TYPE __a3 __asm__("$7"); \
  76. __asm__ __volatile__ ( \
  77. ".set\tnoreorder\n\t" \
  78. cs_init \
  79. "syscall\n\t" \
  80. ".set reorder" \
  81. : "=r" (__v0), "=r" (__a3) \
  82. : input, "r" (__a0) \
  83. : __SYSCALL_CLOBBERS); \
  84. err = __a3; \
  85. _sys_result = __v0; \
  86. } \
  87. _sys_result; \
  88. })
  89. #define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2) \
  90. ({ \
  91. long _sys_result; \
  92. \
  93. { \
  94. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  95. register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
  96. register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
  97. register ARG_TYPE __a3 __asm__("$7"); \
  98. __asm__ __volatile__ ( \
  99. ".set\tnoreorder\n\t" \
  100. cs_init \
  101. "syscall\n\t" \
  102. ".set\treorder" \
  103. : "=r" (__v0), "=r" (__a3) \
  104. : input, "r" (__a0), "r" (__a1) \
  105. : __SYSCALL_CLOBBERS); \
  106. err = __a3; \
  107. _sys_result = __v0; \
  108. } \
  109. _sys_result; \
  110. })
  111. #define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\
  112. ({ \
  113. long _sys_result; \
  114. \
  115. { \
  116. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  117. register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
  118. register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
  119. register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
  120. register ARG_TYPE __a3 __asm__("$7"); \
  121. __asm__ __volatile__ ( \
  122. ".set\tnoreorder\n\t" \
  123. cs_init \
  124. "syscall\n\t" \
  125. ".set\treorder" \
  126. : "=r" (__v0), "=r" (__a3) \
  127. : input, "r" (__a0), "r" (__a1), "r" (__a2) \
  128. : __SYSCALL_CLOBBERS); \
  129. err = __a3; \
  130. _sys_result = __v0; \
  131. } \
  132. _sys_result; \
  133. })
  134. #define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\
  135. ({ \
  136. long _sys_result; \
  137. \
  138. { \
  139. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  140. register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
  141. register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
  142. register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
  143. register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \
  144. __asm__ __volatile__ ( \
  145. ".set\tnoreorder\n\t" \
  146. cs_init \
  147. "syscall\n\t" \
  148. ".set\treorder" \
  149. : "=r" (__v0), "+r" (__a3) \
  150. : input, "r" (__a0), "r" (__a1), "r" (__a2) \
  151. : __SYSCALL_CLOBBERS); \
  152. err = __a3; \
  153. _sys_result = __v0; \
  154. } \
  155. _sys_result; \
  156. })
  157. #if _MIPS_SIM == _ABIO32
  158. #include <alloca.h>
  159. /* We need to use a frame pointer for the functions in which we
  160. adjust $sp around the syscall, or debug information and unwind
  161. information will be $sp relative and thus wrong during the syscall. As
  162. of GCC 3.4.3, this is sufficient. */
  163. #define FORCE_FRAME_POINTER alloca (4)
  164. #define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\
  165. ({ \
  166. long _sys_result; \
  167. \
  168. FORCE_FRAME_POINTER; \
  169. { \
  170. register long __v0 __asm__("$2") ncs_init; \
  171. register long __a0 __asm__("$4") = (long) arg1; \
  172. register long __a1 __asm__("$5") = (long) arg2; \
  173. register long __a2 __asm__("$6") = (long) arg3; \
  174. register long __a3 __asm__("$7") = (long) arg4; \
  175. __asm__ __volatile__ ( \
  176. ".set\tnoreorder\n\t" \
  177. "subu\t$29, 32\n\t" \
  178. "sw\t%6, 16($29)\n\t" \
  179. cs_init \
  180. "syscall\n\t" \
  181. "addiu\t$29, 32\n\t" \
  182. ".set\treorder" \
  183. : "=r" (__v0), "+r" (__a3) \
  184. : input, "r" (__a0), "r" (__a1), "r" (__a2), \
  185. "r" ((long)arg5) \
  186. : __SYSCALL_CLOBBERS); \
  187. err = __a3; \
  188. _sys_result = __v0; \
  189. } \
  190. _sys_result; \
  191. })
  192. #define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\
  193. ({ \
  194. long _sys_result; \
  195. \
  196. FORCE_FRAME_POINTER; \
  197. { \
  198. register long __v0 __asm__("$2") ncs_init; \
  199. register long __a0 __asm__("$4") = (long) arg1; \
  200. register long __a1 __asm__("$5") = (long) arg2; \
  201. register long __a2 __asm__("$6") = (long) arg3; \
  202. register long __a3 __asm__("$7") = (long) arg4; \
  203. __asm__ __volatile__ ( \
  204. ".set\tnoreorder\n\t" \
  205. "subu\t$29, 32\n\t" \
  206. "sw\t%6, 16($29)\n\t" \
  207. "sw\t%7, 20($29)\n\t" \
  208. cs_init \
  209. "syscall\n\t" \
  210. "addiu\t$29, 32\n\t" \
  211. ".set\treorder" \
  212. : "=r" (__v0), "+r" (__a3) \
  213. : input, "r" (__a0), "r" (__a1), "r" (__a2), \
  214. "r" ((long)arg5), "r" ((long)arg6) \
  215. : __SYSCALL_CLOBBERS); \
  216. err = __a3; \
  217. _sys_result = __v0; \
  218. } \
  219. _sys_result; \
  220. })
  221. #define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
  222. ({ \
  223. long _sys_result; \
  224. \
  225. FORCE_FRAME_POINTER; \
  226. { \
  227. register long __v0 __asm__("$2") ncs_init; \
  228. register long __a0 __asm__("$4") = (long) arg1; \
  229. register long __a1 __asm__("$5") = (long) arg2; \
  230. register long __a2 __asm__("$6") = (long) arg3; \
  231. register long __a3 __asm__("$7") = (long) arg4; \
  232. __asm__ __volatile__ ( \
  233. ".set\tnoreorder\n\t" \
  234. "subu\t$29, 32\n\t" \
  235. "sw\t%6, 16($29)\n\t" \
  236. "sw\t%7, 20($29)\n\t" \
  237. "sw\t%8, 24($29)\n\t" \
  238. cs_init \
  239. "syscall\n\t" \
  240. "addiu\t$29, 32\n\t" \
  241. ".set\treorder" \
  242. : "=r" (__v0), "+r" (__a3) \
  243. : input, "r" (__a0), "r" (__a1), "r" (__a2), \
  244. "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \
  245. : __SYSCALL_CLOBBERS); \
  246. err = __a3; \
  247. _sys_result = __v0; \
  248. } \
  249. _sys_result; \
  250. })
  251. #if __mips_isa_rev >= 6
  252. # define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
  253. "$14", "$15", "$24", "$25", "memory"
  254. #else
  255. # define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
  256. "$14", "$15", "$24", "$25", "hi", "lo", "memory"
  257. #endif
  258. #else /* N32 || N64 */
  259. #define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5) \
  260. ({ \
  261. long _sys_result; \
  262. \
  263. { \
  264. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  265. register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
  266. register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
  267. register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
  268. register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \
  269. register ARG_TYPE __a4 __asm__("$8") = (ARG_TYPE) arg5; \
  270. __asm__ __volatile__ ( \
  271. ".set\tnoreorder\n\t" \
  272. cs_init \
  273. "syscall\n\t" \
  274. ".set\treorder" \
  275. : "=r" (__v0), "+r" (__a3) \
  276. : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4) \
  277. : __SYSCALL_CLOBBERS); \
  278. err = __a3; \
  279. _sys_result = __v0; \
  280. } \
  281. _sys_result; \
  282. })
  283. #define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6) \
  284. ({ \
  285. long _sys_result; \
  286. \
  287. { \
  288. register ARG_TYPE __v0 __asm__("$2") ncs_init; \
  289. register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
  290. register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
  291. register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
  292. register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \
  293. register ARG_TYPE __a4 __asm__("$8") = (ARG_TYPE) arg5; \
  294. register ARG_TYPE __a5 __asm__("$9") = (ARG_TYPE) arg6; \
  295. __asm__ __volatile__ ( \
  296. ".set\tnoreorder\n\t" \
  297. cs_init \
  298. "syscall\n\t" \
  299. ".set\treorder" \
  300. : "=r" (__v0), "+r" (__a3) \
  301. : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), \
  302. "r" (__a5) \
  303. : __SYSCALL_CLOBBERS); \
  304. err = __a3; \
  305. _sys_result = __v0; \
  306. } \
  307. _sys_result; \
  308. })
  309. #if __mips_isa_rev >= 6
  310. # define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
  311. "$14", "$15", "$24", "$25", "memory"
  312. #else
  313. # define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
  314. "$14", "$15", "$24", "$25", "hi", "lo", "memory"
  315. #endif
  316. #endif
  317. #endif /* __ASSEMBLER__ */
  318. #endif /* _BITS_SYSCALLS_H */