master
  1/* Copyright (C) 1991-2025 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   <https://www.gnu.org/licenses/>.  */
 17
 18#include <sysdeps/generic/sysdep.h>
 19#include <single-thread.h>
 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#ifndef __ASSEMBLER__
 28# include <errno.h>
 29
 30#define __SYSCALL_CONCAT_X(a,b)     a##b
 31#define __SYSCALL_CONCAT(a,b)       __SYSCALL_CONCAT_X (a, b)
 32
 33
 34#define __INTERNAL_SYSCALL0(name) \
 35  INTERNAL_SYSCALL (name, 0)
 36#define __INTERNAL_SYSCALL1(name, a1) \
 37  INTERNAL_SYSCALL (name, 1, a1)
 38#define __INTERNAL_SYSCALL2(name, a1, a2) \
 39  INTERNAL_SYSCALL (name, 2, a1, a2)
 40#define __INTERNAL_SYSCALL3(name, a1, a2, a3) \
 41  INTERNAL_SYSCALL (name, 3, a1, a2, a3)
 42#define __INTERNAL_SYSCALL4(name, a1, a2, a3, a4) \
 43  INTERNAL_SYSCALL (name, 4, a1, a2, a3, a4)
 44#define __INTERNAL_SYSCALL5(name, a1, a2, a3, a4, a5) \
 45  INTERNAL_SYSCALL (name, 5, a1, a2, a3, a4, a5)
 46#define __INTERNAL_SYSCALL6(name, a1, a2, a3, a4, a5, a6) \
 47  INTERNAL_SYSCALL (name, 6, a1, a2, a3, a4, a5, a6)
 48#define __INTERNAL_SYSCALL7(name, a1, a2, a3, a4, a5, a6, a7) \
 49  INTERNAL_SYSCALL (name, 7, a1, a2, a3, a4, a5, a6, a7)
 50
 51#define __INTERNAL_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
 52#define __INTERNAL_SYSCALL_NARGS(...) \
 53  __INTERNAL_SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
 54#define __INTERNAL_SYSCALL_DISP(b,...) \
 55  __SYSCALL_CONCAT (b,__INTERNAL_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
 56
 57/* Issue a syscall defined by syscall number plus any other argument required.
 58   It is similar to INTERNAL_SYSCALL macro, but without the need to pass the
 59   expected argument number as second parameter.  */
 60#define INTERNAL_SYSCALL_CALL(...) \
 61  __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL, __VA_ARGS__)
 62
 63#define __INTERNAL_SYSCALL_NCS0(name) \
 64  INTERNAL_SYSCALL_NCS (name, 0)
 65#define __INTERNAL_SYSCALL_NCS1(name, a1) \
 66  INTERNAL_SYSCALL_NCS (name, 1, a1)
 67#define __INTERNAL_SYSCALL_NCS2(name, a1, a2) \
 68  INTERNAL_SYSCALL_NCS (name, 2, a1, a2)
 69#define __INTERNAL_SYSCALL_NCS3(name, a1, a2, a3) \
 70  INTERNAL_SYSCALL_NCS (name, 3, a1, a2, a3)
 71#define __INTERNAL_SYSCALL_NCS4(name, a1, a2, a3, a4) \
 72  INTERNAL_SYSCALL_NCS (name, 4, a1, a2, a3, a4)
 73#define __INTERNAL_SYSCALL_NCS5(name, a1, a2, a3, a4, a5) \
 74  INTERNAL_SYSCALL_NCS (name, 5, a1, a2, a3, a4, a5)
 75#define __INTERNAL_SYSCALL_NCS6(name, a1, a2, a3, a4, a5, a6) \
 76  INTERNAL_SYSCALL_NCS (name, 6, a1, a2, a3, a4, a5, a6)
 77#define __INTERNAL_SYSCALL_NCS7(name, a1, a2, a3, a4, a5, a6, a7) \
 78  INTERNAL_SYSCALL_NCS (name, 7, a1, a2, a3, a4, a5, a6, a7)
 79
 80#define INTERNAL_SYSCALL_NCS_CALL(...) \
 81  __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL_NCS, __VA_ARGS__)
 82
 83#define __INLINE_SYSCALL0(name) \
 84  INLINE_SYSCALL (name, 0)
 85#define __INLINE_SYSCALL1(name, a1) \
 86  INLINE_SYSCALL (name, 1, a1)
 87#define __INLINE_SYSCALL2(name, a1, a2) \
 88  INLINE_SYSCALL (name, 2, a1, a2)
 89#define __INLINE_SYSCALL3(name, a1, a2, a3) \
 90  INLINE_SYSCALL (name, 3, a1, a2, a3)
 91#define __INLINE_SYSCALL4(name, a1, a2, a3, a4) \
 92  INLINE_SYSCALL (name, 4, a1, a2, a3, a4)
 93#define __INLINE_SYSCALL5(name, a1, a2, a3, a4, a5) \
 94  INLINE_SYSCALL (name, 5, a1, a2, a3, a4, a5)
 95#define __INLINE_SYSCALL6(name, a1, a2, a3, a4, a5, a6) \
 96  INLINE_SYSCALL (name, 6, a1, a2, a3, a4, a5, a6)
 97#define __INLINE_SYSCALL7(name, a1, a2, a3, a4, a5, a6, a7) \
 98  INLINE_SYSCALL (name, 7, a1, a2, a3, a4, a5, a6, a7)
 99
