blob: 6dc588846b7f6874f180e00db54be918123fde63 [file] [log] [blame]
Mike Frysinger3159ddc2022-09-07 08:24:21 -04001/* Copyright 2005-2011 Google LLC
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following disclaimer
11 * in the documentation and/or other materials provided with the
12 * distribution.
Mike Frysinger3159ddc2022-09-07 08:24:21 -040013 * * Neither the name of Google LLC nor the names of its
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000014 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * ---
30 * Author: Markus Gutschke
31 */
32
33/* This file includes Linux-specific support functions common to the
34 * coredumper and the thread lister; primarily, this is a collection
35 * of direct system calls, and a couple of symbols missing from
36 * standard header files.
37 * There are a few options that the including file can set to control
38 * the behavior of this file:
39 *
40 * SYS_CPLUSPLUS:
41 * The entire header file will normally be wrapped in 'extern "C" { }",
42 * making it suitable for compilation as both C and C++ source. If you
43 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
44 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
45 * system header files, too. It is the caller's responsibility to provide
46 * the necessary definitions.
47 *
48 * SYS_ERRNO:
Andreas Deiningerb0fa1562022-09-30 18:13:22 +020049 * All system calls will update "errno" unless overridden by setting the
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000050 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
51 * an l-value.
52 *
53 * SYS_INLINE:
54 * New symbols will be defined "static inline", unless overridden by
55 * the SYS_INLINE macro.
56 *
57 * SYS_LINUX_SYSCALL_SUPPORT_H
58 * This macro is used to avoid multiple inclusions of this header file.
59 * If you need to include this file more than once, make sure to
60 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
61 *
62 * SYS_PREFIX:
63 * New system calls will have a prefix of "sys_" unless overridden by
64 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
65 * results in prefixes "sys[0..9]_". It is also possible to set this
66 * macro to -1, which avoids all prefixes.
67 *
68 * SYS_SYSCALL_ENTRYPOINT:
69 * Some applications (such as sandboxes that filter system calls), need
70 * to be able to run custom-code each time a system call is made. If this
71 * macro is defined, it expands to the name of a "common" symbol. If
72 * this symbol is assigned a non-NULL pointer value, it is used as the
73 * address of the system call entrypoint.
74 * A pointer to this symbol can be obtained by calling
75 * get_syscall_entrypoint()
76 *
77 * This file defines a few internal symbols that all start with "LSS_".
78 * Do not access these symbols from outside this file. They are not part
79 * of the supported API.
80 */
81#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
82#define SYS_LINUX_SYSCALL_SUPPORT_H
83
Bryan Chan3f6478a2016-06-14 08:38:17 -040084/* We currently only support x86-32, x86-64, ARM, MIPS, PPC, s390 and s390x
85 * on Linux.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000086 * Porting to other related platforms should not be difficult.
87 */
88#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
anton@chromium.org2f724fc2014-04-15 13:05:20 +000089 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \
Andreas Schwab1d387f42022-02-15 16:21:13 +010090 defined(__aarch64__) || defined(__s390__) || defined(__e2k__) || \
mingtaoxt xtc0c96892022-08-11 16:53:21 +080091 (defined(__riscv) && __riscv_xlen == 64) || defined(__loongarch_lp64)) \
zodiac@gmail.com4f470182010-10-13 03:47:54 +000092 && (defined(__linux) || defined(__ANDROID__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000093
94#ifndef SYS_CPLUSPLUS
95#ifdef __cplusplus
96/* Some system header files in older versions of gcc neglect to properly
97 * handle being included from C++. As it appears to be harmless to have
98 * multiple nested 'extern "C"' blocks, just add another one here.
99 */
100extern "C" {
101#endif
102
103#include <errno.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000104#include <fcntl.h>
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000105#include <sched.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000106#include <signal.h>
107#include <stdarg.h>
108#include <stddef.h>
vapier@chromium.org2273e812013-04-01 17:52:44 +0000109#include <stdint.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000110#include <string.h>
111#include <sys/ptrace.h>
112#include <sys/resource.h>
113#include <sys/time.h>
114#include <sys/types.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000115#include <sys/syscall.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000116#include <unistd.h>
117#include <linux/unistd.h>
118#include <endian.h>
119
120#ifdef __mips__
121/* Include definitions of the ABI currently in use. */
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000122#ifdef __ANDROID__
123/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h,
124 * which has the definitions we need.
125 */
126#include <asm/sgidefs.h>
127#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000128#include <sgidefs.h>
129#endif
130#endif
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000131#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000132
Michael Forneyf70e2f12020-01-22 19:19:38 -0800133/* Some libcs, for example Android NDK and musl, #define these
134 * macros as aliases to their non-64 counterparts. To avoid naming
135 * conflict, remove them.
136 *
137 * These are restored by the corresponding #pragma pop_macro near
138 * the end of this file.
139 */
140#pragma push_macro("stat64")
141#pragma push_macro("fstat64")
142#pragma push_macro("lstat64")
143#pragma push_macro("pread64")
144#pragma push_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700145#pragma push_macro("getdents64")
Michael Forneyf70e2f12020-01-22 19:19:38 -0800146#undef stat64
147#undef fstat64
148#undef lstat64
149#undef pread64
150#undef pwrite64
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700151#undef getdents64
mseaborn@chromium.orgca749372012-09-05 18:26:20 +0000152
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400153#if defined(__ANDROID__) && defined(__x86_64__)
154// A number of x86_64 syscalls are blocked by seccomp on recent Android;
155// undefine them so that modern alternatives will be used instead where
156// possible.
157// The alternative syscalls have been sanity checked against linux-3.4+;
158// older versions might not work.
159# undef __NR_getdents
160# undef __NR_dup2
161# undef __NR_fork
162# undef __NR_getpgrp
163# undef __NR_open
164# undef __NR_poll
165# undef __NR_readlink
166# undef __NR_stat
167# undef __NR_unlink
168# undef __NR_pipe
169#endif
170
171#if defined(__ANDROID__)
172// waitpid is blocked by seccomp on all architectures on recent Android.
173# undef __NR_waitpid
174#endif
175
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000176/* As glibc often provides subtly incompatible data structures (and implicit
177 * wrapper functions that convert them), we provide our own kernel data
178 * structures for use by the system calls.
179 * These structures have been developed by using Linux 2.6.23 headers for
180 * reference. Note though, we do not care about exact API compatibility
181 * with the kernel, and in fact the kernel often does not have a single
182 * API that works across architectures. Instead, we try to mimic the glibc
183 * API where reasonable, and only guarantee ABI compatibility with the
184 * kernel headers.
185 * Most notably, here are a few changes that were made to the structures
186 * defined by kernel headers:
187 *
188 * - we only define structures, but not symbolic names for kernel data
189 * types. For the latter, we directly use the native C datatype
190 * (i.e. "unsigned" instead of "mode_t").
191 * - in a few cases, it is possible to define identical structures for
192 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
193 * standardizing on the 64bit version of the data types. In particular,
194 * this means that we use "unsigned" where the 32bit headers say
195 * "unsigned long".
196 * - overall, we try to minimize the number of cases where we need to
197 * conditionally define different structures.
198 * - the "struct kernel_sigaction" class of structures have been
199 * modified to more closely mimic glibc's API by introducing an
200 * anonymous union for the function pointer.
201 * - a small number of field names had to have an underscore appended to
202 * them, because glibc defines a global macro by the same name.
203 */
204
205/* include/linux/dirent.h */
206struct kernel_dirent64 {
207 unsigned long long d_ino;
208 long long d_off;
209 unsigned short d_reclen;
210 unsigned char d_type;
211 char d_name[256];
212};
213
214/* include/linux/dirent.h */
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400215#if !defined(__NR_getdents)
216// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000217#define kernel_dirent kernel_dirent64
218#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000219struct kernel_dirent {
220 long d_ino;
221 long d_off;
222 unsigned short d_reclen;
223 char d_name[256];
224};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000225#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000226
227/* include/linux/uio.h */
228struct kernel_iovec {
229 void *iov_base;
230 unsigned long iov_len;
231};
232
233/* include/linux/socket.h */
234struct kernel_msghdr {
235 void *msg_name;
236 int msg_namelen;
237 struct kernel_iovec*msg_iov;
238 unsigned long msg_iovlen;
239 void *msg_control;
240 unsigned long msg_controllen;
241 unsigned msg_flags;
242};
243
244/* include/asm-generic/poll.h */
245struct kernel_pollfd {
246 int fd;
247 short events;
248 short revents;
249};
250
251/* include/linux/resource.h */
252struct kernel_rlimit {
253 unsigned long rlim_cur;
254 unsigned long rlim_max;
255};
256
257/* include/linux/time.h */
258struct kernel_timespec {
259 long tv_sec;
260 long tv_nsec;
261};
262
263/* include/linux/time.h */
264struct kernel_timeval {
265 long tv_sec;
266 long tv_usec;
267};
268
Doug Kwan32a80cd2022-07-01 17:52:39 +0000269/* include/linux/time.h */
270struct kernel_itimerval {
271 struct kernel_timeval it_interval;
272 struct kernel_timeval it_value;
273};
274
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000275/* include/linux/resource.h */
276struct kernel_rusage {
277 struct kernel_timeval ru_utime;
278 struct kernel_timeval ru_stime;
279 long ru_maxrss;
280 long ru_ixrss;
281 long ru_idrss;
282 long ru_isrss;
283 long ru_minflt;
284 long ru_majflt;
285 long ru_nswap;
286 long ru_inblock;
287 long ru_oublock;
288 long ru_msgsnd;
289 long ru_msgrcv;
290 long ru_nsignals;
291 long ru_nvcsw;
292 long ru_nivcsw;
293};
294
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000295#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300296 || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) \
297 || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000298
299/* include/asm-{arm,i386,mips,ppc}/signal.h */
300struct kernel_old_sigaction {
301 union {
302 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000303 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000304 };
305 unsigned long sa_mask;
306 unsigned long sa_flags;
307 void (*sa_restorer)(void);
308} __attribute__((packed,aligned(4)));
309#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
310 #define kernel_old_sigaction kernel_sigaction
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800311#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
312 // No kernel_old_sigaction defined for arm64 riscv and loongarch64.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000313#endif
314
315/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
316 * exactly match the size of the signal set, even though the API was
317 * intended to be extensible. We define our own KERNEL_NSIG to deal with
318 * this.
319 * Please note that glibc provides signals [1.._NSIG-1], whereas the
320 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
321 * actual number of signals is obviously the same, but the constants
322 * differ by one.
323 */
324#ifdef __mips__
325#define KERNEL_NSIG 128
326#else
327#define KERNEL_NSIG 64
328#endif
329
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000330/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000331struct kernel_sigset_t {
332 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
333 (8*sizeof(unsigned long))];
334};
335
336/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
337struct kernel_sigaction {
338#ifdef __mips__
339 unsigned long sa_flags;
340 union {
341 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000342 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000343 };
344 struct kernel_sigset_t sa_mask;
345#else
346 union {
347 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000348 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000349 };
350 unsigned long sa_flags;
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800351#if !defined(__riscv) && !defined(__loongarch_lp64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000352 void (*sa_restorer)(void);
Andreas Schwab1d387f42022-02-15 16:21:13 +0100353#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000354 struct kernel_sigset_t sa_mask;
355#endif
356};
357
358/* include/linux/socket.h */
359struct kernel_sockaddr {
360 unsigned short sa_family;
361 char sa_data[14];
362};
363
Bryan Chan3f6478a2016-06-14 08:38:17 -0400364/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000365#ifdef __mips__
366#if _MIPS_SIM == _MIPS_SIM_ABI64
Peter Kasting99121a32022-08-22 16:43:44 +0000367typedef unsigned long long kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000368typedef unsigned kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000369typedef unsigned kernel_dev_t;
370typedef unsigned kernel_gid_t;
371typedef unsigned long long kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000372typedef unsigned kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000373typedef unsigned kernel_nlink_t;
374typedef long long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000375typedef unsigned kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000376typedef unsigned kernel_uid_t;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000377struct kernel_stat {
378#else
379struct kernel_stat64 {
380#endif
381 unsigned st_dev;
382 unsigned __pad0[3];
383 unsigned long long st_ino;
384 unsigned st_mode;
385 unsigned st_nlink;
386 unsigned st_uid;
387 unsigned st_gid;
388 unsigned st_rdev;
389 unsigned __pad1[3];
390 long long st_size;
391 unsigned st_atime_;
392 unsigned st_atime_nsec_;
393 unsigned st_mtime_;
394 unsigned st_mtime_nsec_;
395 unsigned st_ctime_;
396 unsigned st_ctime_nsec_;
397 unsigned st_blksize;
398 unsigned __pad2;
399 unsigned long long st_blocks;
400};
401#elif defined __PPC__
402struct kernel_stat64 {
403 unsigned long long st_dev;
404 unsigned long long st_ino;
405 unsigned st_mode;
406 unsigned st_nlink;
407 unsigned st_uid;
408 unsigned st_gid;
409 unsigned long long st_rdev;
410 unsigned short int __pad2;
411 long long st_size;
412 long st_blksize;
413 long long st_blocks;
414 long st_atime_;
415 unsigned long st_atime_nsec_;
416 long st_mtime_;
417 unsigned long st_mtime_nsec_;
418 long st_ctime_;
419 unsigned long st_ctime_nsec_;
420 unsigned long __unused4;
421 unsigned long __unused5;
422};
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300423#elif defined(__e2k__)
424struct kernel_stat64 {
425 unsigned long long st_dev;
426 unsigned long long st_ino;
427 unsigned int st_mode;
428 unsigned int st_nlink;
429 unsigned int st_uid;
430 unsigned int st_gid;
431 unsigned long long st_rdev;
432 long long st_size;
433 int st_blksize;
434 int __pad2;
435 unsigned long long st_blocks;
436 int st_atime_;
437 unsigned int st_atime_nsec_;
438 int st_mtime_;
439 unsigned int st_mtime_nsec_;
440 int st_ctime_;
441 unsigned int st_ctime_nsec_;
442 unsigned int __unused4;
443 unsigned int __unused5;
444};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000445#else
446struct kernel_stat64 {
447 unsigned long long st_dev;
448 unsigned char __pad0[4];
449 unsigned __st_ino;
450 unsigned st_mode;
451 unsigned st_nlink;
452 unsigned st_uid;
453 unsigned st_gid;
454 unsigned long long st_rdev;
455 unsigned char __pad3[4];
456 long long st_size;
457 unsigned st_blksize;
458 unsigned long long st_blocks;
459 unsigned st_atime_;
460 unsigned st_atime_nsec_;
461 unsigned st_mtime_;
462 unsigned st_mtime_nsec_;
463 unsigned st_ctime_;
464 unsigned st_ctime_nsec_;
465 unsigned long long st_ino;
466};
467#endif
468
Bryan Chan3f6478a2016-06-14 08:38:17 -0400469/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000470#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
Peter Kasting99121a32022-08-22 16:43:44 +0000471typedef unsigned kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000472typedef unsigned kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000473typedef unsigned short kernel_dev_t;
474typedef unsigned short kernel_gid_t;
475typedef unsigned kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000476typedef unsigned short kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000477typedef unsigned short kernel_nlink_t;
478typedef unsigned kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000479typedef unsigned kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000480typedef unsigned short kernel_uid_t;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000481struct kernel_stat {
482 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
483 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
484 * format. In reality, we do not see useful data in the top bits. So,
485 * we'll leave the padding in here, until we find a better solution.
486 */
Peter Kasting092a9212022-08-22 20:02:11 +0000487 kernel_dev_t st_dev;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000488 short pad1;
Peter Kasting092a9212022-08-22 20:02:11 +0000489 kernel_ino_t st_ino;
Peter Kastingce877202022-08-23 15:40:54 +0000490 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000491 kernel_nlink_t st_nlink;
492 kernel_uid_t st_uid;
493 kernel_gid_t st_gid;
494 kernel_dev_t st_rdev;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000495 short pad2;
Peter Kasting99121a32022-08-22 16:43:44 +0000496 kernel_off_t st_size;
Peter Kastingce877202022-08-23 15:40:54 +0000497 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000498 kernel_blkcnt_t st_blocks;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000499 kernel_time_t st_atime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000500 unsigned st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000501 kernel_time_t st_mtime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000502 unsigned st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000503 kernel_time_t st_ctime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000504 unsigned st_ctime_nsec_;
505 unsigned __unused4;
506 unsigned __unused5;
507};
508#elif defined(__x86_64__)
Peter Kasting99121a32022-08-22 16:43:44 +0000509typedef int64_t kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000510typedef int64_t kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000511typedef uint64_t kernel_dev_t;
512typedef unsigned kernel_gid_t;
513typedef uint64_t kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000514typedef unsigned kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000515typedef uint64_t kernel_nlink_t;
516typedef int64_t kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000517typedef uint64_t kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000518typedef unsigned kernel_uid_t;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000519struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000520 kernel_dev_t st_dev;
521 kernel_ino_t st_ino;
522 kernel_nlink_t st_nlink;
Peter Kastingce877202022-08-23 15:40:54 +0000523 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000524 kernel_uid_t st_uid;
525 kernel_gid_t st_gid;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000526 unsigned __pad0;
Peter Kasting092a9212022-08-22 20:02:11 +0000527 kernel_dev_t st_rdev;
Peter Kasting99121a32022-08-22 16:43:44 +0000528 kernel_off_t st_size;
Peter Kastingce877202022-08-23 15:40:54 +0000529 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000530 kernel_blkcnt_t st_blocks;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000531 kernel_time_t st_atime_;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000532 uint64_t st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000533 kernel_time_t st_mtime_;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000534 uint64_t st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000535 kernel_time_t st_ctime_;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000536 uint64_t st_ctime_nsec_;
anton@chromium.org43de0522014-04-04 11:20:46 +0000537 int64_t __unused4[3];
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000538};
539#elif defined(__PPC__)
Peter Kasting99121a32022-08-22 16:43:44 +0000540typedef unsigned long kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000541typedef unsigned long kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000542typedef unsigned kernel_dev_t;
543typedef unsigned kernel_gid_t;
544typedef unsigned long kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000545typedef unsigned long kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000546typedef unsigned short kernel_nlink_t;
547typedef long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000548typedef unsigned long kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000549typedef unsigned kernel_uid_t;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000550struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000551 kernel_dev_t st_dev;
552 kernel_ino_t st_ino;
Peter Kastingce877202022-08-23 15:40:54 +0000553 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000554 kernel_nlink_t st_nlink;
555 kernel_gid_t st_uid;
556 kernel_uid_t st_gid;
557 kernel_dev_t st_rdev;
558 kernel_off_t st_size;
Peter Kastingce877202022-08-23 15:40:54 +0000559 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000560 kernel_blkcnt_t st_blocks;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000561 kernel_time_t st_atime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000562 unsigned long st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000563 kernel_time_t st_mtime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000564 unsigned long st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000565 kernel_time_t st_ctime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000566 unsigned long st_ctime_nsec_;
567 unsigned long __unused4;
568 unsigned long __unused5;
569};
570#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
Peter Kasting99121a32022-08-22 16:43:44 +0000571typedef int kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000572typedef int kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000573typedef unsigned kernel_dev_t;
574typedef unsigned kernel_gid_t;
575typedef unsigned kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000576typedef unsigned kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000577typedef unsigned kernel_nlink_t;
578typedef long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000579typedef long kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000580typedef unsigned kernel_uid_t;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000581struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000582 kernel_dev_t st_dev;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000583 int st_pad1[3];
Peter Kasting092a9212022-08-22 20:02:11 +0000584 kernel_ino_t st_ino;
Peter Kastingce877202022-08-23 15:40:54 +0000585 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000586 kernel_nlink_t st_nlink;
587 kernel_uid_t st_uid;
588 kernel_gid_t st_gid;
589 kernel_dev_t st_rdev;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000590 int st_pad2[2];
Peter Kasting99121a32022-08-22 16:43:44 +0000591 kernel_off_t st_size;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000592 int st_pad3;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000593 kernel_time_t st_atime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000594 long st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000595 kernel_time_t st_mtime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000596 long st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000597 kernel_time_t st_ctime_;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000598 long st_ctime_nsec_;
Peter Kastingce877202022-08-23 15:40:54 +0000599 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000600 kernel_blkcnt_t st_blocks;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000601 int st_pad4[14];
602};
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800603#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
Peter Kasting99121a32022-08-22 16:43:44 +0000604typedef long kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000605typedef int kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000606typedef unsigned long kernel_dev_t;
607typedef unsigned int kernel_gid_t;
608typedef unsigned long kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000609typedef unsigned int kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000610typedef unsigned int kernel_nlink_t;
611typedef long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000612typedef long kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000613typedef unsigned int kernel_uid_t;
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000614struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000615 kernel_dev_t st_dev;
616 kernel_ino_t st_ino;
Peter Kastingce877202022-08-23 15:40:54 +0000617 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000618 kernel_nlink_t st_nlink;
619 kernel_uid_t st_uid;
620 kernel_gid_t st_gid;
621 kernel_dev_t st_rdev;
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000622 unsigned long __pad1;
Peter Kasting99121a32022-08-22 16:43:44 +0000623 kernel_off_t st_size;
Peter Kastingce877202022-08-23 15:40:54 +0000624 kernel_blksize_t st_blksize;
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000625 int __pad2;
Peter Kasting99121a32022-08-22 16:43:44 +0000626 kernel_blkcnt_t st_blocks;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000627 kernel_time_t st_atime_;
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000628 unsigned long st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000629 kernel_time_t st_mtime_;
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000630 unsigned long st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000631 kernel_time_t st_ctime_;
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000632 unsigned long st_ctime_nsec_;
633 unsigned int __unused4;
634 unsigned int __unused5;
635};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400636#elif defined(__s390x__)
Peter Kasting99121a32022-08-22 16:43:44 +0000637typedef long kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000638typedef unsigned long kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000639typedef unsigned long kernel_dev_t;
640typedef unsigned int kernel_gid_t;
641typedef unsigned long kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000642typedef unsigned int kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000643typedef unsigned long kernel_nlink_t;
644typedef unsigned long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000645typedef unsigned long kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000646typedef unsigned int kernel_uid_t;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400647struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000648 kernel_dev_t st_dev;
649 kernel_ino_t st_ino;
650 kernel_nlink_t st_nlink;
Peter Kastingce877202022-08-23 15:40:54 +0000651 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000652 kernel_uid_t st_uid;
653 kernel_gid_t st_gid;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400654 unsigned int __pad1;
Peter Kasting092a9212022-08-22 20:02:11 +0000655 kernel_dev_t st_rdev;
Peter Kasting99121a32022-08-22 16:43:44 +0000656 kernel_off_t st_size;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000657 kernel_time_t st_atime_;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400658 unsigned long st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000659 kernel_time_t st_mtime_;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400660 unsigned long st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000661 kernel_time_t st_ctime_;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400662 unsigned long st_ctime_nsec_;
Peter Kastingce877202022-08-23 15:40:54 +0000663 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000664 kernel_blkcnt_t st_blocks;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400665 unsigned long __unused[3];
666};
667#elif defined(__s390__)
Peter Kasting99121a32022-08-22 16:43:44 +0000668typedef unsigned long kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000669typedef unsigned long kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000670typedef unsigned short kernel_dev_t;
671typedef unsigned short kernel_gid_t;
672typedef unsigned long kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000673typedef unsigned short kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000674typedef unsigned short kernel_nlink_t;
675typedef unsigned long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000676typedef unsigned long kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000677typedef unsigned short kernel_uid_t;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400678struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000679 kernel_dev_t st_dev;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400680 unsigned short __pad1;
Peter Kasting092a9212022-08-22 20:02:11 +0000681 kernel_ino_t st_ino;
Peter Kastingce877202022-08-23 15:40:54 +0000682 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000683 kernel_nlink_t st_nlink;
684 kernel_uid_t st_uid;
685 kernel_gid_t st_gid;
686 kernel_dev_t st_rdev;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400687 unsigned short __pad2;
Peter Kasting99121a32022-08-22 16:43:44 +0000688 kernel_off_t st_size;
Peter Kastingce877202022-08-23 15:40:54 +0000689 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000690 kernel_blkcnt_t st_blocks;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000691 kernel_time_t st_atime_;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400692 unsigned long st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000693 kernel_time_t st_mtime_;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400694 unsigned long st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000695 kernel_time_t st_ctime_;
Bryan Chan3f6478a2016-06-14 08:38:17 -0400696 unsigned long st_ctime_nsec_;
697 unsigned long __unused4;
698 unsigned long __unused5;
699};
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300700#elif defined(__e2k__)
Peter Kasting99121a32022-08-22 16:43:44 +0000701typedef unsigned long kernel_blkcnt_t;
Peter Kastingce877202022-08-23 15:40:54 +0000702typedef unsigned long kernel_blksize_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000703typedef unsigned long kernel_dev_t;
704typedef unsigned int kernel_gid_t;
705typedef unsigned long kernel_ino_t;
Peter Kastingce877202022-08-23 15:40:54 +0000706typedef unsigned int kernel_mode_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000707typedef unsigned long kernel_nlink_t;
708typedef unsigned long kernel_off_t;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000709typedef unsigned long kernel_time_t;
Peter Kasting092a9212022-08-22 20:02:11 +0000710typedef unsigned int kernel_uid_t;
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300711struct kernel_stat {
Peter Kasting092a9212022-08-22 20:02:11 +0000712 kernel_dev_t st_dev;
713 kernel_ino_t st_ino;
Peter Kastingce877202022-08-23 15:40:54 +0000714 kernel_mode_t st_mode;
Peter Kasting092a9212022-08-22 20:02:11 +0000715 kernel_nlink_t st_nlink;
716 kernel_uid_t st_uid;
717 kernel_gid_t st_gid;
718 kernel_dev_t st_rdev;
Peter Kasting99121a32022-08-22 16:43:44 +0000719 kernel_off_t st_size;
Peter Kastingce877202022-08-23 15:40:54 +0000720 kernel_blksize_t st_blksize;
Peter Kasting99121a32022-08-22 16:43:44 +0000721 kernel_blkcnt_t st_blocks;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000722 kernel_time_t st_atime_;
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300723 unsigned long st_atime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000724 kernel_time_t st_mtime_;
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300725 unsigned long st_mtime_nsec_;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +0000726 kernel_time_t st_ctime_;
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300727 unsigned long st_ctime_nsec_;
728};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000729#endif
730
Bryan Chan3f6478a2016-06-14 08:38:17 -0400731/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000732#ifdef __mips__
733#if _MIPS_SIM != _MIPS_SIM_ABI64
734struct kernel_statfs64 {
735 unsigned long f_type;
736 unsigned long f_bsize;
737 unsigned long f_frsize;
738 unsigned long __pad;
739 unsigned long long f_blocks;
740 unsigned long long f_bfree;
741 unsigned long long f_files;
742 unsigned long long f_ffree;
743 unsigned long long f_bavail;
744 struct { int val[2]; } f_fsid;
745 unsigned long f_namelen;
746 unsigned long f_spare[6];
747};
748#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -0400749#elif defined(__s390__)
750/* See also arch/s390/include/asm/compat.h */
751struct kernel_statfs64 {
752 unsigned int f_type;
753 unsigned int f_bsize;
754 unsigned long long f_blocks;
755 unsigned long long f_bfree;
756 unsigned long long f_bavail;
757 unsigned long long f_files;
758 unsigned long long f_ffree;
759 struct { int val[2]; } f_fsid;
760 unsigned int f_namelen;
761 unsigned int f_frsize;
762 unsigned int f_flags;
763 unsigned int f_spare[4];
764};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000765#elif !defined(__x86_64__)
766struct kernel_statfs64 {
767 unsigned long f_type;
768 unsigned long f_bsize;
769 unsigned long long f_blocks;
770 unsigned long long f_bfree;
771 unsigned long long f_bavail;
772 unsigned long long f_files;
773 unsigned long long f_ffree;
774 struct { int val[2]; } f_fsid;
775 unsigned long f_namelen;
776 unsigned long f_frsize;
777 unsigned long f_spare[5];
778};
779#endif
780
Bryan Chan3f6478a2016-06-14 08:38:17 -0400781/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000782#ifdef __mips__
783struct kernel_statfs {
784 long f_type;
785 long f_bsize;
786 long f_frsize;
787 long f_blocks;
788 long f_bfree;
789 long f_files;
790 long f_ffree;
791 long f_bavail;
792 struct { int val[2]; } f_fsid;
793 long f_namelen;
794 long f_spare[6];
795};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000796#elif defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000797struct kernel_statfs {
798 /* x86_64 actually defines all these fields as signed, whereas all other */
799 /* platforms define them as unsigned. Leaving them at unsigned should not */
vapier@chromium.org2273e812013-04-01 17:52:44 +0000800 /* cause any problems. Make sure these are 64-bit even on x32. */
801 uint64_t f_type;
802 uint64_t f_bsize;
803 uint64_t f_blocks;
804 uint64_t f_bfree;
805 uint64_t f_bavail;
806 uint64_t f_files;
807 uint64_t f_ffree;
808 struct { int val[2]; } f_fsid;
809 uint64_t f_namelen;
810 uint64_t f_frsize;
811 uint64_t f_spare[5];
812};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400813#elif defined(__s390__)
814struct kernel_statfs {
815 unsigned int f_type;
816 unsigned int f_bsize;
817 unsigned long f_blocks;
818 unsigned long f_bfree;
819 unsigned long f_bavail;
820 unsigned long f_files;
821 unsigned long f_ffree;
822 struct { int val[2]; } f_fsid;
823 unsigned int f_namelen;
824 unsigned int f_frsize;
825 unsigned int f_flags;
826 unsigned int f_spare[4];
827};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000828#else
829struct kernel_statfs {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000830 unsigned long f_type;
831 unsigned long f_bsize;
832 unsigned long f_blocks;
833 unsigned long f_bfree;
834 unsigned long f_bavail;
835 unsigned long f_files;
836 unsigned long f_ffree;
837 struct { int val[2]; } f_fsid;
838 unsigned long f_namelen;
839 unsigned long f_frsize;
840 unsigned long f_spare[5];
841};
842#endif
843
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800844struct kernel_statx_timestamp {
845 int64_t tv_sec;
846 uint32_t tv_nsec;
847 int32_t __reserved;
848};
849
850struct kernel_statx {
851 uint32_t stx_mask;
852 uint32_t stx_blksize;
853 uint64_t stx_attributes;
854 uint32_t stx_nlink;
855 uint32_t stx_uid;
856 uint32_t stx_gid;
857 uint16_t stx_mode;
858 uint16_t __spare0[1];
859 uint64_t stx_ino;
860 uint64_t stx_size;
861 uint64_t stx_blocks;
862 uint64_t stx_attributes_mask;
863 struct kernel_statx_timestamp stx_atime;
864 struct kernel_statx_timestamp stx_btime;
865 struct kernel_statx_timestamp stx_ctime;
866 struct kernel_statx_timestamp stx_mtime;
867 uint32_t stx_rdev_major;
868 uint32_t stx_rdev_minor;
869 uint32_t stx_dev_major;
870 uint32_t stx_dev_minor;
871 uint64_t stx_mnt_id;
872 uint64_t __spare2;
873 uint64_t __spare3[12];
874};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000875
876/* Definitions missing from the standard header files */
877#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000878#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000879#define O_DIRECTORY 0040000
880#else
881#define O_DIRECTORY 0200000
882#endif
883#endif
884#ifndef NT_PRXFPREG
885#define NT_PRXFPREG 0x46e62b7f
886#endif
887#ifndef PTRACE_GETFPXREGS
888#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
889#endif
890#ifndef PR_GET_DUMPABLE
891#define PR_GET_DUMPABLE 3
892#endif
893#ifndef PR_SET_DUMPABLE
894#define PR_SET_DUMPABLE 4
895#endif
896#ifndef PR_GET_SECCOMP
897#define PR_GET_SECCOMP 21
898#endif
899#ifndef PR_SET_SECCOMP
900#define PR_SET_SECCOMP 22
901#endif
902#ifndef AT_FDCWD
903#define AT_FDCWD (-100)
904#endif
905#ifndef AT_SYMLINK_NOFOLLOW
906#define AT_SYMLINK_NOFOLLOW 0x100
907#endif
908#ifndef AT_REMOVEDIR
909#define AT_REMOVEDIR 0x200
910#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800911#ifndef AT_NO_AUTOMOUNT
912#define AT_NO_AUTOMOUNT 0x800
913#endif
914#ifndef AT_EMPTY_PATH
915#define AT_EMPTY_PATH 0x1000
916#endif
917#ifndef STATX_BASIC_STATS
918#define STATX_BASIC_STATS 0x000007ffU
919#endif
920#ifndef AT_STATX_SYNC_AS_STAT
921#define AT_STATX_SYNC_AS_STAT 0x0000
922#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000923#ifndef MREMAP_FIXED
924#define MREMAP_FIXED 2
925#endif
926#ifndef SA_RESTORER
927#define SA_RESTORER 0x04000000
928#endif
929#ifndef CPUCLOCK_PROF
930#define CPUCLOCK_PROF 0
931#endif
932#ifndef CPUCLOCK_VIRT
933#define CPUCLOCK_VIRT 1
934#endif
935#ifndef CPUCLOCK_SCHED
936#define CPUCLOCK_SCHED 2
937#endif
938#ifndef CPUCLOCK_PERTHREAD_MASK
939#define CPUCLOCK_PERTHREAD_MASK 4
940#endif
941#ifndef MAKE_PROCESS_CPUCLOCK
942#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400943 ((int)(~(unsigned)(pid) << 3) | (int)(clock))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000944#endif
945#ifndef MAKE_THREAD_CPUCLOCK
946#define MAKE_THREAD_CPUCLOCK(tid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400947 ((int)(~(unsigned)(tid) << 3) | \
948 (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000949#endif
950
951#ifndef FUTEX_WAIT
952#define FUTEX_WAIT 0
953#endif
954#ifndef FUTEX_WAKE
955#define FUTEX_WAKE 1
956#endif
957#ifndef FUTEX_FD
958#define FUTEX_FD 2
959#endif
960#ifndef FUTEX_REQUEUE
961#define FUTEX_REQUEUE 3
962#endif
963#ifndef FUTEX_CMP_REQUEUE
964#define FUTEX_CMP_REQUEUE 4
965#endif
966#ifndef FUTEX_WAKE_OP
967#define FUTEX_WAKE_OP 5
968#endif
969#ifndef FUTEX_LOCK_PI
970#define FUTEX_LOCK_PI 6
971#endif
972#ifndef FUTEX_UNLOCK_PI
973#define FUTEX_UNLOCK_PI 7
974#endif
975#ifndef FUTEX_TRYLOCK_PI
976#define FUTEX_TRYLOCK_PI 8
977#endif
978#ifndef FUTEX_PRIVATE_FLAG
979#define FUTEX_PRIVATE_FLAG 128
980#endif
981#ifndef FUTEX_CMD_MASK
982#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
983#endif
984#ifndef FUTEX_WAIT_PRIVATE
985#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
986#endif
987#ifndef FUTEX_WAKE_PRIVATE
988#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
989#endif
990#ifndef FUTEX_REQUEUE_PRIVATE
991#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
992#endif
993#ifndef FUTEX_CMP_REQUEUE_PRIVATE
994#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
995#endif
996#ifndef FUTEX_WAKE_OP_PRIVATE
997#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
998#endif
999#ifndef FUTEX_LOCK_PI_PRIVATE
1000#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
1001#endif
1002#ifndef FUTEX_UNLOCK_PI_PRIVATE
1003#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
1004#endif
1005#ifndef FUTEX_TRYLOCK_PI_PRIVATE
1006#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
1007#endif
1008
1009
1010#if defined(__x86_64__)
1011#ifndef ARCH_SET_GS
1012#define ARCH_SET_GS 0x1001
1013#endif
1014#ifndef ARCH_GET_GS
1015#define ARCH_GET_GS 0x1004
1016#endif
1017#endif
1018
1019#if defined(__i386__)
1020#ifndef __NR_quotactl
1021#define __NR_quotactl 131
1022#endif
1023#ifndef __NR_setresuid
1024#define __NR_setresuid 164
1025#define __NR_getresuid 165
1026#define __NR_setresgid 170
1027#define __NR_getresgid 171
1028#endif
1029#ifndef __NR_rt_sigaction
1030#define __NR_rt_sigreturn 173
1031#define __NR_rt_sigaction 174
1032#define __NR_rt_sigprocmask 175
1033#define __NR_rt_sigpending 176
1034#define __NR_rt_sigsuspend 179
1035#endif
1036#ifndef __NR_pread64
1037#define __NR_pread64 180
1038#endif
1039#ifndef __NR_pwrite64
1040#define __NR_pwrite64 181
1041#endif
1042#ifndef __NR_ugetrlimit
1043#define __NR_ugetrlimit 191
1044#endif
1045#ifndef __NR_stat64
1046#define __NR_stat64 195
1047#endif
1048#ifndef __NR_fstat64
1049#define __NR_fstat64 197
1050#endif
1051#ifndef __NR_setresuid32
1052#define __NR_setresuid32 208
1053#define __NR_getresuid32 209
1054#define __NR_setresgid32 210
1055#define __NR_getresgid32 211
1056#endif
1057#ifndef __NR_setfsuid32
1058#define __NR_setfsuid32 215
1059#define __NR_setfsgid32 216
1060#endif
1061#ifndef __NR_getdents64
1062#define __NR_getdents64 220
1063#endif
1064#ifndef __NR_gettid
1065#define __NR_gettid 224
1066#endif
1067#ifndef __NR_readahead
1068#define __NR_readahead 225
1069#endif
1070#ifndef __NR_setxattr
1071#define __NR_setxattr 226
1072#endif
1073#ifndef __NR_lsetxattr
1074#define __NR_lsetxattr 227
1075#endif
1076#ifndef __NR_getxattr
1077#define __NR_getxattr 229
1078#endif
1079#ifndef __NR_lgetxattr
1080#define __NR_lgetxattr 230
1081#endif
1082#ifndef __NR_listxattr
1083#define __NR_listxattr 232
1084#endif
1085#ifndef __NR_llistxattr
1086#define __NR_llistxattr 233
1087#endif
1088#ifndef __NR_tkill
1089#define __NR_tkill 238
1090#endif
1091#ifndef __NR_futex
1092#define __NR_futex 240
1093#endif
1094#ifndef __NR_sched_setaffinity
1095#define __NR_sched_setaffinity 241
1096#define __NR_sched_getaffinity 242
1097#endif
1098#ifndef __NR_set_tid_address
1099#define __NR_set_tid_address 258
1100#endif
1101#ifndef __NR_clock_gettime
1102#define __NR_clock_gettime 265
1103#endif
1104#ifndef __NR_clock_getres
1105#define __NR_clock_getres 266
1106#endif
1107#ifndef __NR_statfs64
1108#define __NR_statfs64 268
1109#endif
1110#ifndef __NR_fstatfs64
1111#define __NR_fstatfs64 269
1112#endif
1113#ifndef __NR_fadvise64_64
1114#define __NR_fadvise64_64 272
1115#endif
1116#ifndef __NR_ioprio_set
1117#define __NR_ioprio_set 289
1118#endif
1119#ifndef __NR_ioprio_get
1120#define __NR_ioprio_get 290
1121#endif
1122#ifndef __NR_openat
1123#define __NR_openat 295
1124#endif
1125#ifndef __NR_fstatat64
1126#define __NR_fstatat64 300
1127#endif
1128#ifndef __NR_unlinkat
1129#define __NR_unlinkat 301
1130#endif
1131#ifndef __NR_move_pages
1132#define __NR_move_pages 317
1133#endif
1134#ifndef __NR_getcpu
1135#define __NR_getcpu 318
1136#endif
1137#ifndef __NR_fallocate
1138#define __NR_fallocate 324
1139#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001140#ifndef __NR_getrandom
1141#define __NR_getrandom 355
1142#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001143/* End of i386 definitions */
1144#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
1145#ifndef __NR_setresuid
1146#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
1147#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
1148#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
1149#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
1150#endif
1151#ifndef __NR_rt_sigaction
1152#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
1153#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
1154#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
1155#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
1156#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
1157#endif
1158#ifndef __NR_pread64
1159#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
1160#endif
1161#ifndef __NR_pwrite64
1162#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
1163#endif
1164#ifndef __NR_ugetrlimit
1165#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
1166#endif
1167#ifndef __NR_stat64
1168#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
1169#endif
1170#ifndef __NR_fstat64
1171#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
1172#endif
1173#ifndef __NR_setresuid32
1174#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
1175#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
1176#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
1177#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
1178#endif
1179#ifndef __NR_setfsuid32
1180#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
1181#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
1182#endif
1183#ifndef __NR_getdents64
1184#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
1185#endif
1186#ifndef __NR_gettid
1187#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1188#endif
1189#ifndef __NR_readahead
1190#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1191#endif
1192#ifndef __NR_setxattr
1193#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1194#endif
1195#ifndef __NR_lsetxattr
1196#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1197#endif
1198#ifndef __NR_getxattr
1199#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1200#endif
1201#ifndef __NR_lgetxattr
1202#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1203#endif
1204#ifndef __NR_listxattr
1205#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1206#endif
1207#ifndef __NR_llistxattr
1208#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1209#endif
1210#ifndef __NR_tkill
1211#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1212#endif
1213#ifndef __NR_futex
1214#define __NR_futex (__NR_SYSCALL_BASE + 240)
1215#endif
1216#ifndef __NR_sched_setaffinity
1217#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1218#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1219#endif
1220#ifndef __NR_set_tid_address
1221#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1222#endif
1223#ifndef __NR_clock_gettime
1224#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1225#endif
1226#ifndef __NR_clock_getres
1227#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1228#endif
1229#ifndef __NR_statfs64
1230#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1231#endif
1232#ifndef __NR_fstatfs64
1233#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1234#endif
1235#ifndef __NR_ioprio_set
1236#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1237#endif
1238#ifndef __NR_ioprio_get
1239#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1240#endif
Matthew Denton92a65a82021-04-01 13:00:07 -07001241#ifndef __NR_fstatat64
1242#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
1243#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001244#ifndef __NR_move_pages
1245#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1246#endif
1247#ifndef __NR_getcpu
1248#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1249#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001250#ifndef __NR_getrandom
1251#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
1252#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001253/* End of ARM 3/EABI definitions */
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001254#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001255#ifndef __NR_setxattr
1256#define __NR_setxattr 5
1257#endif
1258#ifndef __NR_lsetxattr
1259#define __NR_lsetxattr 6
1260#endif
1261#ifndef __NR_getxattr
1262#define __NR_getxattr 8
1263#endif
1264#ifndef __NR_lgetxattr
1265#define __NR_lgetxattr 9
1266#endif
1267#ifndef __NR_listxattr
1268#define __NR_listxattr 11
1269#endif
1270#ifndef __NR_llistxattr
1271#define __NR_llistxattr 12
1272#endif
1273#ifndef __NR_ioprio_set
1274#define __NR_ioprio_set 30
1275#endif
1276#ifndef __NR_ioprio_get
1277#define __NR_ioprio_get 31
1278#endif
1279#ifndef __NR_unlinkat
1280#define __NR_unlinkat 35
1281#endif
1282#ifndef __NR_fallocate
1283#define __NR_fallocate 47
1284#endif
1285#ifndef __NR_openat
1286#define __NR_openat 56
1287#endif
1288#ifndef __NR_quotactl
1289#define __NR_quotactl 60
1290#endif
1291#ifndef __NR_getdents64
1292#define __NR_getdents64 61
1293#endif
1294#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001295// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001296#define __NR_getdents __NR_getdents64
1297#endif
1298#ifndef __NR_pread64
1299#define __NR_pread64 67
1300#endif
1301#ifndef __NR_pwrite64
1302#define __NR_pwrite64 68
1303#endif
1304#ifndef __NR_ppoll
1305#define __NR_ppoll 73
1306#endif
1307#ifndef __NR_readlinkat
1308#define __NR_readlinkat 78
1309#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001310#if !defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001311#ifndef __NR_newfstatat
1312#define __NR_newfstatat 79
1313#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001314#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001315#ifndef __NR_set_tid_address
1316#define __NR_set_tid_address 96
1317#endif
1318#ifndef __NR_futex
1319#define __NR_futex 98
1320#endif
1321#ifndef __NR_clock_gettime
1322#define __NR_clock_gettime 113
1323#endif
1324#ifndef __NR_clock_getres
1325#define __NR_clock_getres 114
1326#endif
1327#ifndef __NR_sched_setaffinity
1328#define __NR_sched_setaffinity 122
1329#define __NR_sched_getaffinity 123
1330#endif
1331#ifndef __NR_tkill
1332#define __NR_tkill 130
1333#endif
1334#ifndef __NR_setresuid
1335#define __NR_setresuid 147
1336#define __NR_getresuid 148
1337#define __NR_setresgid 149
1338#define __NR_getresgid 150
1339#endif
1340#ifndef __NR_gettid
1341#define __NR_gettid 178
1342#endif
1343#ifndef __NR_readahead
1344#define __NR_readahead 213
1345#endif
1346#ifndef __NR_fadvise64
1347#define __NR_fadvise64 223
1348#endif
1349#ifndef __NR_move_pages
1350#define __NR_move_pages 239
1351#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001352#ifndef __NR_getrandom
1353#define __NR_getrandom 278
1354#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001355#ifndef __NR_statx
1356#define __NR_statx 291
1357#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001358#elif defined(__x86_64__)
1359#ifndef __NR_pread64
1360#define __NR_pread64 17
1361#endif
1362#ifndef __NR_pwrite64
1363#define __NR_pwrite64 18
1364#endif
1365#ifndef __NR_setresuid
1366#define __NR_setresuid 117
1367#define __NR_getresuid 118
1368#define __NR_setresgid 119
1369#define __NR_getresgid 120
1370#endif
1371#ifndef __NR_quotactl
1372#define __NR_quotactl 179
1373#endif
1374#ifndef __NR_gettid
1375#define __NR_gettid 186
1376#endif
1377#ifndef __NR_readahead
1378#define __NR_readahead 187
1379#endif
1380#ifndef __NR_setxattr
1381#define __NR_setxattr 188
1382#endif
1383#ifndef __NR_lsetxattr
1384#define __NR_lsetxattr 189
1385#endif
1386#ifndef __NR_getxattr
1387#define __NR_getxattr 191
1388#endif
1389#ifndef __NR_lgetxattr
1390#define __NR_lgetxattr 192
1391#endif
1392#ifndef __NR_listxattr
1393#define __NR_listxattr 194
1394#endif
1395#ifndef __NR_llistxattr
1396#define __NR_llistxattr 195
1397#endif
1398#ifndef __NR_tkill
1399#define __NR_tkill 200
1400#endif
1401#ifndef __NR_futex
1402#define __NR_futex 202
1403#endif
1404#ifndef __NR_sched_setaffinity
1405#define __NR_sched_setaffinity 203
1406#define __NR_sched_getaffinity 204
1407#endif
1408#ifndef __NR_getdents64
1409#define __NR_getdents64 217
1410#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001411#ifndef __NR_getdents
1412// when getdents is not available, getdents64 is used for both.
1413#define __NR_getdents __NR_getdents64
1414#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001415#ifndef __NR_set_tid_address
1416#define __NR_set_tid_address 218
1417#endif
1418#ifndef __NR_fadvise64
1419#define __NR_fadvise64 221
1420#endif
1421#ifndef __NR_clock_gettime
1422#define __NR_clock_gettime 228
1423#endif
1424#ifndef __NR_clock_getres
1425#define __NR_clock_getres 229
1426#endif
1427#ifndef __NR_ioprio_set
1428#define __NR_ioprio_set 251
1429#endif
1430#ifndef __NR_ioprio_get
1431#define __NR_ioprio_get 252
1432#endif
1433#ifndef __NR_openat
1434#define __NR_openat 257
1435#endif
1436#ifndef __NR_newfstatat
1437#define __NR_newfstatat 262
1438#endif
1439#ifndef __NR_unlinkat
1440#define __NR_unlinkat 263
1441#endif
1442#ifndef __NR_move_pages
1443#define __NR_move_pages 279
1444#endif
1445#ifndef __NR_fallocate
1446#define __NR_fallocate 285
1447#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001448#ifndef __NR_getrandom
1449#define __NR_getrandom 318
1450#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001451/* End of x86-64 definitions */
1452#elif defined(__mips__)
1453#if _MIPS_SIM == _MIPS_SIM_ABI32
1454#ifndef __NR_setresuid
1455#define __NR_setresuid (__NR_Linux + 185)
1456#define __NR_getresuid (__NR_Linux + 186)
1457#define __NR_setresgid (__NR_Linux + 190)
1458#define __NR_getresgid (__NR_Linux + 191)
1459#endif
1460#ifndef __NR_rt_sigaction
1461#define __NR_rt_sigreturn (__NR_Linux + 193)
1462#define __NR_rt_sigaction (__NR_Linux + 194)
1463#define __NR_rt_sigprocmask (__NR_Linux + 195)
1464#define __NR_rt_sigpending (__NR_Linux + 196)
1465#define __NR_rt_sigsuspend (__NR_Linux + 199)
1466#endif
1467#ifndef __NR_pread64
1468#define __NR_pread64 (__NR_Linux + 200)
1469#endif
1470#ifndef __NR_pwrite64
1471#define __NR_pwrite64 (__NR_Linux + 201)
1472#endif
1473#ifndef __NR_stat64
1474#define __NR_stat64 (__NR_Linux + 213)
1475#endif
1476#ifndef __NR_fstat64
1477#define __NR_fstat64 (__NR_Linux + 215)
1478#endif
1479#ifndef __NR_getdents64
1480#define __NR_getdents64 (__NR_Linux + 219)
1481#endif
1482#ifndef __NR_gettid
1483#define __NR_gettid (__NR_Linux + 222)
1484#endif
1485#ifndef __NR_readahead
1486#define __NR_readahead (__NR_Linux + 223)
1487#endif
1488#ifndef __NR_setxattr
1489#define __NR_setxattr (__NR_Linux + 224)
1490#endif
1491#ifndef __NR_lsetxattr
1492#define __NR_lsetxattr (__NR_Linux + 225)
1493#endif
1494#ifndef __NR_getxattr
1495#define __NR_getxattr (__NR_Linux + 227)
1496#endif
1497#ifndef __NR_lgetxattr
1498#define __NR_lgetxattr (__NR_Linux + 228)
1499#endif
1500#ifndef __NR_listxattr
1501#define __NR_listxattr (__NR_Linux + 230)
1502#endif
1503#ifndef __NR_llistxattr
1504#define __NR_llistxattr (__NR_Linux + 231)
1505#endif
1506#ifndef __NR_tkill
1507#define __NR_tkill (__NR_Linux + 236)
1508#endif
1509#ifndef __NR_futex
1510#define __NR_futex (__NR_Linux + 238)
1511#endif
1512#ifndef __NR_sched_setaffinity
1513#define __NR_sched_setaffinity (__NR_Linux + 239)
1514#define __NR_sched_getaffinity (__NR_Linux + 240)
1515#endif
1516#ifndef __NR_set_tid_address
1517#define __NR_set_tid_address (__NR_Linux + 252)
1518#endif
1519#ifndef __NR_statfs64
1520#define __NR_statfs64 (__NR_Linux + 255)
1521#endif
1522#ifndef __NR_fstatfs64
1523#define __NR_fstatfs64 (__NR_Linux + 256)
1524#endif
1525#ifndef __NR_clock_gettime
1526#define __NR_clock_gettime (__NR_Linux + 263)
1527#endif
1528#ifndef __NR_clock_getres
1529#define __NR_clock_getres (__NR_Linux + 264)
1530#endif
1531#ifndef __NR_openat
1532#define __NR_openat (__NR_Linux + 288)
1533#endif
1534#ifndef __NR_fstatat
1535#define __NR_fstatat (__NR_Linux + 293)
1536#endif
1537#ifndef __NR_unlinkat
1538#define __NR_unlinkat (__NR_Linux + 294)
1539#endif
1540#ifndef __NR_move_pages
1541#define __NR_move_pages (__NR_Linux + 308)
1542#endif
1543#ifndef __NR_getcpu
1544#define __NR_getcpu (__NR_Linux + 312)
1545#endif
1546#ifndef __NR_ioprio_set
1547#define __NR_ioprio_set (__NR_Linux + 314)
1548#endif
1549#ifndef __NR_ioprio_get
1550#define __NR_ioprio_get (__NR_Linux + 315)
1551#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001552#ifndef __NR_getrandom
1553#define __NR_getrandom (__NR_Linux + 353)
1554#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001555/* End of MIPS (old 32bit API) definitions */
1556#elif _MIPS_SIM == _MIPS_SIM_ABI64
1557#ifndef __NR_pread64
1558#define __NR_pread64 (__NR_Linux + 16)
1559#endif
1560#ifndef __NR_pwrite64
1561#define __NR_pwrite64 (__NR_Linux + 17)
1562#endif
1563#ifndef __NR_setresuid
1564#define __NR_setresuid (__NR_Linux + 115)
1565#define __NR_getresuid (__NR_Linux + 116)
1566#define __NR_setresgid (__NR_Linux + 117)
1567#define __NR_getresgid (__NR_Linux + 118)
1568#endif
1569#ifndef __NR_gettid
1570#define __NR_gettid (__NR_Linux + 178)
1571#endif
1572#ifndef __NR_readahead
1573#define __NR_readahead (__NR_Linux + 179)
1574#endif
1575#ifndef __NR_setxattr
1576#define __NR_setxattr (__NR_Linux + 180)
1577#endif
1578#ifndef __NR_lsetxattr
1579#define __NR_lsetxattr (__NR_Linux + 181)
1580#endif
1581#ifndef __NR_getxattr
1582#define __NR_getxattr (__NR_Linux + 183)
1583#endif
1584#ifndef __NR_lgetxattr
1585#define __NR_lgetxattr (__NR_Linux + 184)
1586#endif
1587#ifndef __NR_listxattr
1588#define __NR_listxattr (__NR_Linux + 186)
1589#endif
1590#ifndef __NR_llistxattr
1591#define __NR_llistxattr (__NR_Linux + 187)
1592#endif
1593#ifndef __NR_tkill
1594#define __NR_tkill (__NR_Linux + 192)
1595#endif
1596#ifndef __NR_futex
1597#define __NR_futex (__NR_Linux + 194)
1598#endif
1599#ifndef __NR_sched_setaffinity
1600#define __NR_sched_setaffinity (__NR_Linux + 195)
1601#define __NR_sched_getaffinity (__NR_Linux + 196)
1602#endif
1603#ifndef __NR_set_tid_address
1604#define __NR_set_tid_address (__NR_Linux + 212)
1605#endif
1606#ifndef __NR_clock_gettime
1607#define __NR_clock_gettime (__NR_Linux + 222)
1608#endif
1609#ifndef __NR_clock_getres
1610#define __NR_clock_getres (__NR_Linux + 223)
1611#endif
1612#ifndef __NR_openat
1613#define __NR_openat (__NR_Linux + 247)
1614#endif
1615#ifndef __NR_fstatat
1616#define __NR_fstatat (__NR_Linux + 252)
1617#endif
1618#ifndef __NR_unlinkat
1619#define __NR_unlinkat (__NR_Linux + 253)
1620#endif
1621#ifndef __NR_move_pages
1622#define __NR_move_pages (__NR_Linux + 267)
1623#endif
1624#ifndef __NR_getcpu
1625#define __NR_getcpu (__NR_Linux + 271)
1626#endif
1627#ifndef __NR_ioprio_set
1628#define __NR_ioprio_set (__NR_Linux + 273)
1629#endif
1630#ifndef __NR_ioprio_get
1631#define __NR_ioprio_get (__NR_Linux + 274)
1632#endif
Yu Yind9ad2962020-11-24 16:49:22 +08001633#ifndef __NR_getrandom
1634#define __NR_getrandom (__NR_Linux + 313)
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001635#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001636/* End of MIPS (64bit API) definitions */
1637#else
1638#ifndef __NR_setresuid
1639#define __NR_setresuid (__NR_Linux + 115)
1640#define __NR_getresuid (__NR_Linux + 116)
1641#define __NR_setresgid (__NR_Linux + 117)
1642#define __NR_getresgid (__NR_Linux + 118)
1643#endif
1644#ifndef __NR_gettid
1645#define __NR_gettid (__NR_Linux + 178)
1646#endif
1647#ifndef __NR_readahead
1648#define __NR_readahead (__NR_Linux + 179)
1649#endif
1650#ifndef __NR_setxattr
1651#define __NR_setxattr (__NR_Linux + 180)
1652#endif
1653#ifndef __NR_lsetxattr
1654#define __NR_lsetxattr (__NR_Linux + 181)
1655#endif
1656#ifndef __NR_getxattr
1657#define __NR_getxattr (__NR_Linux + 183)
1658#endif
1659#ifndef __NR_lgetxattr
1660#define __NR_lgetxattr (__NR_Linux + 184)
1661#endif
1662#ifndef __NR_listxattr
1663#define __NR_listxattr (__NR_Linux + 186)
1664#endif
1665#ifndef __NR_llistxattr
1666#define __NR_llistxattr (__NR_Linux + 187)
1667#endif
1668#ifndef __NR_tkill
1669#define __NR_tkill (__NR_Linux + 192)
1670#endif
1671#ifndef __NR_futex
1672#define __NR_futex (__NR_Linux + 194)
1673#endif
1674#ifndef __NR_sched_setaffinity
1675#define __NR_sched_setaffinity (__NR_Linux + 195)
1676#define __NR_sched_getaffinity (__NR_Linux + 196)
1677#endif
1678#ifndef __NR_set_tid_address
1679#define __NR_set_tid_address (__NR_Linux + 213)
1680#endif
1681#ifndef __NR_statfs64
1682#define __NR_statfs64 (__NR_Linux + 217)
1683#endif
1684#ifndef __NR_fstatfs64
1685#define __NR_fstatfs64 (__NR_Linux + 218)
1686#endif
1687#ifndef __NR_clock_gettime
1688#define __NR_clock_gettime (__NR_Linux + 226)
1689#endif
1690#ifndef __NR_clock_getres
1691#define __NR_clock_getres (__NR_Linux + 227)
1692#endif
1693#ifndef __NR_openat
1694#define __NR_openat (__NR_Linux + 251)
1695#endif
1696#ifndef __NR_fstatat
1697#define __NR_fstatat (__NR_Linux + 256)
1698#endif
1699#ifndef __NR_unlinkat
1700#define __NR_unlinkat (__NR_Linux + 257)
1701#endif
1702#ifndef __NR_move_pages
1703#define __NR_move_pages (__NR_Linux + 271)
1704#endif
1705#ifndef __NR_getcpu
1706#define __NR_getcpu (__NR_Linux + 275)
1707#endif
1708#ifndef __NR_ioprio_set
1709#define __NR_ioprio_set (__NR_Linux + 277)
1710#endif
1711#ifndef __NR_ioprio_get
1712#define __NR_ioprio_get (__NR_Linux + 278)
1713#endif
1714/* End of MIPS (new 32bit API) definitions */
1715#endif
1716/* End of MIPS definitions */
1717#elif defined(__PPC__)
1718#ifndef __NR_setfsuid
1719#define __NR_setfsuid 138
1720#define __NR_setfsgid 139
1721#endif
1722#ifndef __NR_setresuid
1723#define __NR_setresuid 164
1724#define __NR_getresuid 165
1725#define __NR_setresgid 169
1726#define __NR_getresgid 170
1727#endif
1728#ifndef __NR_rt_sigaction
1729#define __NR_rt_sigreturn 172
1730#define __NR_rt_sigaction 173
1731#define __NR_rt_sigprocmask 174
1732#define __NR_rt_sigpending 175
1733#define __NR_rt_sigsuspend 178
1734#endif
1735#ifndef __NR_pread64
1736#define __NR_pread64 179
1737#endif
1738#ifndef __NR_pwrite64
1739#define __NR_pwrite64 180
1740#endif
1741#ifndef __NR_ugetrlimit
1742#define __NR_ugetrlimit 190
1743#endif
1744#ifndef __NR_readahead
1745#define __NR_readahead 191
1746#endif
1747#ifndef __NR_stat64
1748#define __NR_stat64 195
1749#endif
1750#ifndef __NR_fstat64
1751#define __NR_fstat64 197
1752#endif
1753#ifndef __NR_getdents64
1754#define __NR_getdents64 202
1755#endif
1756#ifndef __NR_gettid
1757#define __NR_gettid 207
1758#endif
1759#ifndef __NR_tkill
1760#define __NR_tkill 208
1761#endif
1762#ifndef __NR_setxattr
1763#define __NR_setxattr 209
1764#endif
1765#ifndef __NR_lsetxattr
1766#define __NR_lsetxattr 210
1767#endif
1768#ifndef __NR_getxattr
1769#define __NR_getxattr 212
1770#endif
1771#ifndef __NR_lgetxattr
1772#define __NR_lgetxattr 213
1773#endif
1774#ifndef __NR_listxattr
1775#define __NR_listxattr 215
1776#endif
1777#ifndef __NR_llistxattr
1778#define __NR_llistxattr 216
1779#endif
1780#ifndef __NR_futex
1781#define __NR_futex 221
1782#endif
1783#ifndef __NR_sched_setaffinity
1784#define __NR_sched_setaffinity 222
1785#define __NR_sched_getaffinity 223
1786#endif
1787#ifndef __NR_set_tid_address
1788#define __NR_set_tid_address 232
1789#endif
1790#ifndef __NR_clock_gettime
1791#define __NR_clock_gettime 246
1792#endif
1793#ifndef __NR_clock_getres
1794#define __NR_clock_getres 247
1795#endif
1796#ifndef __NR_statfs64
1797#define __NR_statfs64 252
1798#endif
1799#ifndef __NR_fstatfs64
1800#define __NR_fstatfs64 253
1801#endif
1802#ifndef __NR_fadvise64_64
1803#define __NR_fadvise64_64 254
1804#endif
1805#ifndef __NR_ioprio_set
1806#define __NR_ioprio_set 273
1807#endif
1808#ifndef __NR_ioprio_get
1809#define __NR_ioprio_get 274
1810#endif
1811#ifndef __NR_openat
1812#define __NR_openat 286
1813#endif
1814#ifndef __NR_fstatat64
1815#define __NR_fstatat64 291
1816#endif
1817#ifndef __NR_unlinkat
1818#define __NR_unlinkat 292
1819#endif
1820#ifndef __NR_move_pages
1821#define __NR_move_pages 301
1822#endif
1823#ifndef __NR_getcpu
1824#define __NR_getcpu 302
1825#endif
Andreas Deiningerb0fa1562022-09-30 18:13:22 +02001826/* End of powerpc definitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001827#elif defined(__s390__)
1828#ifndef __NR_quotactl
1829#define __NR_quotactl 131
1830#endif
1831#ifndef __NR_rt_sigreturn
1832#define __NR_rt_sigreturn 173
1833#endif
1834#ifndef __NR_rt_sigaction
1835#define __NR_rt_sigaction 174
1836#endif
1837#ifndef __NR_rt_sigprocmask
1838#define __NR_rt_sigprocmask 175
1839#endif
1840#ifndef __NR_rt_sigpending
1841#define __NR_rt_sigpending 176
1842#endif
1843#ifndef __NR_rt_sigsuspend
1844#define __NR_rt_sigsuspend 179
1845#endif
1846#ifndef __NR_pread64
1847#define __NR_pread64 180
1848#endif
1849#ifndef __NR_pwrite64
1850#define __NR_pwrite64 181
1851#endif
1852#ifndef __NR_getdents64
1853#define __NR_getdents64 220
1854#endif
1855#ifndef __NR_readahead
1856#define __NR_readahead 222
1857#endif
1858#ifndef __NR_setxattr
1859#define __NR_setxattr 224
1860#endif
1861#ifndef __NR_lsetxattr
1862#define __NR_lsetxattr 225
1863#endif
1864#ifndef __NR_getxattr
1865#define __NR_getxattr 227
1866#endif
1867#ifndef __NR_lgetxattr
1868#define __NR_lgetxattr 228
1869#endif
1870#ifndef __NR_listxattr
1871#define __NR_listxattr 230
1872#endif
1873#ifndef __NR_llistxattr
1874#define __NR_llistxattr 231
1875#endif
1876#ifndef __NR_gettid
1877#define __NR_gettid 236
1878#endif
1879#ifndef __NR_tkill
1880#define __NR_tkill 237
1881#endif
1882#ifndef __NR_futex
1883#define __NR_futex 238
1884#endif
1885#ifndef __NR_sched_setaffinity
1886#define __NR_sched_setaffinity 239
1887#endif
1888#ifndef __NR_sched_getaffinity
1889#define __NR_sched_getaffinity 240
1890#endif
1891#ifndef __NR_set_tid_address
1892#define __NR_set_tid_address 252
1893#endif
1894#ifndef __NR_clock_gettime
1895#define __NR_clock_gettime 260
1896#endif
1897#ifndef __NR_clock_getres
1898#define __NR_clock_getres 261
1899#endif
1900#ifndef __NR_statfs64
1901#define __NR_statfs64 265
1902#endif
1903#ifndef __NR_fstatfs64
1904#define __NR_fstatfs64 266
1905#endif
1906#ifndef __NR_ioprio_set
1907#define __NR_ioprio_set 282
1908#endif
1909#ifndef __NR_ioprio_get
1910#define __NR_ioprio_get 283
1911#endif
1912#ifndef __NR_openat
1913#define __NR_openat 288
1914#endif
1915#ifndef __NR_unlinkat
1916#define __NR_unlinkat 294
1917#endif
1918#ifndef __NR_move_pages
1919#define __NR_move_pages 310
1920#endif
1921#ifndef __NR_getcpu
1922#define __NR_getcpu 311
1923#endif
1924#ifndef __NR_fallocate
1925#define __NR_fallocate 314
1926#endif
1927/* Some syscalls are named/numbered differently between s390 and s390x. */
1928#ifdef __s390x__
1929# ifndef __NR_getrlimit
1930# define __NR_getrlimit 191
1931# endif
1932# ifndef __NR_setresuid
1933# define __NR_setresuid 208
1934# endif
1935# ifndef __NR_getresuid
1936# define __NR_getresuid 209
1937# endif
1938# ifndef __NR_setresgid
1939# define __NR_setresgid 210
1940# endif
1941# ifndef __NR_getresgid
1942# define __NR_getresgid 211
1943# endif
1944# ifndef __NR_setfsuid
1945# define __NR_setfsuid 215
1946# endif
1947# ifndef __NR_setfsgid
1948# define __NR_setfsgid 216
1949# endif
1950# ifndef __NR_fadvise64
1951# define __NR_fadvise64 253
1952# endif
1953# ifndef __NR_newfstatat
1954# define __NR_newfstatat 293
1955# endif
1956#else /* __s390x__ */
1957# ifndef __NR_getrlimit
1958# define __NR_getrlimit 76
1959# endif
1960# ifndef __NR_setfsuid
1961# define __NR_setfsuid 138
1962# endif
1963# ifndef __NR_setfsgid
1964# define __NR_setfsgid 139
1965# endif
1966# ifndef __NR_setresuid
1967# define __NR_setresuid 164
1968# endif
1969# ifndef __NR_getresuid
1970# define __NR_getresuid 165
1971# endif
1972# ifndef __NR_setresgid
1973# define __NR_setresgid 170
1974# endif
1975# ifndef __NR_getresgid
1976# define __NR_getresgid 171
1977# endif
1978# ifndef __NR_ugetrlimit
1979# define __NR_ugetrlimit 191
1980# endif
1981# ifndef __NR_mmap2
1982# define __NR_mmap2 192
1983# endif
1984# ifndef __NR_setresuid32
1985# define __NR_setresuid32 208
1986# endif
1987# ifndef __NR_getresuid32
1988# define __NR_getresuid32 209
1989# endif
1990# ifndef __NR_setresgid32
1991# define __NR_setresgid32 210
1992# endif
1993# ifndef __NR_getresgid32
1994# define __NR_getresgid32 211
1995# endif
1996# ifndef __NR_setfsuid32
1997# define __NR_setfsuid32 215
1998# endif
1999# ifndef __NR_setfsgid32
2000# define __NR_setfsgid32 216
2001# endif
2002# ifndef __NR_fadvise64_64
2003# define __NR_fadvise64_64 264
2004# endif
2005# ifndef __NR_fstatat64
2006# define __NR_fstatat64 293
2007# endif
2008#endif /* __s390__ */
2009/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002010#endif
2011
2012
2013/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002014#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002015 #error "Need to port invocations of syscalls for bounded ptrs"
2016#else
2017 /* The core dumper and the thread lister get executed after threads
2018 * have been suspended. As a consequence, we cannot call any functions
2019 * that acquire locks. Unfortunately, libc wraps most system calls
2020 * (e.g. in order to implement pthread_atfork, and to make calls
2021 * cancellable), which means we cannot call these functions. Instead,
2022 * we have to call syscall() directly.
2023 */
2024 #undef LSS_ERRNO
2025 #ifdef SYS_ERRNO
2026 /* Allow the including file to override the location of errno. This can
2027 * be useful when using clone() with the CLONE_VM option.
2028 */
2029 #define LSS_ERRNO SYS_ERRNO
2030 #else
2031 #define LSS_ERRNO errno
2032 #endif
2033
2034 #undef LSS_INLINE
2035 #ifdef SYS_INLINE
2036 #define LSS_INLINE SYS_INLINE
2037 #else
2038 #define LSS_INLINE static inline
2039 #endif
2040
2041 /* Allow the including file to override the prefix used for all new
2042 * system calls. By default, it will be set to "sys_".
2043 */
2044 #undef LSS_NAME
2045 #ifndef SYS_PREFIX
2046 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002047 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002048 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002049 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002050 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002051 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002052 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002053 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002054 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002055 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002056 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002057 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002058 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002059 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002060 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002061 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002062 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002063 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002064 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002065 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002066 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00002067 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002068 #define LSS_NAME(name) sys9_##name
2069 #endif
2070
2071 #undef LSS_RETURN
Askar Safine1e7b0a2021-04-12 14:03:02 +03002072 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
2073 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \
mingtaoxt xtc0c96892022-08-11 16:53:21 +08002074 || defined(__e2k__) || defined(__riscv) || defined(__loongarch_lp64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002075 /* Failing system calls return a negative result in the range of
2076 * -1..-4095. These are "errno" values with the sign inverted.
2077 */
2078 #define LSS_RETURN(type, res) \
2079 do { \
2080 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
Peter Kasting0d6435b2022-07-20 20:21:35 +00002081 LSS_ERRNO = (int)(-(res)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002082 res = -1; \
2083 } \
2084 return (type) (res); \
2085 } while (0)
2086 #elif defined(__mips__)
2087 /* On MIPS, failing system calls return -1, and set errno in a
2088 * separate CPU register.
2089 */
2090 #define LSS_RETURN(type, res, err) \
2091 do { \
2092 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002093 unsigned long __errnovalue = (res); \
2094 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002095 res = -1; \
2096 } \
2097 return (type) (res); \
2098 } while (0)
2099 #elif defined(__PPC__)
2100 /* On PPC, failing system calls return -1, and set errno in a
2101 * separate CPU register. See linux/unistd.h.
2102 */
2103 #define LSS_RETURN(type, res, err) \
2104 do { \
2105 if (err & 0x10000000 ) { \
2106 LSS_ERRNO = (res); \
2107 res = -1; \
2108 } \
2109 return (type) (res); \
2110 } while (0)
2111 #endif
2112 #if defined(__i386__)
2113 /* In PIC mode (e.g. when building shared libraries), gcc for i386
2114 * reserves ebx. Unfortunately, most distribution ship with implementations
2115 * of _syscallX() which clobber ebx.
2116 * Also, most definitions of _syscallX() neglect to mark "memory" as being
2117 * clobbered. This causes problems with compilers, that do a better job
2118 * at optimizing across __asm__ calls.
2119 * So, we just have to redefine all of the _syscallX() macros.
2120 */
2121 #undef LSS_ENTRYPOINT
2122 #ifdef SYS_SYSCALL_ENTRYPOINT
2123 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2124 void (**entrypoint)(void);
2125 asm volatile(".bss\n"
2126 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002127 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2128 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002129 ".previous\n"
2130 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
2131 "call 0f\n"
2132 "0:pop %0\n"
2133 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002134 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002135 : "=r"(entrypoint));
2136 return entrypoint;
2137 }
2138
2139 #define LSS_ENTRYPOINT ".bss\n" \
2140 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002141 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2142 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002143 ".previous\n" \
2144 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
2145 "push %%eax\n" \
2146 "call 10000f\n" \
2147 "10000:pop %%eax\n" \
2148 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002149 "mov " SYS_SYSCALL_ENTRYPOINT \
2150 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002151 "mov 0(%%eax), %%eax\n" \
2152 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002153 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002154 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002155 "call 10001f\n" \
2156 "10001:pop %%eax\n" \
2157 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002158 "xchg 4(%%esp), %%eax\n" \
2159 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002160 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002161 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002162 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002163 #else
2164 #define LSS_ENTRYPOINT "int $0x80\n"
2165 #endif
2166 #undef LSS_BODY
2167 #define LSS_BODY(type,args...) \
2168 long __res; \
2169 __asm__ __volatile__("push %%ebx\n" \
2170 "movl %2,%%ebx\n" \
2171 LSS_ENTRYPOINT \
2172 "pop %%ebx" \
2173 args \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002174 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002175 LSS_RETURN(type,__res)
2176 #undef _syscall0
2177 #define _syscall0(type,name) \
2178 type LSS_NAME(name)(void) { \
2179 long __res; \
2180 __asm__ volatile(LSS_ENTRYPOINT \
2181 : "=a" (__res) \
2182 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08002183 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002184 LSS_RETURN(type,__res); \
2185 }
2186 #undef _syscall1
2187 #define _syscall1(type,name,type1,arg1) \
2188 type LSS_NAME(name)(type1 arg1) { \
2189 LSS_BODY(type, \
2190 : "=a" (__res) \
2191 : "0" (__NR_##name), "ri" ((long)(arg1))); \
2192 }
2193 #undef _syscall2
2194 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2195 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
2196 LSS_BODY(type, \
2197 : "=a" (__res) \
2198 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
2199 }
2200 #undef _syscall3
2201 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2202 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
2203 LSS_BODY(type, \
2204 : "=a" (__res) \
2205 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2206 "d" ((long)(arg3))); \
2207 }
2208 #undef _syscall4
2209 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2210 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2211 LSS_BODY(type, \
2212 : "=a" (__res) \
2213 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2214 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2215 }
2216 #undef _syscall5
2217 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2218 type5,arg5) \
2219 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2220 type5 arg5) { \
2221 long __res; \
2222 __asm__ __volatile__("push %%ebx\n" \
2223 "movl %2,%%ebx\n" \
2224 "movl %1,%%eax\n" \
2225 LSS_ENTRYPOINT \
2226 "pop %%ebx" \
2227 : "=a" (__res) \
2228 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2229 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2230 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002231 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002232 LSS_RETURN(type,__res); \
2233 }
2234 #undef _syscall6
2235 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2236 type5,arg5,type6,arg6) \
2237 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2238 type5 arg5, type6 arg6) { \
2239 long __res; \
2240 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2241 __asm__ __volatile__("push %%ebp\n" \
2242 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002243 "movl 4(%2),%%ebp\n" \
2244 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002245 "movl %1,%%eax\n" \
2246 LSS_ENTRYPOINT \
2247 "pop %%ebx\n" \
2248 "pop %%ebp" \
2249 : "=a" (__res) \
2250 : "i" (__NR_##name), "0" ((long)(&__s)), \
2251 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2252 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002253 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002254 LSS_RETURN(type,__res); \
2255 }
2256 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2257 int flags, void *arg, int *parent_tidptr,
2258 void *newtls, int *child_tidptr) {
2259 long __res;
2260 __asm__ __volatile__(/* if (fn == NULL)
2261 * return -EINVAL;
2262 */
2263 "movl %3,%%ecx\n"
2264 "jecxz 1f\n"
2265
2266 /* if (child_stack == NULL)
2267 * return -EINVAL;
2268 */
2269 "movl %4,%%ecx\n"
2270 "jecxz 1f\n"
2271
2272 /* Set up alignment of the child stack:
2273 * child_stack = (child_stack & ~0xF) - 20;
2274 */
2275 "andl $-16,%%ecx\n"
2276 "subl $20,%%ecx\n"
2277
2278 /* Push "arg" and "fn" onto the stack that will be
2279 * used by the child.
2280 */
2281 "movl %6,%%eax\n"
2282 "movl %%eax,4(%%ecx)\n"
2283 "movl %3,%%eax\n"
2284 "movl %%eax,(%%ecx)\n"
2285
2286 /* %eax = syscall(%eax = __NR_clone,
2287 * %ebx = flags,
2288 * %ecx = child_stack,
2289 * %edx = parent_tidptr,
2290 * %esi = newtls,
2291 * %edi = child_tidptr)
2292 * Also, make sure that %ebx gets preserved as it is
2293 * used in PIC mode.
2294 */
2295 "movl %8,%%esi\n"
2296 "movl %7,%%edx\n"
2297 "movl %5,%%eax\n"
2298 "movl %9,%%edi\n"
2299 "pushl %%ebx\n"
2300 "movl %%eax,%%ebx\n"
2301 "movl %2,%%eax\n"
2302 LSS_ENTRYPOINT
2303
2304 /* In the parent: restore %ebx
2305 * In the child: move "fn" into %ebx
2306 */
2307 "popl %%ebx\n"
2308
2309 /* if (%eax != 0)
2310 * return %eax;
2311 */
2312 "test %%eax,%%eax\n"
2313 "jnz 1f\n"
2314
2315 /* In the child, now. Terminate frame pointer chain.
2316 */
2317 "movl $0,%%ebp\n"
2318
2319 /* Call "fn". "arg" is already on the stack.
2320 */
2321 "call *%%ebx\n"
2322
2323 /* Call _exit(%ebx). Unfortunately older versions
2324 * of gcc restrict the number of arguments that can
2325 * be passed to asm(). So, we need to hard-code the
2326 * system call number.
2327 */
2328 "movl %%eax,%%ebx\n"
2329 "movl $1,%%eax\n"
2330 LSS_ENTRYPOINT
2331
2332 /* Return to parent.
2333 */
2334 "1:\n"
2335 : "=a" (__res)
2336 : "0"(-EINVAL), "i"(__NR_clone),
2337 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2338 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002339 : "memory", "ecx", "edx", "esi", "edi");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002340 LSS_RETURN(int, __res);
2341 }
2342
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002343 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2344 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2345
2346 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2347 /* On i386, the kernel does not know how to return from a signal
2348 * handler. Instead, it relies on user space to provide a
2349 * restorer function that calls the {rt_,}sigreturn() system call.
2350 * Unfortunately, we cannot just reference the glibc version of this
2351 * function, as glibc goes out of its way to make it inaccessible.
2352 */
2353 void (*res)(void);
2354 __asm__ __volatile__("call 2f\n"
2355 "0:.align 16\n"
2356 "1:movl %1,%%eax\n"
2357 LSS_ENTRYPOINT
2358 "2:popl %0\n"
2359 "addl $(1b-0b),%0\n"
2360 : "=a" (res)
2361 : "i" (__NR_rt_sigreturn));
2362 return res;
2363 }
2364 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
2365 /* On i386, the kernel does not know how to return from a signal
2366 * handler. Instead, it relies on user space to provide a
2367 * restorer function that calls the {rt_,}sigreturn() system call.
2368 * Unfortunately, we cannot just reference the glibc version of this
2369 * function, as glibc goes out of its way to make it inaccessible.
2370 */
2371 void (*res)(void);
2372 __asm__ __volatile__("call 2f\n"
2373 "0:.align 16\n"
2374 "1:pop %%eax\n"
2375 "movl %1,%%eax\n"
2376 LSS_ENTRYPOINT
2377 "2:popl %0\n"
2378 "addl $(1b-0b),%0\n"
2379 : "=a" (res)
2380 : "i" (__NR_sigreturn));
2381 return res;
2382 }
2383 #elif defined(__x86_64__)
2384 /* There are no known problems with any of the _syscallX() macros
2385 * currently shipping for x86_64, but we still need to be able to define
2386 * our own version so that we can override the location of the errno
2387 * location (e.g. when using the clone() system call with the CLONE_VM
2388 * option).
2389 */
2390 #undef LSS_ENTRYPOINT
2391 #ifdef SYS_SYSCALL_ENTRYPOINT
2392 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2393 void (**entrypoint)(void);
2394 asm volatile(".bss\n"
2395 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002396 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2397 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002398 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002399 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002400 : "=r"(entrypoint));
2401 return entrypoint;
2402 }
2403
2404 #define LSS_ENTRYPOINT \
2405 ".bss\n" \
2406 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002407 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2408 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002409 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002410 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002411 "mov 0(%%rcx), %%rcx\n" \
2412 "test %%rcx, %%rcx\n" \
2413 "jz 10001f\n" \
2414 "call *%%rcx\n" \
2415 "jmp 10002f\n" \
2416 "10001:syscall\n" \
2417 "10002:\n"
2418
2419 #else
2420 #define LSS_ENTRYPOINT "syscall\n"
2421 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002422
2423 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2424 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2425 * sign extension. We can't cast pointers directly because those are
2426 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2427 * to an integer of a different size.
2428 */
2429 #undef LSS_SYSCALL_ARG
2430 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2431 #undef _LSS_RETURN
2432 #define _LSS_RETURN(type, res, cast) \
2433 do { \
2434 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
Peter Kasting880985f2022-06-29 21:17:55 +00002435 LSS_ERRNO = (int)(-(res)); \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002436 res = -1; \
2437 } \
2438 return (type)(cast)(res); \
2439 } while (0)
2440 #undef LSS_RETURN
2441 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2442
2443 #undef _LSS_BODY
2444 #define _LSS_BODY(nr, type, name, cast, ...) \
2445 long long __res; \
2446 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2447 : "=a" (__res) \
2448 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2449 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2450 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002451 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002452 #define LSS_BODY(nr, type, name, args...) \
2453 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2454
2455 #undef LSS_BODY_ASM0
2456 #undef LSS_BODY_ASM1
2457 #undef LSS_BODY_ASM2
2458 #undef LSS_BODY_ASM3
2459 #undef LSS_BODY_ASM4
2460 #undef LSS_BODY_ASM5
2461 #undef LSS_BODY_ASM6
2462 #define LSS_BODY_ASM0
2463 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2464 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2465 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2466 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2467 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2468 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2469
2470 #undef LSS_BODY_CLOBBER0
2471 #undef LSS_BODY_CLOBBER1
2472 #undef LSS_BODY_CLOBBER2
2473 #undef LSS_BODY_CLOBBER3
2474 #undef LSS_BODY_CLOBBER4
2475 #undef LSS_BODY_CLOBBER5
2476 #undef LSS_BODY_CLOBBER6
2477 #define LSS_BODY_CLOBBER0
2478 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2479 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2480 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2481 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2482 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2483 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2484
2485 #undef LSS_BODY_ARG0
2486 #undef LSS_BODY_ARG1
2487 #undef LSS_BODY_ARG2
2488 #undef LSS_BODY_ARG3
2489 #undef LSS_BODY_ARG4
2490 #undef LSS_BODY_ARG5
2491 #undef LSS_BODY_ARG6
2492 #define LSS_BODY_ARG0()
2493 #define LSS_BODY_ARG1(arg1) \
2494 LSS_BODY_ARG0(), "D" (arg1)
2495 #define LSS_BODY_ARG2(arg1, arg2) \
2496 LSS_BODY_ARG1(arg1), "S" (arg2)
2497 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2498 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2499 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2500 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2501 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2502 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2503 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2504 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2505
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002506 #undef _syscall0
2507 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002508 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002509 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002510 }
2511 #undef _syscall1
2512 #define _syscall1(type,name,type1,arg1) \
2513 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002514 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002515 }
2516 #undef _syscall2
2517 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2518 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002519 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002520 }
2521 #undef _syscall3
2522 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2523 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002524 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2525 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002526 }
2527 #undef _syscall4
2528 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2529 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002530 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2531 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002532 }
2533 #undef _syscall5
2534 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2535 type5,arg5) \
2536 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2537 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002538 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2539 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2540 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002541 }
2542 #undef _syscall6
2543 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2544 type5,arg5,type6,arg6) \
2545 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2546 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002547 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2548 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2549 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002550 }
2551 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2552 int flags, void *arg, int *parent_tidptr,
2553 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002554 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002555 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002556 __asm__ __volatile__(/* if (fn == NULL)
2557 * return -EINVAL;
2558 */
2559 "testq %4,%4\n"
2560 "jz 1f\n"
2561
2562 /* if (child_stack == NULL)
2563 * return -EINVAL;
2564 */
2565 "testq %5,%5\n"
2566 "jz 1f\n"
2567
2568 /* childstack -= 2*sizeof(void *);
2569 */
2570 "subq $16,%5\n"
2571
2572 /* Push "arg" and "fn" onto the stack that will be
2573 * used by the child.
2574 */
2575 "movq %7,8(%5)\n"
2576 "movq %4,0(%5)\n"
2577
2578 /* %rax = syscall(%rax = __NR_clone,
2579 * %rdi = flags,
2580 * %rsi = child_stack,
2581 * %rdx = parent_tidptr,
2582 * %r8 = new_tls,
2583 * %r10 = child_tidptr)
2584 */
2585 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002586 "movq %9,%%r8\n"
2587 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002588 LSS_ENTRYPOINT
2589
2590 /* if (%rax != 0)
2591 * return;
2592 */
2593 "testq %%rax,%%rax\n"
2594 "jnz 1f\n"
2595
2596 /* In the child. Terminate frame pointer chain.
2597 */
2598 "xorq %%rbp,%%rbp\n"
2599
2600 /* Call "fn(arg)".
2601 */
2602 "popq %%rax\n"
2603 "popq %%rdi\n"
2604 "call *%%rax\n"
2605
2606 /* Call _exit(%ebx).
2607 */
2608 "movq %%rax,%%rdi\n"
2609 "movq %3,%%rax\n"
2610 LSS_ENTRYPOINT
2611
2612 /* Return to parent.
2613 */
2614 "1:\n"
2615 : "=a" (__res)
2616 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002617 "r"(LSS_SYSCALL_ARG(fn)),
2618 "S"(LSS_SYSCALL_ARG(child_stack)),
2619 "D"(LSS_SYSCALL_ARG(flags)),
2620 "r"(LSS_SYSCALL_ARG(arg)),
2621 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2622 "r"(LSS_SYSCALL_ARG(newtls)),
2623 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002624 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002625 }
2626 LSS_RETURN(int, __res);
2627 }
2628 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002629
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002630 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2631 /* On x86-64, the kernel does not know how to return from
2632 * a signal handler. Instead, it relies on user space to provide a
2633 * restorer function that calls the rt_sigreturn() system call.
2634 * Unfortunately, we cannot just reference the glibc version of this
2635 * function, as glibc goes out of its way to make it inaccessible.
2636 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002637 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002638 __asm__ __volatile__("jmp 2f\n"
2639 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002640 "1:movq %1,%%rax\n"
2641 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002642 "2:leaq 1b(%%rip),%0\n"
2643 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002644 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002645 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002646 }
2647 #elif defined(__ARM_ARCH_3__)
2648 /* Most definitions of _syscallX() neglect to mark "memory" as being
2649 * clobbered. This causes problems with compilers, that do a better job
2650 * at optimizing across __asm__ calls.
2651 * So, we just have to redefine all of the _syscallX() macros.
2652 */
2653 #undef LSS_REG
2654 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2655 #undef LSS_BODY
2656 #define LSS_BODY(type,name,args...) \
2657 register long __res_r0 __asm__("r0"); \
2658 long __res; \
2659 __asm__ __volatile__ (__syscall(name) \
2660 : "=r"(__res_r0) : args : "lr", "memory"); \
2661 __res = __res_r0; \
2662 LSS_RETURN(type, __res)
2663 #undef _syscall0
2664 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002665 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002666 LSS_BODY(type, name); \
2667 }
2668 #undef _syscall1
2669 #define _syscall1(type, name, type1, arg1) \
2670 type LSS_NAME(name)(type1 arg1) { \
2671 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2672 }
2673 #undef _syscall2
2674 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2675 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2676 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2677 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2678 }
2679 #undef _syscall3
2680 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2681 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2682 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2683 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2684 }
2685 #undef _syscall4
2686 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2687 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2688 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2689 LSS_REG(3, arg4); \
2690 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2691 }
2692 #undef _syscall5
2693 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2694 type5,arg5) \
2695 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2696 type5 arg5) { \
2697 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2698 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2699 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2700 "r"(__r4)); \
2701 }
2702 #undef _syscall6
2703 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2704 type5,arg5,type6,arg6) \
2705 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2706 type5 arg5, type6 arg6) { \
2707 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2708 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2709 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2710 "r"(__r4), "r"(__r5)); \
2711 }
2712 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2713 int flags, void *arg, int *parent_tidptr,
2714 void *newtls, int *child_tidptr) {
2715 long __res;
2716 {
2717 register int __flags __asm__("r0") = flags;
2718 register void *__stack __asm__("r1") = child_stack;
2719 register void *__ptid __asm__("r2") = parent_tidptr;
2720 register void *__tls __asm__("r3") = newtls;
2721 register int *__ctid __asm__("r4") = child_tidptr;
2722 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2723 * return -EINVAL;
2724 */
2725 "cmp %2,#0\n"
2726 "cmpne %3,#0\n"
2727 "moveq %0,%1\n"
2728 "beq 1f\n"
2729
2730 /* Push "arg" and "fn" onto the stack that will be
2731 * used by the child.
2732 */
2733 "str %5,[%3,#-4]!\n"
2734 "str %2,[%3,#-4]!\n"
2735
2736 /* %r0 = syscall(%r0 = flags,
2737 * %r1 = child_stack,
2738 * %r2 = parent_tidptr,
2739 * %r3 = newtls,
2740 * %r4 = child_tidptr)
2741 */
2742 __syscall(clone)"\n"
2743
2744 /* if (%r0 != 0)
2745 * return %r0;
2746 */
2747 "movs %0,r0\n"
2748 "bne 1f\n"
2749
2750 /* In the child, now. Call "fn(arg)".
2751 */
2752 "ldr r0,[sp, #4]\n"
2753 "mov lr,pc\n"
2754 "ldr pc,[sp]\n"
2755
2756 /* Call _exit(%r0).
2757 */
2758 __syscall(exit)"\n"
2759 "1:\n"
2760 : "=r" (__res)
2761 : "i"(-EINVAL),
2762 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2763 "r"(__ptid), "r"(__tls), "r"(__ctid)
2764 : "cc", "lr", "memory");
2765 }
2766 LSS_RETURN(int, __res);
2767 }
2768 #elif defined(__ARM_EABI__)
2769 /* Most definitions of _syscallX() neglect to mark "memory" as being
2770 * clobbered. This causes problems with compilers, that do a better job
2771 * at optimizing across __asm__ calls.
2772 * So, we just have to redefine all fo the _syscallX() macros.
2773 */
2774 #undef LSS_REG
2775 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2776 #undef LSS_BODY
2777 #define LSS_BODY(type,name,args...) \
2778 register long __res_r0 __asm__("r0"); \
2779 long __res; \
2780 __asm__ __volatile__ ("push {r7}\n" \
2781 "mov r7, %1\n" \
2782 "swi 0x0\n" \
2783 "pop {r7}\n" \
2784 : "=r"(__res_r0) \
2785 : "i"(__NR_##name) , ## args \
2786 : "lr", "memory"); \
2787 __res = __res_r0; \
2788 LSS_RETURN(type, __res)
2789 #undef _syscall0
2790 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002791 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002792 LSS_BODY(type, name); \
2793 }
2794 #undef _syscall1
2795 #define _syscall1(type, name, type1, arg1) \
2796 type LSS_NAME(name)(type1 arg1) { \
2797 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2798 }
2799 #undef _syscall2
2800 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2801 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2802 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2803 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2804 }
2805 #undef _syscall3
2806 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2807 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2808 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2809 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2810 }
2811 #undef _syscall4
2812 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2813 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2814 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2815 LSS_REG(3, arg4); \
2816 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2817 }
2818 #undef _syscall5
2819 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2820 type5,arg5) \
2821 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2822 type5 arg5) { \
2823 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2824 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2825 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2826 "r"(__r4)); \
2827 }
2828 #undef _syscall6
2829 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2830 type5,arg5,type6,arg6) \
2831 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2832 type5 arg5, type6 arg6) { \
2833 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2834 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2835 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2836 "r"(__r4), "r"(__r5)); \
2837 }
2838 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2839 int flags, void *arg, int *parent_tidptr,
2840 void *newtls, int *child_tidptr) {
2841 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002842 if (fn == NULL || child_stack == NULL) {
2843 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002844 LSS_RETURN(int, __res);
2845 }
2846
2847 /* Push "arg" and "fn" onto the stack that will be
2848 * used by the child.
2849 */
2850 {
2851 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2852 cstack[0] = (uintptr_t)fn;
2853 cstack[1] = (uintptr_t)arg;
2854 child_stack = cstack;
2855 }
2856 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002857 register int __flags __asm__("r0") = flags;
2858 register void *__stack __asm__("r1") = child_stack;
2859 register void *__ptid __asm__("r2") = parent_tidptr;
2860 register void *__tls __asm__("r3") = newtls;
2861 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002862 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002863#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002864 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002865#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002866 /* %r0 = syscall(%r0 = flags,
2867 * %r1 = child_stack,
2868 * %r2 = parent_tidptr,
2869 * %r3 = newtls,
2870 * %r4 = child_tidptr)
2871 */
2872 "mov r7, %6\n"
2873 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002874
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002875 /* if (%r0 != 0)
2876 * return %r0;
2877 */
2878 "cmp r0, #0\n"
2879 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002880
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002881 /* In the child, now. Call "fn(arg)".
2882 */
2883 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002884
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002885 "ldr lr,[sp]\n"
2886 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002887
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002888 /* Call _exit(%r0).
2889 */
2890 "mov r7, %7\n"
2891 "swi 0x0\n"
2892 /* Unreachable */
2893 "bkpt #0\n"
2894 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002895#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002896 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002897#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002898 "movs %0,r0\n"
2899 : "=r"(__res)
2900 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2901 "i"(__NR_clone), "i"(__NR_exit)
2902 : "cc", "lr", "memory"
2903#ifndef __thumb2__
2904 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002905#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002906 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002907 }
2908 LSS_RETURN(int, __res);
2909 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002910 #elif defined(__aarch64__)
2911 /* Most definitions of _syscallX() neglect to mark "memory" as being
2912 * clobbered. This causes problems with compilers, that do a better job
2913 * at optimizing across __asm__ calls.
2914 * So, we just have to redefine all of the _syscallX() macros.
2915 */
2916 #undef LSS_REG
2917 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2918 #undef LSS_BODY
2919 #define LSS_BODY(type,name,args...) \
2920 register int64_t __res_x0 __asm__("x0"); \
2921 int64_t __res; \
2922 __asm__ __volatile__ ("mov x8, %1\n" \
2923 "svc 0x0\n" \
2924 : "=r"(__res_x0) \
2925 : "i"(__NR_##name) , ## args \
2926 : "x8", "memory"); \
2927 __res = __res_x0; \
2928 LSS_RETURN(type, __res)
2929 #undef _syscall0
2930 #define _syscall0(type, name) \
2931 type LSS_NAME(name)(void) { \
2932 LSS_BODY(type, name); \
2933 }
2934 #undef _syscall1
2935 #define _syscall1(type, name, type1, arg1) \
2936 type LSS_NAME(name)(type1 arg1) { \
2937 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2938 }
2939 #undef _syscall2
2940 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2941 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2942 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2943 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2944 }
2945 #undef _syscall3
2946 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2947 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2948 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2949 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2950 }
2951 #undef _syscall4
2952 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2953 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2954 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2955 LSS_REG(3, arg4); \
2956 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2957 }
2958 #undef _syscall5
2959 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2960 type5,arg5) \
2961 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2962 type5 arg5) { \
2963 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2964 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2965 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2966 "r"(__r4)); \
2967 }
2968 #undef _syscall6
2969 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2970 type5,arg5,type6,arg6) \
2971 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2972 type5 arg5, type6 arg6) { \
2973 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2974 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2975 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2976 "r"(__r4), "r"(__r5)); \
2977 }
2978
2979 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2980 int flags, void *arg, int *parent_tidptr,
2981 void *newtls, int *child_tidptr) {
2982 int64_t __res;
2983 {
Peter Kasting0d6435b2022-07-20 20:21:35 +00002984 register uint64_t __flags __asm__("x0") = (uint64_t)flags;
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002985 register void *__stack __asm__("x1") = child_stack;
2986 register void *__ptid __asm__("x2") = parent_tidptr;
2987 register void *__tls __asm__("x3") = newtls;
2988 register int *__ctid __asm__("x4") = child_tidptr;
2989 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2990 * used by the child.
2991 */
2992 "stp %1, %4, [%2, #-16]!\n"
2993
2994 /* %x0 = syscall(%x0 = flags,
2995 * %x1 = child_stack,
2996 * %x2 = parent_tidptr,
2997 * %x3 = newtls,
2998 * %x4 = child_tidptr)
2999 */
3000 "mov x8, %8\n"
3001 "svc 0x0\n"
3002
3003 /* if (%r0 != 0)
3004 * return %r0;
3005 */
3006 "mov %0, x0\n"
3007 "cbnz x0, 1f\n"
3008
3009 /* In the child, now. Call "fn(arg)".
3010 */
3011 "ldp x1, x0, [sp], #16\n"
3012 "blr x1\n"
3013
3014 /* Call _exit(%r0).
3015 */
3016 "mov x8, %9\n"
3017 "svc 0x0\n"
3018 "1:\n"
3019 : "=r" (__res)
3020 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
3021 "r"(__ptid), "r"(__tls), "r"(__ctid),
3022 "i"(__NR_clone), "i"(__NR_exit)
3023 : "cc", "x8", "memory");
3024 }
3025 LSS_RETURN(int, __res);
3026 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003027 #elif defined(__mips__)
3028 #undef LSS_REG
3029 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
3030 (unsigned long)(a)
3031 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00003032 #undef LSS_SYSCALL_CLOBBERS
3033 #if _MIPS_SIM == _MIPS_SIM_ABI32
3034 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
3035 "$11", "$12", "$13", "$14", "$15", \
3036 "$24", "$25", "hi", "lo", "memory"
3037 #else
3038 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
3039 "$13", "$14", "$15", "$24", "$25", \
3040 "hi", "lo", "memory"
3041 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003042 #define LSS_BODY(type,name,r7,...) \
3043 register unsigned long __v0 __asm__("$2") = __NR_##name; \
3044 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00003045 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003046 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00003047 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003048 LSS_RETURN(type, __v0, __r7)
3049 #undef _syscall0
3050 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00003051 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003052 register unsigned long __r7 __asm__("$7"); \
3053 LSS_BODY(type, name, "=r"); \
3054 }
3055 #undef _syscall1
3056 #define _syscall1(type, name, type1, arg1) \
3057 type LSS_NAME(name)(type1 arg1) { \
3058 register unsigned long __r7 __asm__("$7"); \
3059 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
3060 }
3061 #undef _syscall2
3062 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3063 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3064 register unsigned long __r7 __asm__("$7"); \
3065 LSS_REG(4, arg1); LSS_REG(5, arg2); \
3066 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
3067 }
3068 #undef _syscall3
3069 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3070 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3071 register unsigned long __r7 __asm__("$7"); \
3072 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3073 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
3074 }
3075 #undef _syscall4
3076 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3077 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3078 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3079 LSS_REG(7, arg4); \
3080 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
3081 }
3082 #undef _syscall5
3083 #if _MIPS_SIM == _MIPS_SIM_ABI32
3084 /* The old 32bit MIPS system call API passes the fifth and sixth argument
3085 * on the stack, whereas the new APIs use registers "r8" and "r9".
3086 */
3087 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3088 type5,arg5) \
3089 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3090 type5 arg5) { \
3091 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3092 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003093 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003094 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003095 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003096 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003097 "syscall\n" \
3098 "addiu $29, 32\n" \
3099 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003100 : "+r"(__v0), "+r" (__r7) \
3101 : "r"(__r4), "r"(__r5), \
3102 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003103 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003104 "$13", "$14", "$15", "$24", "$25", \
3105 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003106 LSS_RETURN(type, __v0, __r7); \
3107 }
3108 #else
3109 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3110 type5,arg5) \
3111 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3112 type5 arg5) { \
3113 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3114 LSS_REG(7, arg4); LSS_REG(8, arg5); \
3115 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
3116 "r"(__r8)); \
3117 }
3118 #endif
3119 #undef _syscall6
3120 #if _MIPS_SIM == _MIPS_SIM_ABI32
3121 /* The old 32bit MIPS system call API passes the fifth and sixth argument
3122 * on the stack, whereas the new APIs use registers "r8" and "r9".
3123 */
3124 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3125 type5,arg5,type6,arg6) \
3126 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3127 type5 arg5, type6 arg6) { \
3128 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3129 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003130 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003131 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003132 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003133 "sw %5, 16($29)\n" \
3134 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003135 "syscall\n" \
3136 "addiu $29, 32\n" \
3137 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003138 : "+r"(__v0), "+r" (__r7) \
3139 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003140 "r"(__r6), "r" ((unsigned long)arg5), \
3141 "r" ((unsigned long)arg6) \
3142 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003143 "$13", "$14", "$15", "$24", "$25", \
3144 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003145 LSS_RETURN(type, __v0, __r7); \
3146 }
3147 #else
3148 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3149 type5,arg5,type6,arg6) \
3150 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3151 type5 arg5,type6 arg6) { \
3152 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3153 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
3154 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
3155 "r"(__r8), "r"(__r9)); \
3156 }
3157 #endif
3158 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3159 int flags, void *arg, int *parent_tidptr,
3160 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00003161 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003162 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
3163 {
3164 register int __flags __asm__("$4") = flags;
3165 register void *__stack __asm__("$5") = child_stack;
3166 register void *__ptid __asm__("$6") = parent_tidptr;
3167 register int *__ctid __asm__("$8") = child_tidptr;
3168 __asm__ __volatile__(
3169 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3170 "subu $29,24\n"
3171 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3172 "sub $29,16\n"
3173 #else
3174 "dsubu $29,16\n"
3175 #endif
3176
3177 /* if (fn == NULL || child_stack == NULL)
3178 * return -EINVAL;
3179 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003180 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003181 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003182
3183 /* Push "arg" and "fn" onto the stack that will be
3184 * used by the child.
3185 */
3186 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003187 "subu %5,32\n"
3188 "sw %4,0(%5)\n"
3189 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003190 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003191 "sub %5,32\n"
3192 "sw %4,0(%5)\n"
3193 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003194 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00003195 "dsubu %5,32\n"
3196 "sd %4,0(%5)\n"
3197 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003198 #endif
3199
3200 /* $7 = syscall($4 = flags,
3201 * $5 = child_stack,
3202 * $6 = parent_tidptr,
3203 * $7 = newtls,
3204 * $8 = child_tidptr)
3205 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003206 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003207 "syscall\n"
3208
3209 /* if ($7 != 0)
3210 * return $2;
3211 */
3212 "bnez $7,1f\n"
3213 "bnez $2,1f\n"
3214
3215 /* In the child, now. Call "fn(arg)".
3216 */
3217 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3218 "lw $25,0($29)\n"
3219 "lw $4,4($29)\n"
3220 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3221 "lw $25,0($29)\n"
3222 "lw $4,8($29)\n"
3223 #else
3224 "ld $25,0($29)\n"
3225 "ld $4,8($29)\n"
3226 #endif
3227 "jalr $25\n"
3228
3229 /* Call _exit($2)
3230 */
3231 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003232 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003233 "syscall\n"
3234
3235 "1:\n"
3236 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3237 "addu $29, 24\n"
3238 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3239 "add $29, 16\n"
3240 #else
3241 "daddu $29,16\n"
3242 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003243 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003244 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3245 "r"(__stack), "r"(__flags), "r"(arg),
3246 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003247 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003248 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003249 }
3250 LSS_RETURN(int, __v0, __r7);
3251 }
3252 #elif defined (__PPC__)
3253 #undef LSS_LOADARGS_0
3254 #define LSS_LOADARGS_0(name, dummy...) \
3255 __sc_0 = __NR_##name
3256 #undef LSS_LOADARGS_1
3257 #define LSS_LOADARGS_1(name, arg1) \
3258 LSS_LOADARGS_0(name); \
3259 __sc_3 = (unsigned long) (arg1)
3260 #undef LSS_LOADARGS_2
3261 #define LSS_LOADARGS_2(name, arg1, arg2) \
3262 LSS_LOADARGS_1(name, arg1); \
3263 __sc_4 = (unsigned long) (arg2)
3264 #undef LSS_LOADARGS_3
3265 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3266 LSS_LOADARGS_2(name, arg1, arg2); \
3267 __sc_5 = (unsigned long) (arg3)
3268 #undef LSS_LOADARGS_4
3269 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3270 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3271 __sc_6 = (unsigned long) (arg4)
3272 #undef LSS_LOADARGS_5
3273 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3274 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3275 __sc_7 = (unsigned long) (arg5)
3276 #undef LSS_LOADARGS_6
3277 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3278 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3279 __sc_8 = (unsigned long) (arg6)
3280 #undef LSS_ASMINPUT_0
3281 #define LSS_ASMINPUT_0 "0" (__sc_0)
3282 #undef LSS_ASMINPUT_1
3283 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3284 #undef LSS_ASMINPUT_2
3285 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3286 #undef LSS_ASMINPUT_3
3287 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3288 #undef LSS_ASMINPUT_4
3289 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3290 #undef LSS_ASMINPUT_5
3291 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3292 #undef LSS_ASMINPUT_6
3293 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3294 #undef LSS_BODY
3295 #define LSS_BODY(nr, type, name, args...) \
3296 long __sc_ret, __sc_err; \
3297 { \
3298 register unsigned long __sc_0 __asm__ ("r0"); \
3299 register unsigned long __sc_3 __asm__ ("r3"); \
3300 register unsigned long __sc_4 __asm__ ("r4"); \
3301 register unsigned long __sc_5 __asm__ ("r5"); \
3302 register unsigned long __sc_6 __asm__ ("r6"); \
3303 register unsigned long __sc_7 __asm__ ("r7"); \
3304 register unsigned long __sc_8 __asm__ ("r8"); \
3305 \
3306 LSS_LOADARGS_##nr(name, args); \
3307 __asm__ __volatile__ \
3308 ("sc\n\t" \
3309 "mfcr %0" \
3310 : "=&r" (__sc_0), \
3311 "=&r" (__sc_3), "=&r" (__sc_4), \
3312 "=&r" (__sc_5), "=&r" (__sc_6), \
3313 "=&r" (__sc_7), "=&r" (__sc_8) \
3314 : LSS_ASMINPUT_##nr \
3315 : "cr0", "ctr", "memory", \
3316 "r9", "r10", "r11", "r12"); \
3317 __sc_ret = __sc_3; \
3318 __sc_err = __sc_0; \
3319 } \
3320 LSS_RETURN(type, __sc_ret, __sc_err)
3321 #undef _syscall0
3322 #define _syscall0(type, name) \
3323 type LSS_NAME(name)(void) { \
3324 LSS_BODY(0, type, name); \
3325 }
3326 #undef _syscall1
3327 #define _syscall1(type, name, type1, arg1) \
3328 type LSS_NAME(name)(type1 arg1) { \
3329 LSS_BODY(1, type, name, arg1); \
3330 }
3331 #undef _syscall2
3332 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3333 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3334 LSS_BODY(2, type, name, arg1, arg2); \
3335 }
3336 #undef _syscall3
3337 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3338 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3339 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3340 }
3341 #undef _syscall4
3342 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3343 type4, arg4) \
3344 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3345 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3346 }
3347 #undef _syscall5
3348 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3349 type4, arg4, type5, arg5) \
3350 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3351 type5 arg5) { \
3352 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3353 }
3354 #undef _syscall6
3355 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3356 type4, arg4, type5, arg5, type6, arg6) \
3357 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3358 type5 arg5, type6 arg6) { \
3359 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3360 }
3361 /* clone function adapted from glibc 2.3.6 clone.S */
3362 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3363 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3364 */
3365 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3366 int flags, void *arg, int *parent_tidptr,
3367 void *newtls, int *child_tidptr) {
3368 long __ret, __err;
3369 {
3370 register int (*__fn)(void *) __asm__ ("r8") = fn;
3371 register void *__cstack __asm__ ("r4") = child_stack;
3372 register int __flags __asm__ ("r3") = flags;
3373 register void * __arg __asm__ ("r9") = arg;
3374 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3375 register void * __newtls __asm__ ("r6") = newtls;
3376 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3377 __asm__ __volatile__(
3378 /* check for fn == NULL
3379 * and child_stack == NULL
3380 */
3381 "cmpwi cr0, %6, 0\n\t"
3382 "cmpwi cr1, %7, 0\n\t"
3383 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3384 "beq- cr0, 1f\n\t"
3385
3386 /* set up stack frame for child */
3387 "clrrwi %7, %7, 4\n\t"
3388 "li 0, 0\n\t"
3389 "stwu 0, -16(%7)\n\t"
3390
3391 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3392 "mr 28, %6\n\t"
3393 "mr 29, %7\n\t"
3394 "mr 27, %9\n\t"
3395
3396 /* syscall */
3397 "li 0, %4\n\t"
3398 /* flags already in r3
3399 * child_stack already in r4
3400 * ptidptr already in r5
3401 * newtls already in r6
3402 * ctidptr already in r7
3403 */
3404 "sc\n\t"
3405
3406 /* Test if syscall was successful */
3407 "cmpwi cr1, 3, 0\n\t"
3408 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3409 "bne- cr1, 1f\n\t"
3410
3411 /* Do the function call */
3412 "mtctr 28\n\t"
3413 "mr 3, 27\n\t"
3414 "bctrl\n\t"
3415
3416 /* Call _exit(r3) */
3417 "li 0, %5\n\t"
3418 "sc\n\t"
3419
3420 /* Return to parent */
3421 "1:\n"
3422 "mfcr %1\n\t"
3423 "mr %0, 3\n\t"
3424 : "=r" (__ret), "=r" (__err)
3425 : "0" (-1), "1" (EINVAL),
3426 "i" (__NR_clone), "i" (__NR_exit),
3427 "r" (__fn), "r" (__cstack), "r" (__flags),
3428 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3429 "r" (__ctidptr)
3430 : "cr0", "cr1", "memory", "ctr",
3431 "r0", "r29", "r27", "r28");
3432 }
3433 LSS_RETURN(int, __ret, __err);
3434 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003435 #elif defined(__s390__)
3436 #undef LSS_REG
3437 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3438 #undef LSS_BODY
3439 #define LSS_BODY(type, name, args...) \
3440 register unsigned long __nr __asm__("r1") \
3441 = (unsigned long)(__NR_##name); \
3442 register long __res_r2 __asm__("r2"); \
3443 long __res; \
3444 __asm__ __volatile__ \
3445 ("svc 0\n\t" \
3446 : "=d"(__res_r2) \
3447 : "d"(__nr), ## args \
3448 : "memory"); \
3449 __res = __res_r2; \
3450 LSS_RETURN(type, __res)
3451 #undef _syscall0
3452 #define _syscall0(type, name) \
3453 type LSS_NAME(name)(void) { \
3454 LSS_BODY(type, name); \
3455 }
3456 #undef _syscall1
3457 #define _syscall1(type, name, type1, arg1) \
3458 type LSS_NAME(name)(type1 arg1) { \
3459 LSS_REG(2, arg1); \
3460 LSS_BODY(type, name, "0"(__r2)); \
3461 }
3462 #undef _syscall2
3463 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3464 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3465 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3466 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3467 }
3468 #undef _syscall3
3469 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3470 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3471 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3472 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3473 }
3474 #undef _syscall4
3475 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3476 type4, arg4) \
3477 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3478 type4 arg4) { \
3479 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3480 LSS_REG(5, arg4); \
3481 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3482 "d"(__r5)); \
3483 }
3484 #undef _syscall5
3485 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3486 type4, arg4, type5, arg5) \
3487 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3488 type4 arg4, type5 arg5) { \
3489 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3490 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3491 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3492 "d"(__r5), "d"(__r6)); \
3493 }
3494 #undef _syscall6
3495 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3496 type4, arg4, type5, arg5, type6, arg6) \
3497 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3498 type4 arg4, type5 arg5, type6 arg6) { \
3499 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3500 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3501 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3502 "d"(__r5), "d"(__r6), "d"(__r7)); \
3503 }
3504 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3505 int flags, void *arg, int *parent_tidptr,
3506 void *newtls, int *child_tidptr) {
3507 long __ret;
3508 {
3509 register int (*__fn)(void *) __asm__ ("r1") = fn;
3510 register void *__cstack __asm__ ("r2") = child_stack;
3511 register int __flags __asm__ ("r3") = flags;
3512 register void *__arg __asm__ ("r0") = arg;
3513 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3514 register void *__newtls __asm__ ("r6") = newtls;
3515 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3516 __asm__ __volatile__ (
3517 #ifndef __s390x__
3518 /* arg already in r0 */
3519 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3520 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3521 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3522 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3523 /* flags already in r3 */
3524 /* parent_tidptr already in r4 */
3525 /* child_tidptr already in r5 */
3526 /* newtls already in r6 */
3527 "svc %2\n\t" /* invoke clone syscall */
3528 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3529 "jnz 1f\n\t" /* return to parent if non-zero */
3530 /* start child thread */
3531 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3532 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3533 "xc 0(4,%%r15), 0(%%r15)\n\t"
3534 "basr %%r14, %4\n\t" /* jump to fn */
3535 "svc %3\n" /* invoke exit syscall */
3536 "1:\n"
3537 #else
3538 /* arg already in r0 */
3539 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3540 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3541 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3542 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3543 /* flags already in r3 */
3544 /* parent_tidptr already in r4 */
3545 /* child_tidptr already in r5 */
3546 /* newtls already in r6 */
3547 "svc %2\n\t" /* invoke clone syscall */
3548 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3549 "jnz 1f\n\t" /* return to parent if non-zero */
3550 /* start child thread */
3551 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3552 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3553 "xc 0(8,%%r15), 0(%%r15)\n\t"
3554 "basr %%r14, %4\n\t" /* jump to fn */
3555 "svc %3\n" /* invoke exit syscall */
3556 "1:\n"
3557 #endif
3558 : "=r" (__ret)
3559 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3560 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3561 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3562 : "cc", "r14", "memory"
3563 );
3564 }
3565 LSS_RETURN(int, __ret);
3566 }
Andreas Schwab1d387f42022-02-15 16:21:13 +01003567 #elif defined(__riscv) && __riscv_xlen == 64
3568 #undef LSS_REG
3569 #define LSS_REG(r,a) register int64_t __r##r __asm__("a"#r) = (int64_t)a
3570 #undef LSS_BODY
3571 #define LSS_BODY(type,name,args...) \
3572 register int64_t __res_a0 __asm__("a0"); \
3573 register int64_t __a7 __asm__("a7") = __NR_##name; \
3574 int64_t __res; \
3575 __asm__ __volatile__ ("scall\n" \
3576 : "=r"(__res_a0) \
3577 : "r"(__a7) , ## args \
3578 : "memory"); \
3579 __res = __res_a0; \
3580 LSS_RETURN(type, __res)
3581 #undef _syscall0
3582 #define _syscall0(type, name) \
3583 type LSS_NAME(name)(void) { \
3584 LSS_BODY(type, name); \
3585 }
3586 #undef _syscall1
3587 #define _syscall1(type, name, type1, arg1) \
3588 type LSS_NAME(name)(type1 arg1) { \
3589 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
3590 }
3591 #undef _syscall2
3592 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3593 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3594 LSS_REG(0, arg1); LSS_REG(1, arg2); \
3595 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
3596 }
3597 #undef _syscall3
3598 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3599 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3600 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3601 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
3602 }
3603 #undef _syscall4
3604 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3605 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3606 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3607 LSS_REG(3, arg4); \
3608 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
3609 }
3610 #undef _syscall5
3611 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3612 type5,arg5) \
3613 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3614 type5 arg5) { \
3615 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3616 LSS_REG(3, arg4); LSS_REG(4, arg5); \
3617 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3618 "r"(__r4)); \
3619 }
3620 #undef _syscall6
3621 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3622 type5,arg5,type6,arg6) \
3623 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3624 type5 arg5, type6 arg6) { \
3625 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3626 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
3627 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3628 "r"(__r4), "r"(__r5)); \
3629 }
3630
3631 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3632 int flags, void *arg, int *parent_tidptr,
3633 void *newtls, int *child_tidptr) {
3634 int64_t __res;
3635 {
3636 register int64_t __res_a0 __asm__("a0");
3637 register uint64_t __flags __asm__("a0") = flags;
3638 register void *__stack __asm__("a1") = child_stack;
3639 register void *__ptid __asm__("a2") = parent_tidptr;
3640 register void *__tls __asm__("a3") = newtls;
3641 register int *__ctid __asm__("a4") = child_tidptr;
3642 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
3643 * used by the child.
3644 */
3645 "addi %2,%2,-16\n"
3646 "sd %1, 0(%2)\n"
3647 "sd %4, 8(%2)\n"
3648
3649 /* %a0 = syscall(%a0 = flags,
3650 * %a1 = child_stack,
3651 * %a2 = parent_tidptr,
3652 * %a3 = newtls,
3653 * %a4 = child_tidptr)
3654 */
3655 "li a7, %8\n"
3656 "scall\n"
3657
3658 /* if (%a0 != 0)
3659 * return %a0;
3660 */
3661 "bnez %0, 1f\n"
3662
3663 /* In the child, now. Call "fn(arg)".
3664 */
3665 "ld a1, 0(sp)\n"
3666 "ld a0, 8(sp)\n"
3667 "jalr a1\n"
3668
3669 /* Call _exit(%a0).
3670 */
3671 "li a7, %9\n"
3672 "scall\n"
3673 "1:\n"
3674 : "=r" (__res_a0)
3675 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
3676 "r"(__ptid), "r"(__tls), "r"(__ctid),
3677 "i"(__NR_clone), "i"(__NR_exit)
3678 : "cc", "memory");
3679 __res = __res_a0;
3680 }
3681 LSS_RETURN(int, __res);
3682 }
Konstantin Ivlev8007b272021-01-27 18:27:42 +03003683 #elif defined(__e2k__)
3684
3685 #undef _LSS_BODY
3686 #define _LSS_BODY(nr, type, name, ...) \
3687 register unsigned long long __res; \
3688 __asm__ __volatile__ \
3689 ( \
3690 "{\n\t" \
3691 " sdisp %%ctpr1, 0x3\n\t" \
3692 " addd, s 0x0, %[sys_num], %%b[0]\n\t" \
3693 LSS_BODY_ASM##nr \
3694 "}\n\t" \
3695 "{\n\t" \
3696 " call %%ctpr1, wbs = %#\n\t" \
3697 "}\n\t" \
3698 "{\n\t" \
3699 " addd, s 0x0, %%b[0], %[res]\n\t" \
3700 "}\n\t" \
3701 : [res] "=r" (__res) \
3702 : \
3703 LSS_BODY_ARG##nr(__VA_ARGS__) \
3704 [sys_num] "ri" (__NR_##name) \
3705 : "ctpr1", "ctpr2", "ctpr3", \
3706 "b[0]", "b[1]", "b[2]", "b[3]", \
3707 "b[4]", "b[5]", "b[6]", "b[7]" \
3708 ); \
3709 LSS_RETURN(type, __res);
3710
3711 #undef LSS_BODY
3712 #define LSS_BODY(nr, type, name, args...) \
3713 _LSS_BODY(nr, type, name, ## args)
3714
3715 #undef LSS_BODY_ASM0
3716 #undef LSS_BODY_ASM1
3717 #undef LSS_BODY_ASM2
3718 #undef LSS_BODY_ASM3
3719 #undef LSS_BODY_ASM4
3720 #undef LSS_BODY_ASM5
3721 #undef LSS_BODY_ASM6
3722
3723 #define LSS_BODY_ASM0
3724 #define LSS_BODY_ASM1 LSS_BODY_ASM0 \
3725 " addd, s 0x0, %[arg1], %%b[1]\n\t"
3726 #define LSS_BODY_ASM2 LSS_BODY_ASM1 \
3727 " addd, s 0x0, %[arg2], %%b[2]\n\t"
3728 #define LSS_BODY_ASM3 LSS_BODY_ASM2 \
3729 " addd, s 0x0, %[arg3], %%b[3]\n\t"
3730 #define LSS_BODY_ASM4 LSS_BODY_ASM3 \
3731 " addd, s 0x0, %[arg4], %%b[4]\n\t"
3732 #define LSS_BODY_ASM5 LSS_BODY_ASM4 \
3733 " addd, s 0x0, %[arg5], %%b[5]\n\t"
3734 #define LSS_BODY_ASM6 LSS_BODY_ASM5 \
3735 "}\n\t" \
3736 "{\n\t" \
3737 " addd, s 0x0, %[arg6], %%b[6]\n\t"
3738
3739 #undef LSS_SYSCALL_ARG
3740 #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a))
3741
3742 #undef LSS_BODY_ARG0
3743 #undef LSS_BODY_ARG1
3744 #undef LSS_BODY_ARG2
3745 #undef LSS_BODY_ARG3
3746 #undef LSS_BODY_ARG4
3747 #undef LSS_BODY_ARG5
3748 #undef LSS_BODY_ARG6
3749
3750 #define LSS_BODY_ARG0()
3751 #define LSS_BODY_ARG1(_arg1) \
3752 [arg1] "ri" LSS_SYSCALL_ARG(_arg1),
3753 #define LSS_BODY_ARG2(_arg1, _arg2) \
3754 LSS_BODY_ARG1(_arg1) \
3755 [arg2] "ri" LSS_SYSCALL_ARG(_arg2),
3756 #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3757 LSS_BODY_ARG2(_arg1, _arg2) \
3758 [arg3] "ri" LSS_SYSCALL_ARG(_arg3),
3759 #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3760 LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3761 [arg4] "ri" LSS_SYSCALL_ARG(_arg4),
3762 #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3763 LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3764 [arg5] "ri" LSS_SYSCALL_ARG(_arg5),
3765 #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \
3766 LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3767 [arg6] "ri" LSS_SYSCALL_ARG(_arg6),
3768
3769 #undef _syscall0
3770 #define _syscall0(type, name) \
3771 type LSS_NAME(name)(void) { \
3772 LSS_BODY(0, type, name); \
3773 }
3774
3775 #undef _syscall1
3776 #define _syscall1(type, name, type1, arg1) \
3777 type LSS_NAME(name)(type1 arg1) { \
3778 LSS_BODY(1, type, name, arg1) \
3779 }
3780
3781 #undef _syscall2
3782 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3783 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3784 LSS_BODY(2, type, name, arg1, arg2) \
3785 }
3786
3787 #undef _syscall3
3788 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3789 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3790 LSS_BODY(3, type, name, arg1, arg2, arg3) \
3791 }
3792
3793 #undef _syscall4
3794 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3795 type4, arg4) \
3796 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3797 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \
3798 }
3799
3800 #undef _syscall5
3801 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3802 type4, arg4, type5, arg5) \
3803 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3804 type5 arg5) { \
3805 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \
3806 }
3807
3808 #undef _syscall6
3809 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3810 type4, arg4, type5, arg5, type6, arg6) \
3811 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3812 type5 arg5, type6 arg6) { \
3813 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \
3814 }
3815
3816 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3817 int flags, void *arg, int *parent_tidptr,
3818 void *newtls, int *child_tidptr) {
3819 unsigned long long __res;
3820
3821 __asm__ __volatile__ (
3822 "{\n\t"
3823 " addd,s 0x0, %[nr_clone], %%b[0]\n\t"
3824 " addd,s 0x0, %[flags], %%db[1]\n\t"
3825 " addd,s 0x0, %[child_stack], %%db[2]\n\t"
3826 " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t"
3827 " addd,s 0x0, %[child_tidptr], %%db[4]\n\t"
3828 " addd,s 0x0, %[newtls], %%db[5]\n\t"
3829 "}\n\t"
3830 /* if (fn == NULL)
3831 * return -EINVAL;
3832 */
3833
3834 "{\n\t"
3835 " disp %%ctpr1, .L1\n\t"
3836 "}\n\t"
3837 "{\n\t"
3838 " cmpesb,s 0x0, %[fn], %%pred0\n\t"
3839 "}\n\t"
3840 "{\n\t"
3841 " ct %%ctpr1 ? %%pred0\n\t"
3842 "}\n\t"
3843
3844 /* if (child_stack == NULL)
3845 * return -EINVAL;
3846 */
3847 "{\n\t"
3848 " cmpesb,s 0x0, %%db[2], %%pred0\n\t"
3849 "}\n\t"
3850 "{\n\t"
3851 " ct %%ctpr1 ? %%pred0\n\t"
3852 "}\n\t"
3853
3854 /* b[0] = syscall(%b[0] = __NR_clone,
3855 * %db[1] = flags,
3856 * %db[2] = child_stack,
3857 * %db[3] = parent_tidptr,
3858 * %db[4] = child_tidptr,
3859 * %db[5] = newtls)
3860 */
3861 "{\n\t"
3862 " sdisp %%ctpr1, 0x3\n\t"
3863 "}\n\t"
3864 "{\n\t"
3865 " call %%ctpr1, wbs = %#\n\t"
3866 "}\n\t"
3867
3868 /* if (%[b0] != 0)
3869 * return %b[0];
3870 */
3871 "{\n\t"
3872 " disp %%ctpr1, .L2\n\t"
3873 " cmpesb,s 0x0, %%b[0], %%pred0\n\t"
3874 "}\n\t"
3875 "{\n\t"
3876 " ct %%ctpr1 ? ~%%pred0\n\t"
3877 "}\n\t"
3878 /* In the child, now. Call "fn(arg)".
3879 */
3880
3881 "{\n\t"
3882 " movtd,s %[fn], %%ctpr1\n\t"
3883 "}\n\t"
3884 "{\n\t"
3885 " addd,s 0x0, %[arg], %%db[0]\n\t"
3886 "}\n\t"
3887 "{\n\t"
3888 " call %%ctpr1, wbs = %#\n\t"
3889 "}\n\t"
3890 /* Call _exit(%b[0]).
3891 */
3892
3893 "{\n\t"
3894 " sdisp %%ctpr1, 0x3\n\t"
3895 " addd,s 0x0, %%b[0], %%b[1]\n\t"
3896 "}\n\t"
3897 "{\n\t"
3898 " addd,s 0x0, %[nr_exit], %%b[0]\n\t"
3899 "}\n\t"
3900 "{\n\t"
3901 " call %%ctpr1, wbs = %#\n\t"
3902 "}\n\t"
3903 "{\n\t"
3904 " disp %%ctpr1, .L2\n\t"
3905 " adds,s 0x0, 0x0, %%b[0]\n\t"
3906 "}\n\t"
3907 "{\n\t"
3908 " ct %%ctpr1\n\t"
3909 "}\n\t"
3910 ".L1:\n\t"
3911 "{\n\t"
3912 " addd,s 0x0, %[einval], %%b[0]\n\t"
3913 "}\n\t"
3914 ".L2:\n\t"
3915 "{\n\t"
3916 " addd,s 0x0, %%b[0], %[res]\n\t"
3917 "}\n\t"
3918 : [res] "=r" LSS_SYSCALL_ARG(__res)
3919 : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone)
3920 [arg] "ri" LSS_SYSCALL_ARG(arg)
3921 [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit)
3922 [flags] "ri" LSS_SYSCALL_ARG(flags)
3923 [child_stack] "ri" LSS_SYSCALL_ARG(child_stack)
3924 [parent_tidptr] "ri"
3925 LSS_SYSCALL_ARG(parent_tidptr)
3926 [newtls] "ri" LSS_SYSCALL_ARG(newtls)
3927 [child_tidptr] "ri"
3928 LSS_SYSCALL_ARG(child_tidptr)
3929 [fn] "ri" LSS_SYSCALL_ARG(fn)
3930 [einval] "ri" LSS_SYSCALL_ARG(-EINVAL)
3931 : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]",
3932 "b[4]", "b[5]", "pred0");
3933 LSS_RETURN(int, __res);
3934 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08003935 #elif defined(__loongarch_lp64)
3936 /* Most definitions of _syscallX() neglect to mark "memory" as being
3937 * clobbered. This causes problems with compilers, that do a better job
3938 * at optimizing across __asm__ calls.
3939 * So, we just have to redefine all of the _syscallX() macros.
3940 */
3941 #undef LSS_REG
3942 #define LSS_REG(ar,a) register int64_t __r##ar __asm__("a"#ar) = (int64_t)a
3943 /* syscall is like subroutine calls, all caller-saved registers may be
3944 * clobbered, we should add them to the |Clobbers| list.
3945 * a0 is not included because it's in the output list.
3946 */
3947 #define LSS_SYSCALL_CLOBBERS "t0", "t1", "t2", "t3", "t4", "t5", "t6", \
3948 "t7", "t8", "memory"
3949 #undef LSS_BODY
3950 #define LSS_BODY(type,name,args...) \
3951 register int64_t __res_a0 __asm__("a0"); \
3952 int64_t __res; \
3953 __asm__ __volatile__ ("li.d $a7, %1\n" \
3954 "syscall 0x0\n" \
3955 : "=r"(__res_a0) \
3956 : "i"(__NR_##name) , ## args \
3957 : LSS_SYSCALL_CLOBBERS); \
3958 __res = __res_a0; \
3959 LSS_RETURN(type, __res)
3960 #undef _syscall0
3961 #define _syscall0(type, name) \
3962 type LSS_NAME(name)(void) { \
3963 LSS_BODY(type, name); \
3964 }
3965 #undef _syscall1
3966 #define _syscall1(type, name, type1, arg1) \
3967 type LSS_NAME(name)(type1 arg1) { \
3968 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
3969 }
3970 #undef _syscall2
3971 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3972 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3973 LSS_REG(0, arg1); LSS_REG(1, arg2); \
3974 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
3975 }
3976 #undef _syscall3
3977 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3978 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3979 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3980 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
3981 }
3982 #undef _syscall4
3983 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3984 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3985 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3986 LSS_REG(3, arg4); \
3987 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
3988 }
3989 #undef _syscall5
3990 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3991 type5,arg5) \
3992 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3993 type5 arg5) { \
3994 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3995 LSS_REG(3, arg4); LSS_REG(4, arg5); \
3996 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3997 "r"(__r4)); \
3998 }
3999 #undef _syscall6
4000 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
4001 type5,arg5,type6,arg6) \
4002 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
4003 type5 arg5, type6 arg6) { \
4004 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
4005 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
4006 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
4007 "r"(__r4), "r"(__r5)); \
4008 }
4009
4010 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
4011 int flags, void *arg, int *parent_tidptr,
4012 void *newtls, int *child_tidptr) {
4013 int64_t __res;
4014 {
4015 register int64_t __res_a0 __asm__("a0");
4016 register uint64_t __flags __asm__("a0") = flags;
4017 register void *__stack __asm__("a1") = child_stack;
4018 register void *__ptid __asm__("a2") = parent_tidptr;
4019 register void *__tls __asm__("a3") = newtls;
4020 register int *__ctid __asm__("a4") = child_tidptr;
4021 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
4022 * used by the child.
4023 */
4024 "addi.d %2, %2, -16\n"
4025 "st.d %1, %2, 8\n"
4026 "st.d %4, %2, 0\n"
4027
4028 /* %a0 = syscall(%a0 = flags,
4029 * %a1 = child_stack,
4030 * %a2 = parent_tidptr,
4031 * %a3 = newtls,
4032 * %a4 = child_tidptr)
4033 */
4034 "li.d $a7, %8\n"
4035 "syscall 0x0\n"
4036
4037 /* if (%a0 != 0)
4038 * return %a0;
4039 */
4040 "bnez $a0, 1f\n"
4041
4042 /* In the child, now. Call "fn(arg)".
4043 */
4044 "ld.d $a0, $sp, 0\n"
4045 "ld.d $a1, $sp, 8\n"
4046 "addi.d $sp, $sp, 16\n"
4047 "jirl $ra, $a1, 0\n"
4048
4049 /* Call _exit(%a0).
4050 */
4051 "li.d $a7, %9\n"
4052 "syscall 0x0\n"
4053 "1:\n"
4054 : "=r" (__res_a0)
4055 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
4056 "r"(__ptid), "r"(__tls), "r"(__ctid),
4057 "i"(__NR_clone), "i"(__NR_exit)
4058 : LSS_SYSCALL_CLOBBERS);
4059 __res = __res_a0;
4060 }
4061 LSS_RETURN(int, __res);
4062 }
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004063
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004064 #endif
4065 #define __NR__exit __NR_exit
4066 #define __NR__gettid __NR_gettid
4067 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00004068 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004069 LSS_INLINE _syscall1(int, chdir, const char *,p)
4070 LSS_INLINE _syscall1(int, close, int, f)
4071 LSS_INLINE _syscall2(int, clock_getres, int, c,
4072 struct kernel_timespec*, t)
4073 LSS_INLINE _syscall2(int, clock_gettime, int, c,
4074 struct kernel_timespec*, t)
4075 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004076 #if defined(__NR_dup2)
4077 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004078 LSS_INLINE _syscall2(int, dup2, int, s,
4079 int, d)
4080 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004081 #if defined(__NR_dup3)
4082 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
4083 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004084 LSS_INLINE _syscall3(int, execve, const char*, f,
4085 const char*const*,a,const char*const*, e)
4086 LSS_INLINE _syscall1(int, _exit, int, e)
4087 LSS_INLINE _syscall1(int, exit_group, int, e)
4088 LSS_INLINE _syscall3(int, fcntl, int, f,
4089 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004090 #if defined(__NR_fork)
4091 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004092 LSS_INLINE _syscall0(pid_t, fork)
4093 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004094 #if defined(__NR_fstat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004095 LSS_INLINE _syscall2(int, fstat, int, f,
4096 struct kernel_stat*, b)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004097 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004098 LSS_INLINE _syscall2(int, fstatfs, int, f,
4099 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004100 #if defined(__x86_64__)
4101 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
4102 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
4103 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
4104 }
4105 #else
4106 LSS_INLINE _syscall2(int, ftruncate, int, f,
4107 off_t, l)
4108 #endif
Mike Frysinger171a36a2019-01-26 23:05:43 -05004109 LSS_INLINE _syscall6(int, futex, int*, u,
4110 int, o, int, v,
4111 struct kernel_timespec*, t,
4112 int*, u2, int, v2)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004113 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004114 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004115 LSS_INLINE _syscall3(int, getdents64, int, f,
4116 struct kernel_dirent64*, d, int, c)
4117 LSS_INLINE _syscall0(gid_t, getegid)
4118 LSS_INLINE _syscall0(uid_t, geteuid)
Doug Kwan32a80cd2022-07-01 17:52:39 +00004119 LSS_INLINE _syscall2(int, getitimer, int, w,
4120 struct kernel_itimerval*, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004121 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004122 LSS_INLINE _syscall0(pid_t, getpgrp)
4123 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004124 LSS_INLINE _syscall0(pid_t, getpid)
4125 LSS_INLINE _syscall0(pid_t, getppid)
4126 LSS_INLINE _syscall2(int, getpriority, int, a,
4127 int, b)
4128 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
4129 gid_t *, e, gid_t *, s)
4130 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
4131 uid_t *, e, uid_t *, s)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004132 #if defined(__NR_getrlimit)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004133 LSS_INLINE _syscall2(int, getrlimit, int, r,
4134 struct kernel_rlimit*, l)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004135 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004136 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
4137 LSS_INLINE _syscall0(pid_t, _gettid)
4138 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
4139 void*, tz)
4140 LSS_INLINE _syscall5(int, setxattr, const char *,p,
4141 const char *, n, const void *,v,
4142 size_t, s, int, f)
4143 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
4144 const char *, n, const void *,v,
4145 size_t, s, int, f)
4146 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
4147 const char *, n, void *, v, size_t, s)
4148 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
4149 const char *, n, void *, v, size_t, s)
4150 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
4151 char *, l, size_t, s)
4152 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
4153 char *, l, size_t, s)
4154 LSS_INLINE _syscall3(int, ioctl, int, d,
4155 int, r, void *, a)
4156 LSS_INLINE _syscall2(int, ioprio_get, int, which,
4157 int, who)
4158 LSS_INLINE _syscall3(int, ioprio_set, int, which,
4159 int, who, int, ioprio)
4160 LSS_INLINE _syscall2(int, kill, pid_t, p,
4161 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004162 #if defined(__x86_64__)
4163 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
4164 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
4165 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4166 LSS_SYSCALL_ARG(w));
4167 }
4168 #else
4169 LSS_INLINE _syscall3(off_t, lseek, int, f,
4170 off_t, o, int, w)
4171 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004172 LSS_INLINE _syscall2(int, munmap, void*, s,
4173 size_t, l)
4174 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
4175 unsigned long, n, void **,g, int *, d,
4176 int *, s, int, f)
4177 LSS_INLINE _syscall3(int, mprotect, const void *,a,
4178 size_t, l, int, p)
4179 LSS_INLINE _syscall5(void*, _mremap, void*, o,
4180 size_t, os, size_t, ns,
4181 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004182 #if defined(__NR_open)
4183 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004184 LSS_INLINE _syscall3(int, open, const char*, p,
4185 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004186 #endif
4187 #if defined(__NR_poll)
4188 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004189 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
4190 unsigned int, n, int, t)
4191 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004192 #if defined(__NR_ppoll)
4193 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
4194 unsigned int, n, const struct kernel_timespec *, t,
4195 const struct kernel_sigset_t *, sigmask, size_t, s)
4196 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00004197 LSS_INLINE _syscall5(int, prctl, int, option,
4198 unsigned long, arg2,
4199 unsigned long, arg3,
4200 unsigned long, arg4,
4201 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004202 LSS_INLINE _syscall4(long, ptrace, int, r,
4203 pid_t, p, void *, a, void *, d)
4204 #if defined(__NR_quotactl)
4205 // Defined on x86_64 / i386 only
4206 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
4207 int, id, caddr_t, addr)
4208 #endif
4209 LSS_INLINE _syscall3(ssize_t, read, int, f,
4210 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004211 #if defined(__NR_readlink)
4212 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004213 LSS_INLINE _syscall3(int, readlink, const char*, p,
4214 char*, b, size_t, s)
4215 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004216 #if defined(__NR_readlinkat)
4217 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
4218 size_t, s)
4219 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004220 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
4221 const struct kernel_sigaction*, a,
4222 struct kernel_sigaction*, o, size_t, c)
4223 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
4224 size_t, c)
4225 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
4226 const struct kernel_sigset_t*, s,
4227 struct kernel_sigset_t*, o, size_t, c)
4228 LSS_INLINE _syscall2(int, rt_sigsuspend,
4229 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08004230 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
4231 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004232 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
4233 unsigned int, l, unsigned long *, m)
4234 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
4235 unsigned int, l, unsigned long *, m)
4236 LSS_INLINE _syscall0(int, sched_yield)
4237 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
4238 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
4239 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
4240 LSS_INLINE _syscall1(int, setuid, uid_t, u)
4241 LSS_INLINE _syscall1(int, setgid, gid_t, g)
Doug Kwan32a80cd2022-07-01 17:52:39 +00004242 LSS_INLINE _syscall3(int, setitimer, int, w,
4243 const struct kernel_itimerval*, n,
4244 struct kernel_itimerval*, o)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004245 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
4246 pid_t, g)
4247 LSS_INLINE _syscall3(int, setpriority, int, a,
4248 int, b, int, p)
4249 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
4250 gid_t, e, gid_t, s)
4251 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
4252 uid_t, e, uid_t, s)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004253 #if defined(__NR_setrlimit)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004254 LSS_INLINE _syscall2(int, setrlimit, int, r,
4255 const struct kernel_rlimit*, l)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004256 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004257 LSS_INLINE _syscall0(pid_t, setsid)
4258 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
4259 const stack_t*, o)
4260 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004261 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004262 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004263 #if defined(__NR_stat)
Matthew Denton92a65a82021-04-01 13:00:07 -07004264 // stat and lstat are polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004265 LSS_INLINE _syscall2(int, stat, const char*, f,
4266 struct kernel_stat*, b)
4267 #endif
Matthew Denton92a65a82021-04-01 13:00:07 -07004268 #if defined(__NR_lstat)
4269 LSS_INLINE _syscall2(int, lstat, const char*, f,
4270 struct kernel_stat*, b)
4271 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004272 LSS_INLINE _syscall2(int, statfs, const char*, f,
4273 struct kernel_statfs*, b)
4274 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
4275 pid_t, t, int, s)
4276 LSS_INLINE _syscall2(int, tkill, pid_t, p,
4277 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004278 #if defined(__NR_unlink)
4279 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004280 LSS_INLINE _syscall1(int, unlink, const char*, f)
4281 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004282 LSS_INLINE _syscall3(ssize_t, write, int, f,
4283 const void *, b, size_t, c)
4284 LSS_INLINE _syscall3(ssize_t, writev, int, f,
4285 const struct kernel_iovec*, v, size_t, c)
4286 #if defined(__NR_getcpu)
4287 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00004288 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004289 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004290 #if defined(__NR_fadvise64)
4291 #if defined(__x86_64__)
4292 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4293 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
4294 int advice) {
4295 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
4296 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
4297 }
4298 #else
4299 LSS_INLINE _syscall4(int, fadvise64,
4300 int, fd, loff_t, offset, loff_t, len, int, advice)
4301 #endif
4302 #elif defined(__i386__)
4303 #define __NR__fadvise64_64 __NR_fadvise64_64
4304 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
4305 unsigned, offset_lo, unsigned, offset_hi,
4306 unsigned, len_lo, unsigned, len_hi,
4307 int, advice)
4308
4309 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4310 loff_t len, int advice) {
4311 return LSS_NAME(_fadvise64_64)(fd,
4312 (unsigned)offset, (unsigned)(offset >>32),
4313 (unsigned)len, (unsigned)(len >> 32),
4314 advice);
4315 }
4316
4317 #elif defined(__s390__) && !defined(__s390x__)
4318 #define __NR__fadvise64_64 __NR_fadvise64_64
4319 struct kernel_fadvise64_64_args {
4320 int fd;
4321 long long offset;
4322 long long len;
4323 int advice;
4324 };
4325
4326 LSS_INLINE _syscall1(int, _fadvise64_64,
4327 struct kernel_fadvise64_64_args *args)
4328
4329 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4330 loff_t len, int advice) {
4331 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
4332 return LSS_NAME(_fadvise64_64)(&args);
4333 }
4334 #endif
4335 #if defined(__NR_fallocate)
4336 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004337 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4338 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
4339 loff_t len) {
4340 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
4341 (uint64_t)(offset), (uint64_t)(len));
4342 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08004343 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
4344 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
4345 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
4346 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04004347 #define __NR__fallocate __NR_fallocate
4348 LSS_INLINE _syscall6(int, _fallocate, int, fd,
4349 int, mode,
4350 unsigned, offset_lo, unsigned, offset_hi,
4351 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004352
Bryan Chan3f6478a2016-06-14 08:38:17 -04004353 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
4354 loff_t offset, loff_t len) {
4355 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
4356 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
4357 }
4358 #else
4359 LSS_INLINE _syscall4(int, fallocate,
4360 int, f, int, mode, loff_t, offset, loff_t, len)
4361 #endif
4362 #endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07004363 #if defined(__NR_getrandom)
4364 LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length,
4365 unsigned int, flags)
4366 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004367 #if defined(__NR_newfstatat)
4368 LSS_INLINE _syscall4(int, newfstatat, int, d,
4369 const char *, p,
4370 struct kernel_stat*, b, int, f)
4371 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004372 #if defined(__NR_statx)
4373 LSS_INLINE _syscall5(int, statx, int, d,
4374 const char *, p,
4375 int, f, int, m,
4376 struct kernel_statx*, b)
4377 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004378 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004379 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4380 gid_t *egid,
4381 gid_t *sgid) {
4382 return LSS_NAME(getresgid)(rgid, egid, sgid);
4383 }
4384
4385 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4386 uid_t *euid,
4387 uid_t *suid) {
4388 return LSS_NAME(getresuid)(ruid, euid, suid);
4389 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004390
4391 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4392 return LSS_NAME(setfsgid)(gid);
4393 }
4394
4395 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4396 return LSS_NAME(setfsuid)(uid);
4397 }
4398
4399 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4400 return LSS_NAME(setresgid)(rgid, egid, sgid);
4401 }
4402
4403 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4404 return LSS_NAME(setresuid)(ruid, euid, suid);
4405 }
4406
4407 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4408 const struct kernel_sigaction *act,
4409 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04004410 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004411 /* On x86_64, the kernel requires us to always set our own
4412 * SA_RESTORER in order to be able to return from a signal handler.
4413 * This function must have a "magic" signature that the "gdb"
4414 * (and maybe the kernel?) can recognize.
4415 */
4416 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
4417 struct kernel_sigaction a = *act;
4418 a.sa_flags |= SA_RESTORER;
4419 a.sa_restorer = LSS_NAME(restore_rt)();
4420 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
4421 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04004422 } else
4423 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004424 return LSS_NAME(rt_sigaction)(signum, act, oldact,
4425 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004426 }
4427
4428 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4429 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4430 }
4431
Joshua Peraza726d71e2019-11-13 12:21:13 -08004432 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4433 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4434 }
4435 #endif
4436 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004437 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
4438 const struct kernel_sigset_t *set,
4439 struct kernel_sigset_t *oldset) {
4440 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
4441 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08004442 #endif
4443 #if defined(__NR_rt_sigtimedwait)
4444 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
4445 siginfo_t *info,
4446 const struct timespec *timeout) {
4447 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004448 }
4449 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004450 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004451 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
4452 int*, s, int, o,
4453 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004454 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004455 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004456 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004457 #endif
4458 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004459 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
4460 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004461 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4462 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004463 #define __NR__getresgid32 __NR_getresgid32
4464 #define __NR__getresuid32 __NR_getresuid32
4465 #define __NR__setfsgid32 __NR_setfsgid32
4466 #define __NR__setfsuid32 __NR_setfsuid32
4467 #define __NR__setresgid32 __NR_setresgid32
4468 #define __NR__setresuid32 __NR_setresuid32
4469#if defined(__ARM_EABI__)
4470 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
4471 struct kernel_rlimit*, l)
4472#endif
4473 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
4474 gid_t *, e, gid_t *, s)
4475 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
4476 uid_t *, e, uid_t *, s)
4477 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
4478 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
4479 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
4480 gid_t, e, gid_t, s)
4481 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
4482 uid_t, e, uid_t, s)
4483
4484 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4485 gid_t *egid,
4486 gid_t *sgid) {
4487 int rc;
4488 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
4489 LSS_ERRNO == ENOSYS) {
4490 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
4491 return EFAULT;
4492 }
4493 // Clear the high bits first, since getresgid only sets 16 bits
4494 *rgid = *egid = *sgid = 0;
4495 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
4496 }
4497 return rc;
4498 }
4499
4500 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4501 uid_t *euid,
4502 uid_t *suid) {
4503 int rc;
4504 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
4505 LSS_ERRNO == ENOSYS) {
4506 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
4507 return EFAULT;
4508 }
4509 // Clear the high bits first, since getresuid only sets 16 bits
4510 *ruid = *euid = *suid = 0;
4511 rc = LSS_NAME(getresuid)(ruid, euid, suid);
4512 }
4513 return rc;
4514 }
4515
4516 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4517 int rc;
4518 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
4519 LSS_ERRNO == ENOSYS) {
4520 if ((unsigned int)gid & ~0xFFFFu) {
4521 rc = EINVAL;
4522 } else {
4523 rc = LSS_NAME(setfsgid)(gid);
4524 }
4525 }
4526 return rc;
4527 }
4528
4529 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4530 int rc;
4531 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
4532 LSS_ERRNO == ENOSYS) {
4533 if ((unsigned int)uid & ~0xFFFFu) {
4534 rc = EINVAL;
4535 } else {
4536 rc = LSS_NAME(setfsuid)(uid);
4537 }
4538 }
4539 return rc;
4540 }
4541
4542 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4543 int rc;
4544 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
4545 LSS_ERRNO == ENOSYS) {
4546 if ((unsigned int)rgid & ~0xFFFFu ||
4547 (unsigned int)egid & ~0xFFFFu ||
4548 (unsigned int)sgid & ~0xFFFFu) {
4549 rc = EINVAL;
4550 } else {
4551 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
4552 }
4553 }
4554 return rc;
4555 }
4556
4557 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4558 int rc;
4559 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
4560 LSS_ERRNO == ENOSYS) {
4561 if ((unsigned int)ruid & ~0xFFFFu ||
4562 (unsigned int)euid & ~0xFFFFu ||
4563 (unsigned int)suid & ~0xFFFFu) {
4564 rc = EINVAL;
4565 } else {
4566 rc = LSS_NAME(setresuid)(ruid, euid, suid);
4567 }
4568 }
4569 return rc;
4570 }
4571 #endif
4572 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
4573 memset(&set->sig, 0, sizeof(set->sig));
4574 return 0;
4575 }
4576
4577 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
4578 memset(&set->sig, -1, sizeof(set->sig));
4579 return 0;
4580 }
4581
4582 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
4583 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004584 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004585 LSS_ERRNO = EINVAL;
4586 return -1;
4587 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004588 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4589 |= 1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004590 return 0;
4591 }
4592 }
4593
4594 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
4595 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004596 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004597 LSS_ERRNO = EINVAL;
4598 return -1;
4599 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004600 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4601 &= ~(1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004602 return 0;
4603 }
4604 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004605
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004606 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
4607 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004608 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004609 LSS_ERRNO = EINVAL;
4610 return -1;
4611 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004612 return !!(set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] &
4613 (1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004614 }
4615 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04004616 #if defined(__i386__) || \
4617 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4618 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4619 defined(__PPC__) || \
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004620 (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004621 #define __NR__sigaction __NR_sigaction
4622 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004623 #define __NR__sigsuspend __NR_sigsuspend
4624 #define __NR__socketcall __NR_socketcall
4625 LSS_INLINE _syscall2(int, fstat64, int, f,
4626 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00004627 LSS_INLINE _syscall5(int, _llseek, uint, fd,
4628 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004629 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004630#if defined(__s390__) && !defined(__s390x__)
4631 /* On s390, mmap2() arguments are passed in memory. */
4632 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
4633 off_t o) {
4634 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4635 (unsigned long) p, (unsigned long) f,
4636 (unsigned long) d, (unsigned long) o };
4637 LSS_REG(2, buf);
4638 LSS_BODY(void*, mmap2, "0"(__r2));
4639 }
4640#else
4641 #define __NR__mmap2 __NR_mmap2
4642 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004643 size_t, l, int, p,
4644 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04004645 off_t, o)
4646#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004647 LSS_INLINE _syscall3(int, _sigaction, int, s,
4648 const struct kernel_old_sigaction*, a,
4649 struct kernel_old_sigaction*, o)
4650 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004651 #ifdef __PPC__
4652 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
4653 #else
4654 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
4655 int, b,
4656 unsigned long, s)
4657 #endif
4658 LSS_INLINE _syscall2(int, stat64, const char *, p,
4659 struct kernel_stat64 *, b)
4660
4661 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4662 const struct kernel_sigaction *act,
4663 struct kernel_sigaction *oldact) {
4664 int old_errno = LSS_ERRNO;
4665 int rc;
4666 struct kernel_sigaction a;
4667 if (act != NULL) {
4668 a = *act;
4669 #ifdef __i386__
4670 /* On i386, the kernel requires us to always set our own
4671 * SA_RESTORER when using realtime signals. Otherwise, it does not
4672 * know how to return from a signal handler. This function must have
4673 * a "magic" signature that the "gdb" (and maybe the kernel?) can
4674 * recognize.
4675 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
4676 * using non-realtime signals.
4677 *
4678 * TODO: Test whether ARM needs a restorer
4679 */
4680 if (!(a.sa_flags & SA_RESTORER)) {
4681 a.sa_flags |= SA_RESTORER;
4682 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
4683 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
4684 }
4685 #endif
4686 }
4687 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
4688 (KERNEL_NSIG+7)/8);
4689 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4690 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
4691 if (!act) {
4692 ptr_a = NULL;
4693 } else {
4694 oa.sa_handler_ = act->sa_handler_;
4695 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
4696 #ifndef __mips__
4697 oa.sa_restorer = act->sa_restorer;
4698 #endif
4699 oa.sa_flags = act->sa_flags;
4700 }
4701 if (!oldact) {
4702 ptr_oa = NULL;
4703 }
4704 LSS_ERRNO = old_errno;
4705 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
4706 if (rc == 0 && oldact) {
4707 if (act) {
4708 memcpy(oldact, act, sizeof(*act));
4709 } else {
4710 memset(oldact, 0, sizeof(*oldact));
4711 }
4712 oldact->sa_handler_ = ptr_oa->sa_handler_;
4713 oldact->sa_flags = ptr_oa->sa_flags;
4714 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4715 #ifndef __mips__
4716 oldact->sa_restorer = ptr_oa->sa_restorer;
4717 #endif
4718 }
4719 }
4720 return rc;
4721 }
4722
4723 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4724 int old_errno = LSS_ERRNO;
4725 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4726 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4727 LSS_ERRNO = old_errno;
4728 LSS_NAME(sigemptyset)(set);
4729 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4730 }
4731 return rc;
4732 }
4733
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004734 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4735 int olderrno = LSS_ERRNO;
4736 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4737 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4738 LSS_ERRNO = olderrno;
4739 rc = LSS_NAME(_sigsuspend)(
4740 #ifndef __PPC__
4741 set, 0,
4742 #endif
4743 set->sig[0]);
4744 }
4745 return rc;
4746 }
4747 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004748 #if defined(__i386__) || \
4749 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4750 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4751 defined(__PPC__) || \
4752 (defined(__s390__) && !defined(__s390x__))
4753 /* On these architectures, implement mmap() with mmap2(). */
4754 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4755 int64_t o) {
4756 if (o % 4096) {
4757 LSS_ERRNO = EINVAL;
4758 return (void *) -1;
4759 }
4760 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4761 }
4762 #elif defined(__s390x__)
4763 /* On s390x, mmap() arguments are passed in memory. */
4764 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4765 int64_t o) {
4766 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4767 (unsigned long) p, (unsigned long) f,
4768 (unsigned long) d, (unsigned long) o };
4769 LSS_REG(2, buf);
4770 LSS_BODY(void*, mmap, "0"(__r2));
4771 }
4772 #elif defined(__x86_64__)
4773 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4774 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4775 int64_t o) {
4776 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4777 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4778 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4779 }
4780 #else
4781 /* Remaining 64-bit architectures. */
4782 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4783 int, flags, int, fd, int64_t, offset)
4784 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004785 #if defined(__PPC__)
4786 #undef LSS_SC_LOADARGS_0
4787 #define LSS_SC_LOADARGS_0(dummy...)
4788 #undef LSS_SC_LOADARGS_1
4789 #define LSS_SC_LOADARGS_1(arg1) \
4790 __sc_4 = (unsigned long) (arg1)
4791 #undef LSS_SC_LOADARGS_2
4792 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4793 LSS_SC_LOADARGS_1(arg1); \
4794 __sc_5 = (unsigned long) (arg2)
4795 #undef LSS_SC_LOADARGS_3
4796 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4797 LSS_SC_LOADARGS_2(arg1, arg2); \
4798 __sc_6 = (unsigned long) (arg3)
4799 #undef LSS_SC_LOADARGS_4
4800 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4801 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4802 __sc_7 = (unsigned long) (arg4)
4803 #undef LSS_SC_LOADARGS_5
4804 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4805 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4806 __sc_8 = (unsigned long) (arg5)
4807 #undef LSS_SC_BODY
4808 #define LSS_SC_BODY(nr, type, opt, args...) \
4809 long __sc_ret, __sc_err; \
4810 { \
4811 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4812 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4813 register unsigned long __sc_4 __asm__ ("r4"); \
4814 register unsigned long __sc_5 __asm__ ("r5"); \
4815 register unsigned long __sc_6 __asm__ ("r6"); \
4816 register unsigned long __sc_7 __asm__ ("r7"); \
4817 register unsigned long __sc_8 __asm__ ("r8"); \
4818 LSS_SC_LOADARGS_##nr(args); \
4819 __asm__ __volatile__ \
4820 ("stwu 1, -48(1)\n\t" \
4821 "stw 4, 20(1)\n\t" \
4822 "stw 5, 24(1)\n\t" \
4823 "stw 6, 28(1)\n\t" \
4824 "stw 7, 32(1)\n\t" \
4825 "stw 8, 36(1)\n\t" \
4826 "addi 4, 1, 20\n\t" \
4827 "sc\n\t" \
4828 "mfcr %0" \
4829 : "=&r" (__sc_0), \
4830 "=&r" (__sc_3), "=&r" (__sc_4), \
4831 "=&r" (__sc_5), "=&r" (__sc_6), \
4832 "=&r" (__sc_7), "=&r" (__sc_8) \
4833 : LSS_ASMINPUT_##nr \
4834 : "cr0", "ctr", "memory"); \
4835 __sc_ret = __sc_3; \
4836 __sc_err = __sc_0; \
4837 } \
4838 LSS_RETURN(type, __sc_ret, __sc_err)
4839
4840 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4841 int flags){
4842 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4843 }
4844
4845 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4846 const struct kernel_msghdr *msg,
4847 int flags) {
4848 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4849 }
4850
4851 // TODO(csilvers): why is this ifdef'ed out?
4852#if 0
4853 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4854 int flags,
4855 const struct kernel_sockaddr *to,
4856 unsigned int tolen) {
4857 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4858 }
4859#endif
4860
4861 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4862 LSS_SC_BODY(2, int, 13, s, how);
4863 }
4864
4865 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4866 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4867 }
4868
4869 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4870 int sv[2]) {
4871 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4872 }
4873 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004874 #if defined(__NR_recvmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004875 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4876 int, flags)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004877 #endif
4878 #if defined(__NR_sendmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004879 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4880 msg, int, flags)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004881 #endif
4882 #if defined(__NR_sendto)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004883 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4884 int, flags, const struct kernel_sockaddr*, to,
4885 unsigned int, tolen)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004886 #endif
4887 #if defined(__NR_shutdown)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004888 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004889 #endif
4890 #if defined(__NR_socket)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004891 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004892 #endif
4893 #if defined(__NR_socketpair)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004894 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4895 int*, sv)
4896 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004897
4898 #if defined(__NR_socketcall)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004899 LSS_INLINE _syscall2(int, _socketcall, int, c,
4900 va_list, a)
4901 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4902 int rc;
4903 va_list ap;
4904 va_start(ap, op);
4905 rc = LSS_NAME(_socketcall)(op, ap);
4906 va_end(ap);
4907 return rc;
4908 }
4909
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004910 # if !defined(__NR_recvmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004911 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4912 int flags){
4913 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4914 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004915 # endif
4916 # if !defined(__NR_sendmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004917 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4918 const struct kernel_msghdr *msg,
4919 int flags) {
4920 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4921 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004922 # endif
4923 # if !defined(__NR_sendto)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004924 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4925 int flags,
4926 const struct kernel_sockaddr *to,
4927 unsigned int tolen) {
4928 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4929 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004930 # endif
4931 # if !defined(__NR_shutdown)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004932 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4933 return LSS_NAME(socketcall)(13, s, how);
4934 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004935 # endif
4936 # if !defined(__NR_socket)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004937 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4938 return LSS_NAME(socketcall)(1, domain, type, protocol);
4939 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004940 # endif
4941 # if !defined(__NR_socketpair)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004942 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4943 int sv[2]) {
4944 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4945 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004946 # endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004947 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004948 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004949 LSS_INLINE _syscall4(int, fstatat64, int, d,
4950 const char *, p,
4951 struct kernel_stat64 *, b, int, f)
4952 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004953 #if defined(__NR_waitpid)
4954 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004955 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4956 int*, s, int, o)
4957 #endif
4958 #if defined(__mips__)
4959 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4960 * both file handles through CPU registers.
4961 */
4962 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4963 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4964 register unsigned long __v1 __asm__("$3");
4965 register unsigned long __r7 __asm__("$7");
4966 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004967 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004968 : "0"(__v0)
4969 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004970 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004971 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004972 unsigned long __errnovalue = __v0;
4973 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004974 return -1;
4975 } else {
4976 p[0] = __v0;
4977 p[1] = __v1;
4978 return 0;
4979 }
4980 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004981 #elif defined(__NR_pipe)
4982 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004983 LSS_INLINE _syscall1(int, pipe, int *, p)
4984 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004985 #if defined(__NR_pipe2)
4986 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4987 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004988 /* TODO(csilvers): see if ppc can/should support this as well */
4989 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004990 defined(__ARM_EABI__) || \
4991 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4992 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004993 #define __NR__statfs64 __NR_statfs64
4994 #define __NR__fstatfs64 __NR_fstatfs64
4995 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4996 size_t, s,struct kernel_statfs64*, b)
4997 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4998 size_t, s,struct kernel_statfs64*, b)
4999 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
5000 struct kernel_statfs64 *b) {
5001 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
5002 }
5003 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
5004 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
5005 }
5006 #endif
5007
5008 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
5009 extern char **environ;
5010 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
5011 }
5012
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00005013 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005014 pid_t tid = LSS_NAME(_gettid)();
5015 if (tid != -1) {
5016 return tid;
5017 }
5018 return LSS_NAME(getpid)();
5019 }
5020
5021 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
5022 size_t new_size, int flags, ...) {
5023 va_list ap;
5024 void *new_address, *rc;
5025 va_start(ap, flags);
5026 new_address = va_arg(ap, void *);
5027 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
Peter Kasting880985f2022-06-29 21:17:55 +00005028 (unsigned long)flags, new_address);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005029 va_end(ap);
5030 return rc;
5031 }
5032
Peter Kasting880985f2022-06-29 21:17:55 +00005033 LSS_INLINE long LSS_NAME(ptrace_detach)(pid_t pid) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005034 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
5035 * then sends job control signals to the real parent, rather than to
5036 * the tracer. We reduce the risk of this happening by starting a
5037 * whole new time slice, and then quickly sending a SIGCONT signal
5038 * right after detaching from the tracee.
5039 *
5040 * We use tkill to ensure that we only issue a wakeup for the thread being
5041 * detached. Large multi threaded apps can take a long time in the kernel
5042 * processing SIGCONT.
5043 */
Peter Kasting880985f2022-06-29 21:17:55 +00005044 long rc;
5045 int err;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005046 LSS_NAME(sched_yield)();
5047 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
5048 err = LSS_ERRNO;
5049 LSS_NAME(tkill)(pid, SIGCONT);
5050 /* Old systems don't have tkill */
5051 if (LSS_ERRNO == ENOSYS)
5052 LSS_NAME(kill)(pid, SIGCONT);
5053 LSS_ERRNO = err;
5054 return rc;
5055 }
5056
5057 LSS_INLINE int LSS_NAME(raise)(int sig) {
5058 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
5059 }
5060
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00005061 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005062 return LSS_NAME(setpgid)(0, 0);
5063 }
5064
vapier@chromium.org2273e812013-04-01 17:52:44 +00005065 #if defined(__x86_64__)
5066 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
5067 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
5068 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
5069 LSS_SYSCALL_ARG(c), (uint64_t)(o));
5070 }
5071
5072 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
5073 loff_t o) {
5074 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
5075 LSS_SYSCALL_ARG(c), (uint64_t)(o));
5076 }
5077
Peter Kasting3bb68592022-07-18 19:29:31 +00005078 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, size_t c) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00005079 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
5080 LSS_SYSCALL_ARG(c));
5081 }
5082 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005083 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
5084 void *, b, size_t, c,
5085 loff_t, o)
5086 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
5087 const void *, b, size_t, c,
5088 loff_t, o)
5089 LSS_INLINE _syscall3(int, readahead, int, f,
5090 loff_t, o, unsigned, c)
5091 #else
5092 #define __NR__pread64 __NR_pread64
5093 #define __NR__pwrite64 __NR_pwrite64
5094 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00005095 #if defined(__ARM_EABI__) || defined(__mips__)
5096 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
5097 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005098 * fifth and sixth make such a pair (r4,r5).
5099 */
5100 #define LSS_LLARG_PAD 0,
5101 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
5102 void *, b, size_t, c,
5103 unsigned, skip, unsigned, o1, unsigned, o2)
5104 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
5105 const void *, b, size_t, c,
5106 unsigned, skip, unsigned, o1, unsigned, o2)
5107 LSS_INLINE _syscall5(int, _readahead, int, f,
5108 unsigned, skip,
5109 unsigned, o1, unsigned, o2, size_t, c)
5110 #else
5111 #define LSS_LLARG_PAD
5112 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
5113 void *, b, size_t, c, unsigned, o1,
5114 unsigned, o2)
5115 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
5116 const void *, b, size_t, c, unsigned, o1,
Samuel Attardacbdd592022-07-26 16:02:01 +00005117 unsigned, o2)
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005118 LSS_INLINE _syscall4(int, _readahead, int, f,
5119 unsigned, o1, unsigned, o2, size_t, c)
5120 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005121 /* We force 64bit-wide parameters onto the stack, then access each
5122 * 32-bit component individually. This guarantees that we build the
5123 * correct parameters independent of the native byte-order of the
5124 * underlying architecture.
5125 */
5126 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
5127 loff_t off) {
5128 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005129 return LSS_NAME(_pread64)(fd, buf, count,
5130 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005131 }
5132 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
5133 size_t count, loff_t off) {
5134 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005135 return LSS_NAME(_pwrite64)(fd, buf, count,
5136 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005137 }
Peter Kasting3bb68592022-07-18 19:29:31 +00005138 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, size_t count) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005139 union { loff_t off; unsigned arg[2]; } o = { off };
Peter Kasting3bb68592022-07-18 19:29:31 +00005140 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], count);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005141 }
5142 #endif
5143#endif
5144
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005145/*
5146 * Polyfills for deprecated syscalls.
5147 */
5148
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005149#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005150 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
5151 return LSS_NAME(dup3)(s, d, 0);
5152 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005153#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005154
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005155#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005156 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
5157 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
5158 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005159#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005160
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005161#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005162 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
5163 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
5164 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005165#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005166
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005167#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005168 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
5169 size_t size) {
5170 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
5171 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005172#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005173
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005174#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05005175 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005176 return LSS_NAME(pipe2)(pipefd, 0);
5177 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005178#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005179
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005180#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005181 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
5182 int timeout) {
5183 struct kernel_timespec timeout_ts;
5184 struct kernel_timespec *timeout_ts_p = NULL;
5185
5186 if (timeout >= 0) {
5187 timeout_ts.tv_sec = timeout / 1000;
5188 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
5189 timeout_ts_p = &timeout_ts;
5190 }
5191 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
5192 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005193#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005194
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005195#if defined(__NR_statx)
5196 /* copy the contents of kernel_statx to the kernel_stat structure. */
5197 LSS_INLINE void LSS_NAME(cp_stat_statx)(struct kernel_stat *to,
5198 struct kernel_statx *from) {
5199 memset(to, 0, sizeof(struct kernel_stat));
Peter Kasting092a9212022-08-22 20:02:11 +00005200 to->st_dev = (kernel_dev_t)((from->stx_dev_minor & 0xff) |
5201 ((from->stx_dev_major & 0xfff) << 8) |
5202 ((from->stx_dev_minor & ~0xffu) << 12));
5203 to->st_rdev = (kernel_dev_t)((from->stx_rdev_minor & 0xff) |
5204 ((from->stx_rdev_major & 0xfff) << 8) |
5205 ((from->stx_rdev_minor & ~0xffu) << 12));
5206 to->st_ino = (kernel_ino_t)from->stx_ino;
Peter Kastingce877202022-08-23 15:40:54 +00005207 to->st_mode = (kernel_mode_t)from->stx_mode;
Peter Kasting092a9212022-08-22 20:02:11 +00005208 to->st_nlink = (kernel_nlink_t)from->stx_nlink;
5209 to->st_uid = (kernel_uid_t)from->stx_uid;
5210 to->st_gid = (kernel_gid_t)from->stx_gid;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +00005211 to->st_atime_ = (kernel_time_t)(from->stx_atime.tv_sec);
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005212 to->st_atime_nsec_ = from->stx_atime.tv_nsec;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +00005213 to->st_mtime_ = (kernel_time_t)(from->stx_mtime.tv_sec);
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005214 to->st_mtime_nsec_ = from->stx_mtime.tv_nsec;
Peter Kasting7a6e3fd2022-08-22 17:33:00 +00005215 to->st_ctime_ = (kernel_time_t)(from->stx_ctime.tv_sec);
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005216 to->st_ctime_nsec_ = from->stx_ctime.tv_nsec;
Peter Kasting99121a32022-08-22 16:43:44 +00005217 to->st_size = (kernel_off_t)(from->stx_size);
5218 to->st_blocks = (kernel_blkcnt_t)(from->stx_blocks);
Peter Kastingce877202022-08-23 15:40:54 +00005219 to->st_blksize = (kernel_blksize_t)from->stx_blksize;
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005220 }
5221#endif
5222
5223#if !defined(__NR_fstat)
5224 LSS_INLINE int LSS_NAME(fstat)(int fd,
5225 struct kernel_stat *buf) {
5226 #if defined(__NR_newfstatat)
5227 return LSS_NAME(newfstatat)(fd, "", buf, AT_EMPTY_PATH);
5228 #elif defined(__NR_statx)
5229 struct kernel_statx stx;
5230 int flags = AT_NO_AUTOMOUNT | AT_EMPTY_PATH;
5231 int mask = STATX_BASIC_STATS;
5232 int res = LSS_NAME(statx)(fd, "", flags, mask, &stx);
5233 LSS_NAME(cp_stat_statx)(buf, &stx);
5234 return res;
5235 #endif
5236 }
5237#endif
5238
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005239#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005240 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
5241 struct kernel_stat *buf) {
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005242 #if defined(__NR_newfstatat)
5243 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
5244 #elif defined(__NR_statx)
5245 struct kernel_statx stx;
5246 int flags = AT_NO_AUTOMOUNT | AT_STATX_SYNC_AS_STAT;
5247 int mask = STATX_BASIC_STATS;
5248 int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx);
5249 LSS_NAME(cp_stat_statx)(buf, &stx);
5250 return res;
5251 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005252 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005253#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005254
Matthew Denton92a65a82021-04-01 13:00:07 -07005255#if !defined(__NR_lstat)
5256 LSS_INLINE int LSS_NAME(lstat)(const char *pathname,
5257 struct kernel_stat *buf) {
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005258 #if defined(__NR_newfstatat)
5259 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW);
5260 #elif defined(__NR_statx)
5261 struct kernel_statx stx;
5262 int flags = AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW;
5263 int mask = STATX_BASIC_STATS;
5264 int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx);
5265 LSS_NAME(cp_stat_statx)(buf, &stx);
5266 return res;
5267 #endif
Matthew Denton92a65a82021-04-01 13:00:07 -07005268 }
5269#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005270
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005271#if !defined(__NR_waitpid)
5272 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
5273 return LSS_NAME(wait4)(pid, status, options, 0);
5274 }
5275#endif
5276
5277#if !defined(__NR_fork)
5278// TODO: define this in an arch-independant way instead of inlining the clone
5279// syscall body.
5280
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005281# if defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005282 LSS_INLINE pid_t LSS_NAME(fork)(void) {
5283 // No fork syscall on aarch64 - implement by means of the clone syscall.
5284 // Note that this does not reset glibc's cached view of the PID/TID, so
5285 // some glibc interfaces might go wrong in the forked subprocess.
5286 int flags = SIGCHLD;
5287 void *child_stack = NULL;
5288 void *parent_tidptr = NULL;
5289 void *newtls = NULL;
5290 void *child_tidptr = NULL;
5291
5292 LSS_REG(0, flags);
5293 LSS_REG(1, child_stack);
5294 LSS_REG(2, parent_tidptr);
5295 LSS_REG(3, newtls);
5296 LSS_REG(4, child_tidptr);
5297 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
5298 "r"(__r4));
5299 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005300# elif defined(__x86_64__)
5301 LSS_INLINE pid_t LSS_NAME(fork)(void) {
5302 // Android disallows the fork syscall on x86_64 - implement by means of the
5303 // clone syscall as above for aarch64.
5304 int flags = SIGCHLD;
5305 void *child_stack = NULL;
5306 void *parent_tidptr = NULL;
5307 void *newtls = NULL;
5308 void *child_tidptr = NULL;
5309
5310 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
5311 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
5312 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
5313 }
5314# else
5315# error missing fork polyfill for this architecture
5316# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005317#endif
5318
Michael Forneyf70e2f12020-01-22 19:19:38 -08005319/* These restore the original values of these macros saved by the
5320 * corresponding #pragma push_macro near the top of this file. */
5321#pragma pop_macro("stat64")
5322#pragma pop_macro("fstat64")
5323#pragma pop_macro("lstat64")
5324#pragma pop_macro("pread64")
5325#pragma pop_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -07005326#pragma pop_macro("getdents64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00005327
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005328#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
5329}
5330#endif
5331
5332#endif
5333#endif