syscalls.h 9.8 KB

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