100#define __INLINE_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
101#define __INLINE_SYSCALL_NARGS(...) \
102  __INLINE_SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
103#define __INLINE_SYSCALL_DISP(b,...) \
104  __SYSCALL_CONCAT (b,__INLINE_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
105
106/* Issue a syscall defined by syscall number plus any other argument
107   required.  Any error will be handled using arch defined macros and errno
108   will be set accordingly.
109   It is similar to INLINE_SYSCALL macro, but without the need to pass the
110   expected argument number as second parameter.  */
111#define INLINE_SYSCALL_CALL(...) \
112  __INLINE_SYSCALL_DISP (__INLINE_SYSCALL, __VA_ARGS__)
113
114#define __INTERNAL_SYSCALL_NCS0(name) \
115  INTERNAL_SYSCALL_NCS (name, 0)
116#define __INTERNAL_SYSCALL_NCS1(name, a1) \
117  INTERNAL_SYSCALL_NCS (name, 1, a1)
118#define __INTERNAL_SYSCALL_NCS2(name, a1, a2) \
119  INTERNAL_SYSCALL_NCS (name, 2, a1, a2)
120#define __INTERNAL_SYSCALL_NCS3(name, a1, a2, a3) \
121  INTERNAL_SYSCALL_NCS (name, 3, a1, a2, a3)
122#define __INTERNAL_SYSCALL_NCS4(name, a1, a2, a3, a4) \
123  INTERNAL_SYSCALL_NCS (name, 4, a1, a2, a3, a4)
124#define __INTERNAL_SYSCALL_NCS5(name, a1, a2, a3, a4, a5) \
125  INTERNAL_SYSCALL_NCS (name, 5, a1, a2, a3, a4, a5)
126#define __INTERNAL_SYSCALL_NCS6(name, a1, a2, a3, a4, a5, a6) \
127  INTERNAL_SYSCALL_NCS (name, 6, a1, a2, a3, a4, a5, a6)
128#define __INTERNAL_SYSCALL_NCS7(name, a1, a2, a3, a4, a5, a6, a7) \
129  INTERNAL_SYSCALL_NCS (name, 7, a1, a2, a3, a4, a5, a6, a7)
130
131/* Issue a syscall defined by syscall number plus any other argument required.
132   It is similar to INTERNAL_SYSCALL_NCS macro, but without the need to pass
133   the expected argument number as third parameter.  */
134#define INTERNAL_SYSCALL_NCS_CALL(...) \
135  __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL_NCS, __VA_ARGS__)
136
137/* Cancellation macros.  */
138#include <syscall_types.h>
139
140/* Adjust both the __syscall_cancel and the SYSCALL_CANCEL macro to support
141   7 arguments instead of default 6 (curently only mip32).  It avoid add
142   the requirement to each architecture to support 7 argument macros
143   {INTERNAL,INLINE}_SYSCALL.  */
144#ifdef HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS
145# define __SYSCALL_CANCEL7_ARG_DEF	__syscall_arg_t a7,
146# define __SYSCALL_CANCEL7_ARCH_ARG_DEF ,__syscall_arg_t a7
147# define __SYSCALL_CANCEL7_ARG		0,
148# define __SYSCALL_CANCEL7_ARG7		a7,
149# define __SYSCALL_CANCEL7_ARCH_ARG7	, a7
150#else
151# define __SYSCALL_CANCEL7_ARG_DEF
152# define __SYSCALL_CANCEL7_ARCH_ARG_DEF
153# define __SYSCALL_CANCEL7_ARG
154# define __SYSCALL_CANCEL7_ARG7
155# define __SYSCALL_CANCEL7_ARCH_ARG7
156#endif
157long int __internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
158				    __syscall_arg_t a3, __syscall_arg_t a4,
159				    __syscall_arg_t a5, __syscall_arg_t a6,
160				    __SYSCALL_CANCEL7_ARG_DEF
161				    __syscall_arg_t nr) attribute_hidden;
162
163long int __syscall_cancel (__syscall_arg_t arg1, __syscall_arg_t arg2,
164			   __syscall_arg_t arg3, __syscall_arg_t arg4,
165			   __syscall_arg_t arg5, __syscall_arg_t arg6,
166			   __SYSCALL_CANCEL7_ARG_DEF
167			   __syscall_arg_t nr) attribute_hidden;
168
169#define __SYSCALL_CANCEL0(name)						\
170  __syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
171#define __SYSCALL_CANCEL1(name, a1)					\
172  __syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0,				\
173		    __SYSCALL_CANCEL7_ARG __NR_##name)
174#define __SYSCALL_CANCEL2(name, a1, a2) \
175  __syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0,			\
176		    __SYSCALL_CANCEL7_ARG __NR_##name)
177#define __SYSCALL_CANCEL3(name, a1, a2, a3) \
178  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0, 0, 0,	\
179		    __SYSCALL_CANCEL7_ARG __NR_##name)
180#define __SYSCALL_CANCEL4(name, a1, a2, a3, a4) \
181  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),			\
182		    __SSC(a4), 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
183#define __SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \
184  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC(a4),	\
185		    __SSC (a5), 0, __SYSCALL_CANCEL7_ARG __NR_##name)
186#define __SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \
187  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4),	\
188		    __SSC (a5), __SSC (a6), __SYSCALL_CANCEL7_ARG	\
189		    __NR_##name)
190#define __SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7)		\
191  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4),	\
192		    __SSC (a5), __SSC (a6), __SSC (a7), __NR_##name)
193
194#define __SYSCALL_CANCEL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
195#define __SYSCALL_CANCEL_NARGS(...) \
196  __SYSCALL_CANCEL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
197#define __SYSCALL_CANCEL_CONCAT_X(a,b)     a##b
198#define __SYSCALL_CANCEL_CONCAT(a,b)       __SYSCALL_CANCEL_CONCAT_X (a, b)
199#define __SYSCALL_CANCEL_DISP(b,...) \
200  __SYSCALL_CANCEL_CONCAT (b,__SYSCALL_CANCEL_NARGS(__VA_ARGS__))(__VA_ARGS__)
201
202/* Issue a cancellable syscall defined first argument plus any other argument
203   required.  If and error occurs its value, the macro returns -1 and sets
204   errno accordingly.  */
205#define __SYSCALL_CANCEL_CALL(...) \
206  __SYSCALL_CANCEL_DISP (__SYSCALL_CANCEL, __VA_ARGS__)
207
208#define __INTERNAL_SYSCALL_CANCEL0(name)				\
209  __internal_syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG	\
210			     __NR_##name)
211#define __INTERNAL_SYSCALL_CANCEL1(name, a1)				\
212  __internal_syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0,			\
213			     __SYSCALL_CANCEL7_ARG __NR_##name)
214#define __INTERNAL_SYSCALL_CANCEL2(name, a1, a2)			\
215  __internal_syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0,	\
216			     __SYSCALL_CANCEL7_ARG __NR_##name)
217#define __INTERNAL_SYSCALL_CANCEL3(name, a1, a2, a3)			\
218  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0,	\
219			     0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
220#define __INTERNAL_SYSCALL_CANCEL4(name, a1, a2, a3, a4)		\
221  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
222			     __SSC(a4), 0, 0,				\
223			     __SYSCALL_CANCEL7_ARG __NR_##name)
224#define __INTERNAL_SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5)		\
225  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
226			     __SSC(a4), __SSC (a5), 0,			\
227			     __SYSCALL_CANCEL7_ARG __NR_##name)
228#define __INTERNAL_SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6)	\
229  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
230			     __SSC (a4), __SSC (a5), __SSC (a6),	\
231			     __SYSCALL_CANCEL7_ARG __NR_##name)
232#define __INTERNAL_SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7) \
233  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),     \
234			     __SSC (a4), __SSC (a5), __SSC (a6),     \
235			     __SSC (a7), __NR_##name)
236
237/* Issue a cancellable syscall defined by syscall number NAME plus any other
238   argument required.  If an error occurs its value is returned as an negative
239   number unmodified and errno is not set.  */
240#define __INTERNAL_SYSCALL_CANCEL_CALL(...) \
241  __SYSCALL_CANCEL_DISP (__INTERNAL_SYSCALL_CANCEL, __VA_ARGS__)
242
243#if IS_IN (rtld)
244/* The loader does not need to handle thread cancellation, use direct
245   syscall instead.  */
246# define INTERNAL_SYSCALL_CANCEL(...) INTERNAL_SYSCALL_CALL(__VA_ARGS__)
247# define SYSCALL_CANCEL(...)          INLINE_SYSCALL_CALL (__VA_ARGS__)
248#else
249# define INTERNAL_SYSCALL_CANCEL(...) \
250  __INTERNAL_SYSCALL_CANCEL_CALL (__VA_ARGS__)
251# define SYSCALL_CANCEL(...) \
252  __SYSCALL_CANCEL_CALL (__VA_ARGS__)
253#endif
254
255#endif /* __ASSEMBLER__  */
256
257/* Machine-dependent sysdep.h files are expected to define the macro
258   PSEUDO (function_name, syscall_name) to emit assembly code to define the
259   C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
260   r0 and r1 are the system call outputs.  MOVE(x, y) should be defined as
261   an instruction such that "MOVE(r1, r0)" works.  ret should be defined
262   as the return instruction.  */
263
264#ifndef SYS_ify
265#define SYS_ify(syscall_name) SYS_##syscall_name
266#endif
267
268/* Terminate a system call named SYM.  This is used on some platforms
269   to generate correct debugging information.  */
270#ifndef PSEUDO_END
271#define PSEUDO_END(sym)
272#endif
273#ifndef PSEUDO_END_NOERRNO
274#define PSEUDO_END_NOERRNO(sym)	PSEUDO_END(sym)
275#endif
276#ifndef PSEUDO_END_ERRVAL
277#define PSEUDO_END_ERRVAL(sym)	PSEUDO_END(sym)
278#endif
279
280/* Wrappers around system calls should normally inline the system call code.
281   But sometimes it is not possible or implemented and we use this code.  */
282#ifndef INLINE_SYSCALL
283#define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
284#endif