| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* Copyright (C) 1991-2016 Free Software Foundation, Inc. | 
|  | 2 | This file is part of the GNU C Library. | 
|  | 3 |  | 
|  | 4 | The GNU C Library is free software; you can redistribute it and/or | 
|  | 5 | modify it under the terms of the GNU Lesser General Public | 
|  | 6 | License as published by the Free Software Foundation; either | 
|  | 7 | version 2.1 of the License, or (at your option) any later version. | 
|  | 8 |  | 
|  | 9 | The GNU C Library is distributed in the hope that it will be useful, | 
|  | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | 12 | Lesser General Public License for more details. | 
|  | 13 |  | 
|  | 14 | You should have received a copy of the GNU Lesser General Public | 
|  | 15 | License along with the GNU C Library; if not, see | 
|  | 16 | <http://www.gnu.org/licenses/>.  */ | 
|  | 17 |  | 
|  | 18 | #include <sysdeps/generic/sysdep.h> | 
|  | 19 |  | 
|  | 20 | #include <sys/syscall.h> | 
|  | 21 | #define	HAVE_SYSCALLS | 
|  | 22 |  | 
|  | 23 | /* Note that using a `PASTE' macro loses.  */ | 
|  | 24 | #define	SYSCALL__(name, args)	PSEUDO (__##name, name, args) | 
|  | 25 | #define	SYSCALL(name, args)	PSEUDO (name, name, args) | 
|  | 26 |  | 
|  | 27 | #define __SYSCALL0(name) \ | 
|  | 28 | INLINE_SYSCALL (name, 0) | 
|  | 29 | #define __SYSCALL1(name, a1) \ | 
|  | 30 | INLINE_SYSCALL (name, 1, a1) | 
|  | 31 | #define __SYSCALL2(name, a1, a2) \ | 
|  | 32 | INLINE_SYSCALL (name, 2, a1, a2) | 
|  | 33 | #define __SYSCALL3(name, a1, a2, a3) \ | 
|  | 34 | INLINE_SYSCALL (name, 3, a1, a2, a3) | 
|  | 35 | #define __SYSCALL4(name, a1, a2, a3, a4) \ | 
|  | 36 | INLINE_SYSCALL (name, 4, a1, a2, a3, a4) | 
|  | 37 | #define __SYSCALL5(name, a1, a2, a3, a4, a5) \ | 
|  | 38 | INLINE_SYSCALL (name, 5, a1, a2, a3, a4, a5) | 
|  | 39 | #define __SYSCALL6(name, a1, a2, a3, a4, a5, a6) \ | 
|  | 40 | INLINE_SYSCALL (name, 6, a1, a2, a3, a4, a5, a6) | 
|  | 41 | #define __SYSCALL7(name, a1, a2, a3, a4, a5, a6, a7) \ | 
|  | 42 | INLINE_SYSCALL (name, 7, a1, a2, a3, a4, a5, a6, a7) | 
|  | 43 |  | 
|  | 44 | #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n | 
|  | 45 | #define __SYSCALL_NARGS(...) \ | 
|  | 46 | __SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,) | 
|  | 47 | #define __SYSCALL_CONCAT_X(a,b)     a##b | 
|  | 48 | #define __SYSCALL_CONCAT(a,b)       __SYSCALL_CONCAT_X (a, b) | 
|  | 49 | #define __SYSCALL_DISP(b,...) \ | 
|  | 50 | __SYSCALL_CONCAT (b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) | 
|  | 51 |  | 
|  | 52 | #define __SYSCALL_CALL(...) __SYSCALL_DISP (__SYSCALL, __VA_ARGS__) | 
|  | 53 |  | 
|  | 54 | #define SYSCALL_CANCEL(...) \ | 
|  | 55 | ({									     \ | 
|  | 56 | long int sc_ret;							     \ | 
|  | 57 | if (SINGLE_THREAD_P) 						     \ | 
|  | 58 | sc_ret = __SYSCALL_CALL (__VA_ARGS__);   				     \ | 
|  | 59 | else								     \ | 
|  | 60 | {									     \ | 
|  | 61 | int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();			     \ | 
|  | 62 | sc_ret = __SYSCALL_CALL (__VA_ARGS__);				     \ | 
|  | 63 | LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \ | 
|  | 64 | }									     \ | 
|  | 65 | sc_ret;								     \ | 
|  | 66 | }) | 
|  | 67 |  | 
|  | 68 | /* Machine-dependent sysdep.h files are expected to define the macro | 
|  | 69 | PSEUDO (function_name, syscall_name) to emit assembly code to define the | 
|  | 70 | C-callable function FUNCTION_NAME to do system call SYSCALL_NAME. | 
|  | 71 | r0 and r1 are the system call outputs.  MOVE(x, y) should be defined as | 
|  | 72 | an instruction such that "MOVE(r1, r0)" works.  ret should be defined | 
|  | 73 | as the return instruction.  */ | 
|  | 74 |  | 
|  | 75 | #ifndef SYS_ify | 
|  | 76 | #define SYS_ify(syscall_name) SYS_##syscall_name | 
|  | 77 | #endif | 
|  | 78 |  | 
|  | 79 | /* Terminate a system call named SYM.  This is used on some platforms | 
|  | 80 | to generate correct debugging information.  */ | 
|  | 81 | #ifndef PSEUDO_END | 
|  | 82 | #define PSEUDO_END(sym) | 
|  | 83 | #endif | 
|  | 84 | #ifndef PSEUDO_END_NOERRNO | 
|  | 85 | #define PSEUDO_END_NOERRNO(sym)	PSEUDO_END(sym) | 
|  | 86 | #endif | 
|  | 87 | #ifndef PSEUDO_END_ERRVAL | 
|  | 88 | #define PSEUDO_END_ERRVAL(sym)	PSEUDO_END(sym) | 
|  | 89 | #endif | 
|  | 90 |  | 
|  | 91 | /* Wrappers around system calls should normally inline the system call code. | 
|  | 92 | But sometimes it is not possible or implemented and we use this code.  */ | 
|  | 93 | #ifndef INLINE_SYSCALL | 
|  | 94 | #define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args) | 
|  | 95 | #endif |