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