syscalls.h 12 KB

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