blob: f73e418c578ec795e1e0ffcdf6c7eade647aa41d [file] [log] [blame]
mcgrathr@google.coma7999932011-11-21 22:26:20 +00001/* Copyright (c) 2005-2011, Google Inc.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * ---
31 * Author: Markus Gutschke
32 */
33
34/* This file includes Linux-specific support functions common to the
35 * coredumper and the thread lister; primarily, this is a collection
36 * of direct system calls, and a couple of symbols missing from
37 * standard header files.
38 * There are a few options that the including file can set to control
39 * the behavior of this file:
40 *
41 * SYS_CPLUSPLUS:
42 * The entire header file will normally be wrapped in 'extern "C" { }",
43 * making it suitable for compilation as both C and C++ source. If you
44 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
45 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
46 * system header files, too. It is the caller's responsibility to provide
47 * the necessary definitions.
48 *
49 * SYS_ERRNO:
50 * All system calls will update "errno" unless overriden by setting the
51 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
52 * an l-value.
53 *
54 * SYS_INLINE:
55 * New symbols will be defined "static inline", unless overridden by
56 * the SYS_INLINE macro.
57 *
58 * SYS_LINUX_SYSCALL_SUPPORT_H
59 * This macro is used to avoid multiple inclusions of this header file.
60 * If you need to include this file more than once, make sure to
61 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
62 *
63 * SYS_PREFIX:
64 * New system calls will have a prefix of "sys_" unless overridden by
65 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
66 * results in prefixes "sys[0..9]_". It is also possible to set this
67 * macro to -1, which avoids all prefixes.
68 *
69 * SYS_SYSCALL_ENTRYPOINT:
70 * Some applications (such as sandboxes that filter system calls), need
71 * to be able to run custom-code each time a system call is made. If this
72 * macro is defined, it expands to the name of a "common" symbol. If
73 * this symbol is assigned a non-NULL pointer value, it is used as the
74 * address of the system call entrypoint.
75 * A pointer to this symbol can be obtained by calling
76 * get_syscall_entrypoint()
77 *
78 * This file defines a few internal symbols that all start with "LSS_".
79 * Do not access these symbols from outside this file. They are not part
80 * of the supported API.
81 */
82#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
83#define SYS_LINUX_SYSCALL_SUPPORT_H
84
Bryan Chan3f6478a2016-06-14 08:38:17 -040085/* We currently only support x86-32, x86-64, ARM, MIPS, PPC, s390 and s390x
86 * on Linux.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000087 * Porting to other related platforms should not be difficult.
88 */
89#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
anton@chromium.org2f724fc2014-04-15 13:05:20 +000090 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \
Andreas Schwab1d387f42022-02-15 16:21:13 +010091 defined(__aarch64__) || defined(__s390__) || defined(__e2k__) || \
92 (defined(__riscv) && __riscv_xlen == 64)) \
zodiac@gmail.com4f470182010-10-13 03:47:54 +000093 && (defined(__linux) || defined(__ANDROID__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000094
95#ifndef SYS_CPLUSPLUS
96#ifdef __cplusplus
97/* Some system header files in older versions of gcc neglect to properly
98 * handle being included from C++. As it appears to be harmless to have
99 * multiple nested 'extern "C"' blocks, just add another one here.
100 */
101extern "C" {
102#endif
103
104#include <errno.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000105#include <fcntl.h>
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000106#include <sched.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000107#include <signal.h>
108#include <stdarg.h>
109#include <stddef.h>
vapier@chromium.org2273e812013-04-01 17:52:44 +0000110#include <stdint.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000111#include <string.h>
112#include <sys/ptrace.h>
113#include <sys/resource.h>
114#include <sys/time.h>
115#include <sys/types.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000116#include <sys/syscall.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000117#include <unistd.h>
118#include <linux/unistd.h>
119#include <endian.h>
120
121#ifdef __mips__
122/* Include definitions of the ABI currently in use. */
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000123#ifdef __ANDROID__
124/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h,
125 * which has the definitions we need.
126 */
127#include <asm/sgidefs.h>
128#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000129#include <sgidefs.h>
130#endif
131#endif
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000132#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000133
Michael Forneyf70e2f12020-01-22 19:19:38 -0800134/* Some libcs, for example Android NDK and musl, #define these
135 * macros as aliases to their non-64 counterparts. To avoid naming
136 * conflict, remove them.
137 *
138 * These are restored by the corresponding #pragma pop_macro near
139 * the end of this file.
140 */
141#pragma push_macro("stat64")
142#pragma push_macro("fstat64")
143#pragma push_macro("lstat64")
144#pragma push_macro("pread64")
145#pragma push_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700146#pragma push_macro("getdents64")
Michael Forneyf70e2f12020-01-22 19:19:38 -0800147#undef stat64
148#undef fstat64
149#undef lstat64
150#undef pread64
151#undef pwrite64
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700152#undef getdents64
mseaborn@chromium.orgca749372012-09-05 18:26:20 +0000153
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400154#if defined(__ANDROID__) && defined(__x86_64__)
155// A number of x86_64 syscalls are blocked by seccomp on recent Android;
156// undefine them so that modern alternatives will be used instead where
157// possible.
158// The alternative syscalls have been sanity checked against linux-3.4+;
159// older versions might not work.
160# undef __NR_getdents
161# undef __NR_dup2
162# undef __NR_fork
163# undef __NR_getpgrp
164# undef __NR_open
165# undef __NR_poll
166# undef __NR_readlink
167# undef __NR_stat
168# undef __NR_unlink
169# undef __NR_pipe
170#endif
171
172#if defined(__ANDROID__)
173// waitpid is blocked by seccomp on all architectures on recent Android.
174# undef __NR_waitpid
175#endif
176
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000177/* As glibc often provides subtly incompatible data structures (and implicit
178 * wrapper functions that convert them), we provide our own kernel data
179 * structures for use by the system calls.
180 * These structures have been developed by using Linux 2.6.23 headers for
181 * reference. Note though, we do not care about exact API compatibility
182 * with the kernel, and in fact the kernel often does not have a single
183 * API that works across architectures. Instead, we try to mimic the glibc
184 * API where reasonable, and only guarantee ABI compatibility with the
185 * kernel headers.
186 * Most notably, here are a few changes that were made to the structures
187 * defined by kernel headers:
188 *
189 * - we only define structures, but not symbolic names for kernel data
190 * types. For the latter, we directly use the native C datatype
191 * (i.e. "unsigned" instead of "mode_t").
192 * - in a few cases, it is possible to define identical structures for
193 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
194 * standardizing on the 64bit version of the data types. In particular,
195 * this means that we use "unsigned" where the 32bit headers say
196 * "unsigned long".
197 * - overall, we try to minimize the number of cases where we need to
198 * conditionally define different structures.
199 * - the "struct kernel_sigaction" class of structures have been
200 * modified to more closely mimic glibc's API by introducing an
201 * anonymous union for the function pointer.
202 * - a small number of field names had to have an underscore appended to
203 * them, because glibc defines a global macro by the same name.
204 */
205
206/* include/linux/dirent.h */
207struct kernel_dirent64 {
208 unsigned long long d_ino;
209 long long d_off;
210 unsigned short d_reclen;
211 unsigned char d_type;
212 char d_name[256];
213};
214
215/* include/linux/dirent.h */
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400216#if !defined(__NR_getdents)
217// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000218#define kernel_dirent kernel_dirent64
219#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000220struct kernel_dirent {
221 long d_ino;
222 long d_off;
223 unsigned short d_reclen;
224 char d_name[256];
225};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000226#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000227
228/* include/linux/uio.h */
229struct kernel_iovec {
230 void *iov_base;
231 unsigned long iov_len;
232};
233
234/* include/linux/socket.h */
235struct kernel_msghdr {
236 void *msg_name;
237 int msg_namelen;
238 struct kernel_iovec*msg_iov;
239 unsigned long msg_iovlen;
240 void *msg_control;
241 unsigned long msg_controllen;
242 unsigned msg_flags;
243};
244
245/* include/asm-generic/poll.h */
246struct kernel_pollfd {
247 int fd;
248 short events;
249 short revents;
250};
251
252/* include/linux/resource.h */
253struct kernel_rlimit {
254 unsigned long rlim_cur;
255 unsigned long rlim_max;
256};
257
258/* include/linux/time.h */
259struct kernel_timespec {
260 long tv_sec;
261 long tv_nsec;
262};
263
264/* include/linux/time.h */
265struct kernel_timeval {
266 long tv_sec;
267 long tv_usec;
268};
269
270/* include/linux/resource.h */
271struct kernel_rusage {
272 struct kernel_timeval ru_utime;
273 struct kernel_timeval ru_stime;
274 long ru_maxrss;
275 long ru_ixrss;
276 long ru_idrss;
277 long ru_isrss;
278 long ru_minflt;
279 long ru_majflt;
280 long ru_nswap;
281 long ru_inblock;
282 long ru_oublock;
283 long ru_msgsnd;
284 long ru_msgrcv;
285 long ru_nsignals;
286 long ru_nvcsw;
287 long ru_nivcsw;
288};
289
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000290#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300291 || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) \
292 || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000293
294/* include/asm-{arm,i386,mips,ppc}/signal.h */
295struct kernel_old_sigaction {
296 union {
297 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000298 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000299 };
300 unsigned long sa_mask;
301 unsigned long sa_flags;
302 void (*sa_restorer)(void);
303} __attribute__((packed,aligned(4)));
304#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
305 #define kernel_old_sigaction kernel_sigaction
Andreas Schwab1d387f42022-02-15 16:21:13 +0100306#elif defined(__aarch64__) || defined(__riscv)
307 // No kernel_old_sigaction defined for arm64 or riscv.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000308#endif
309
310/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
311 * exactly match the size of the signal set, even though the API was
312 * intended to be extensible. We define our own KERNEL_NSIG to deal with
313 * this.
314 * Please note that glibc provides signals [1.._NSIG-1], whereas the
315 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
316 * actual number of signals is obviously the same, but the constants
317 * differ by one.
318 */
319#ifdef __mips__
320#define KERNEL_NSIG 128
321#else
322#define KERNEL_NSIG 64
323#endif
324
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000325/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000326struct kernel_sigset_t {
327 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
328 (8*sizeof(unsigned long))];
329};
330
331/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
332struct kernel_sigaction {
333#ifdef __mips__
334 unsigned long sa_flags;
335 union {
336 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000337 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000338 };
339 struct kernel_sigset_t sa_mask;
340#else
341 union {
342 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000343 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000344 };
345 unsigned long sa_flags;
Andreas Schwab1d387f42022-02-15 16:21:13 +0100346#ifndef __riscv
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000347 void (*sa_restorer)(void);
Andreas Schwab1d387f42022-02-15 16:21:13 +0100348#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000349 struct kernel_sigset_t sa_mask;
350#endif
351};
352
353/* include/linux/socket.h */
354struct kernel_sockaddr {
355 unsigned short sa_family;
356 char sa_data[14];
357};
358
Bryan Chan3f6478a2016-06-14 08:38:17 -0400359/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000360#ifdef __mips__
361#if _MIPS_SIM == _MIPS_SIM_ABI64
362struct kernel_stat {
363#else
364struct kernel_stat64 {
365#endif
366 unsigned st_dev;
367 unsigned __pad0[3];
368 unsigned long long st_ino;
369 unsigned st_mode;
370 unsigned st_nlink;
371 unsigned st_uid;
372 unsigned st_gid;
373 unsigned st_rdev;
374 unsigned __pad1[3];
375 long long st_size;
376 unsigned st_atime_;
377 unsigned st_atime_nsec_;
378 unsigned st_mtime_;
379 unsigned st_mtime_nsec_;
380 unsigned st_ctime_;
381 unsigned st_ctime_nsec_;
382 unsigned st_blksize;
383 unsigned __pad2;
384 unsigned long long st_blocks;
385};
386#elif defined __PPC__
387struct kernel_stat64 {
388 unsigned long long st_dev;
389 unsigned long long st_ino;
390 unsigned st_mode;
391 unsigned st_nlink;
392 unsigned st_uid;
393 unsigned st_gid;
394 unsigned long long st_rdev;
395 unsigned short int __pad2;
396 long long st_size;
397 long st_blksize;
398 long long st_blocks;
399 long st_atime_;
400 unsigned long st_atime_nsec_;
401 long st_mtime_;
402 unsigned long st_mtime_nsec_;
403 long st_ctime_;
404 unsigned long st_ctime_nsec_;
405 unsigned long __unused4;
406 unsigned long __unused5;
407};
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300408#elif defined(__e2k__)
409struct kernel_stat64 {
410 unsigned long long st_dev;
411 unsigned long long st_ino;
412 unsigned int st_mode;
413 unsigned int st_nlink;
414 unsigned int st_uid;
415 unsigned int st_gid;
416 unsigned long long st_rdev;
417 long long st_size;
418 int st_blksize;
419 int __pad2;
420 unsigned long long st_blocks;
421 int st_atime_;
422 unsigned int st_atime_nsec_;
423 int st_mtime_;
424 unsigned int st_mtime_nsec_;
425 int st_ctime_;
426 unsigned int st_ctime_nsec_;
427 unsigned int __unused4;
428 unsigned int __unused5;
429};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000430#else
431struct kernel_stat64 {
432 unsigned long long st_dev;
433 unsigned char __pad0[4];
434 unsigned __st_ino;
435 unsigned st_mode;
436 unsigned st_nlink;
437 unsigned st_uid;
438 unsigned st_gid;
439 unsigned long long st_rdev;
440 unsigned char __pad3[4];
441 long long st_size;
442 unsigned st_blksize;
443 unsigned long long st_blocks;
444 unsigned st_atime_;
445 unsigned st_atime_nsec_;
446 unsigned st_mtime_;
447 unsigned st_mtime_nsec_;
448 unsigned st_ctime_;
449 unsigned st_ctime_nsec_;
450 unsigned long long st_ino;
451};
452#endif
453
Bryan Chan3f6478a2016-06-14 08:38:17 -0400454/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000455#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
456struct kernel_stat {
457 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
458 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
459 * format. In reality, we do not see useful data in the top bits. So,
460 * we'll leave the padding in here, until we find a better solution.
461 */
462 unsigned short st_dev;
463 short pad1;
464 unsigned st_ino;
465 unsigned short st_mode;
466 unsigned short st_nlink;
467 unsigned short st_uid;
468 unsigned short st_gid;
469 unsigned short st_rdev;
470 short pad2;
471 unsigned st_size;
472 unsigned st_blksize;
473 unsigned st_blocks;
474 unsigned st_atime_;
475 unsigned st_atime_nsec_;
476 unsigned st_mtime_;
477 unsigned st_mtime_nsec_;
478 unsigned st_ctime_;
479 unsigned st_ctime_nsec_;
480 unsigned __unused4;
481 unsigned __unused5;
482};
483#elif defined(__x86_64__)
484struct kernel_stat {
vapier@chromium.org2273e812013-04-01 17:52:44 +0000485 uint64_t st_dev;
486 uint64_t st_ino;
487 uint64_t st_nlink;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000488 unsigned st_mode;
489 unsigned st_uid;
490 unsigned st_gid;
491 unsigned __pad0;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000492 uint64_t st_rdev;
493 int64_t st_size;
494 int64_t st_blksize;
495 int64_t st_blocks;
496 uint64_t st_atime_;
497 uint64_t st_atime_nsec_;
498 uint64_t st_mtime_;
499 uint64_t st_mtime_nsec_;
500 uint64_t st_ctime_;
501 uint64_t st_ctime_nsec_;
anton@chromium.org43de0522014-04-04 11:20:46 +0000502 int64_t __unused4[3];
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000503};
504#elif defined(__PPC__)
505struct kernel_stat {
506 unsigned st_dev;
507 unsigned long st_ino; // ino_t
508 unsigned long st_mode; // mode_t
509 unsigned short st_nlink; // nlink_t
510 unsigned st_uid; // uid_t
511 unsigned st_gid; // gid_t
512 unsigned st_rdev;
513 long st_size; // off_t
514 unsigned long st_blksize;
515 unsigned long st_blocks;
516 unsigned long st_atime_;
517 unsigned long st_atime_nsec_;
518 unsigned long st_mtime_;
519 unsigned long st_mtime_nsec_;
520 unsigned long st_ctime_;
521 unsigned long st_ctime_nsec_;
522 unsigned long __unused4;
523 unsigned long __unused5;
524};
525#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
526struct kernel_stat {
527 unsigned st_dev;
528 int st_pad1[3];
529 unsigned st_ino;
530 unsigned st_mode;
531 unsigned st_nlink;
532 unsigned st_uid;
533 unsigned st_gid;
534 unsigned st_rdev;
535 int st_pad2[2];
536 long st_size;
537 int st_pad3;
538 long st_atime_;
539 long st_atime_nsec_;
540 long st_mtime_;
541 long st_mtime_nsec_;
542 long st_ctime_;
543 long st_ctime_nsec_;
544 int st_blksize;
545 int st_blocks;
546 int st_pad4[14];
547};
Andreas Schwab1d387f42022-02-15 16:21:13 +0100548#elif defined(__aarch64__) || defined(__riscv)
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000549struct kernel_stat {
550 unsigned long st_dev;
551 unsigned long st_ino;
552 unsigned int st_mode;
553 unsigned int st_nlink;
554 unsigned int st_uid;
555 unsigned int st_gid;
556 unsigned long st_rdev;
557 unsigned long __pad1;
558 long st_size;
559 int st_blksize;
560 int __pad2;
561 long st_blocks;
562 long st_atime_;
563 unsigned long st_atime_nsec_;
564 long st_mtime_;
565 unsigned long st_mtime_nsec_;
566 long st_ctime_;
567 unsigned long st_ctime_nsec_;
568 unsigned int __unused4;
569 unsigned int __unused5;
570};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400571#elif defined(__s390x__)
572struct kernel_stat {
573 unsigned long st_dev;
574 unsigned long st_ino;
575 unsigned long st_nlink;
576 unsigned int st_mode;
577 unsigned int st_uid;
578 unsigned int st_gid;
579 unsigned int __pad1;
580 unsigned long st_rdev;
581 unsigned long st_size;
582 unsigned long st_atime_;
583 unsigned long st_atime_nsec_;
584 unsigned long st_mtime_;
585 unsigned long st_mtime_nsec_;
586 unsigned long st_ctime_;
587 unsigned long st_ctime_nsec_;
588 unsigned long st_blksize;
589 long st_blocks;
590 unsigned long __unused[3];
591};
592#elif defined(__s390__)
593struct kernel_stat {
594 unsigned short st_dev;
595 unsigned short __pad1;
596 unsigned long st_ino;
597 unsigned short st_mode;
598 unsigned short st_nlink;
599 unsigned short st_uid;
600 unsigned short st_gid;
601 unsigned short st_rdev;
602 unsigned short __pad2;
603 unsigned long st_size;
604 unsigned long st_blksize;
605 unsigned long st_blocks;
606 unsigned long st_atime_;
607 unsigned long st_atime_nsec_;
608 unsigned long st_mtime_;
609 unsigned long st_mtime_nsec_;
610 unsigned long st_ctime_;
611 unsigned long st_ctime_nsec_;
612 unsigned long __unused4;
613 unsigned long __unused5;
614};
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300615#elif defined(__e2k__)
616struct kernel_stat {
617 unsigned long st_dev;
618 unsigned long st_ino;
619 unsigned int st_mode;
620 unsigned long st_nlink;
621 unsigned int st_uid;
622 unsigned int st_gid;
623 unsigned long st_rdev;
624 unsigned long st_size;
625 unsigned long st_blksize;
626 unsigned long st_blocks;
627 unsigned long st_atime_;
628 unsigned long st_atime_nsec_;
629 unsigned long st_mtime_;
630 unsigned long st_mtime_nsec_;
631 unsigned long st_ctime_;
632 unsigned long st_ctime_nsec_;
633};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000634#endif
635
Bryan Chan3f6478a2016-06-14 08:38:17 -0400636/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000637#ifdef __mips__
638#if _MIPS_SIM != _MIPS_SIM_ABI64
639struct kernel_statfs64 {
640 unsigned long f_type;
641 unsigned long f_bsize;
642 unsigned long f_frsize;
643 unsigned long __pad;
644 unsigned long long f_blocks;
645 unsigned long long f_bfree;
646 unsigned long long f_files;
647 unsigned long long f_ffree;
648 unsigned long long f_bavail;
649 struct { int val[2]; } f_fsid;
650 unsigned long f_namelen;
651 unsigned long f_spare[6];
652};
653#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -0400654#elif defined(__s390__)
655/* See also arch/s390/include/asm/compat.h */
656struct kernel_statfs64 {
657 unsigned int f_type;
658 unsigned int f_bsize;
659 unsigned long long f_blocks;
660 unsigned long long f_bfree;
661 unsigned long long f_bavail;
662 unsigned long long f_files;
663 unsigned long long f_ffree;
664 struct { int val[2]; } f_fsid;
665 unsigned int f_namelen;
666 unsigned int f_frsize;
667 unsigned int f_flags;
668 unsigned int f_spare[4];
669};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000670#elif !defined(__x86_64__)
671struct kernel_statfs64 {
672 unsigned long f_type;
673 unsigned long f_bsize;
674 unsigned long long f_blocks;
675 unsigned long long f_bfree;
676 unsigned long long f_bavail;
677 unsigned long long f_files;
678 unsigned long long f_ffree;
679 struct { int val[2]; } f_fsid;
680 unsigned long f_namelen;
681 unsigned long f_frsize;
682 unsigned long f_spare[5];
683};
684#endif
685
Bryan Chan3f6478a2016-06-14 08:38:17 -0400686/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000687#ifdef __mips__
688struct kernel_statfs {
689 long f_type;
690 long f_bsize;
691 long f_frsize;
692 long f_blocks;
693 long f_bfree;
694 long f_files;
695 long f_ffree;
696 long f_bavail;
697 struct { int val[2]; } f_fsid;
698 long f_namelen;
699 long f_spare[6];
700};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000701#elif defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000702struct kernel_statfs {
703 /* x86_64 actually defines all these fields as signed, whereas all other */
704 /* platforms define them as unsigned. Leaving them at unsigned should not */
vapier@chromium.org2273e812013-04-01 17:52:44 +0000705 /* cause any problems. Make sure these are 64-bit even on x32. */
706 uint64_t f_type;
707 uint64_t f_bsize;
708 uint64_t f_blocks;
709 uint64_t f_bfree;
710 uint64_t f_bavail;
711 uint64_t f_files;
712 uint64_t f_ffree;
713 struct { int val[2]; } f_fsid;
714 uint64_t f_namelen;
715 uint64_t f_frsize;
716 uint64_t f_spare[5];
717};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400718#elif defined(__s390__)
719struct kernel_statfs {
720 unsigned int f_type;
721 unsigned int f_bsize;
722 unsigned long f_blocks;
723 unsigned long f_bfree;
724 unsigned long f_bavail;
725 unsigned long f_files;
726 unsigned long f_ffree;
727 struct { int val[2]; } f_fsid;
728 unsigned int f_namelen;
729 unsigned int f_frsize;
730 unsigned int f_flags;
731 unsigned int f_spare[4];
732};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000733#else
734struct kernel_statfs {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000735 unsigned long f_type;
736 unsigned long f_bsize;
737 unsigned long f_blocks;
738 unsigned long f_bfree;
739 unsigned long f_bavail;
740 unsigned long f_files;
741 unsigned long f_ffree;
742 struct { int val[2]; } f_fsid;
743 unsigned long f_namelen;
744 unsigned long f_frsize;
745 unsigned long f_spare[5];
746};
747#endif
748
749
750/* Definitions missing from the standard header files */
751#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000752#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000753#define O_DIRECTORY 0040000
754#else
755#define O_DIRECTORY 0200000
756#endif
757#endif
758#ifndef NT_PRXFPREG
759#define NT_PRXFPREG 0x46e62b7f
760#endif
761#ifndef PTRACE_GETFPXREGS
762#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
763#endif
764#ifndef PR_GET_DUMPABLE
765#define PR_GET_DUMPABLE 3
766#endif
767#ifndef PR_SET_DUMPABLE
768#define PR_SET_DUMPABLE 4
769#endif
770#ifndef PR_GET_SECCOMP
771#define PR_GET_SECCOMP 21
772#endif
773#ifndef PR_SET_SECCOMP
774#define PR_SET_SECCOMP 22
775#endif
776#ifndef AT_FDCWD
777#define AT_FDCWD (-100)
778#endif
779#ifndef AT_SYMLINK_NOFOLLOW
780#define AT_SYMLINK_NOFOLLOW 0x100
781#endif
782#ifndef AT_REMOVEDIR
783#define AT_REMOVEDIR 0x200
784#endif
785#ifndef MREMAP_FIXED
786#define MREMAP_FIXED 2
787#endif
788#ifndef SA_RESTORER
789#define SA_RESTORER 0x04000000
790#endif
791#ifndef CPUCLOCK_PROF
792#define CPUCLOCK_PROF 0
793#endif
794#ifndef CPUCLOCK_VIRT
795#define CPUCLOCK_VIRT 1
796#endif
797#ifndef CPUCLOCK_SCHED
798#define CPUCLOCK_SCHED 2
799#endif
800#ifndef CPUCLOCK_PERTHREAD_MASK
801#define CPUCLOCK_PERTHREAD_MASK 4
802#endif
803#ifndef MAKE_PROCESS_CPUCLOCK
804#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400805 ((int)(~(unsigned)(pid) << 3) | (int)(clock))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000806#endif
807#ifndef MAKE_THREAD_CPUCLOCK
808#define MAKE_THREAD_CPUCLOCK(tid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400809 ((int)(~(unsigned)(tid) << 3) | \
810 (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000811#endif
812
813#ifndef FUTEX_WAIT
814#define FUTEX_WAIT 0
815#endif
816#ifndef FUTEX_WAKE
817#define FUTEX_WAKE 1
818#endif
819#ifndef FUTEX_FD
820#define FUTEX_FD 2
821#endif
822#ifndef FUTEX_REQUEUE
823#define FUTEX_REQUEUE 3
824#endif
825#ifndef FUTEX_CMP_REQUEUE
826#define FUTEX_CMP_REQUEUE 4
827#endif
828#ifndef FUTEX_WAKE_OP
829#define FUTEX_WAKE_OP 5
830#endif
831#ifndef FUTEX_LOCK_PI
832#define FUTEX_LOCK_PI 6
833#endif
834#ifndef FUTEX_UNLOCK_PI
835#define FUTEX_UNLOCK_PI 7
836#endif
837#ifndef FUTEX_TRYLOCK_PI
838#define FUTEX_TRYLOCK_PI 8
839#endif
840#ifndef FUTEX_PRIVATE_FLAG
841#define FUTEX_PRIVATE_FLAG 128
842#endif
843#ifndef FUTEX_CMD_MASK
844#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
845#endif
846#ifndef FUTEX_WAIT_PRIVATE
847#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
848#endif
849#ifndef FUTEX_WAKE_PRIVATE
850#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
851#endif
852#ifndef FUTEX_REQUEUE_PRIVATE
853#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
854#endif
855#ifndef FUTEX_CMP_REQUEUE_PRIVATE
856#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
857#endif
858#ifndef FUTEX_WAKE_OP_PRIVATE
859#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
860#endif
861#ifndef FUTEX_LOCK_PI_PRIVATE
862#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
863#endif
864#ifndef FUTEX_UNLOCK_PI_PRIVATE
865#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
866#endif
867#ifndef FUTEX_TRYLOCK_PI_PRIVATE
868#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
869#endif
870
871
872#if defined(__x86_64__)
873#ifndef ARCH_SET_GS
874#define ARCH_SET_GS 0x1001
875#endif
876#ifndef ARCH_GET_GS
877#define ARCH_GET_GS 0x1004
878#endif
879#endif
880
881#if defined(__i386__)
882#ifndef __NR_quotactl
883#define __NR_quotactl 131
884#endif
885#ifndef __NR_setresuid
886#define __NR_setresuid 164
887#define __NR_getresuid 165
888#define __NR_setresgid 170
889#define __NR_getresgid 171
890#endif
891#ifndef __NR_rt_sigaction
892#define __NR_rt_sigreturn 173
893#define __NR_rt_sigaction 174
894#define __NR_rt_sigprocmask 175
895#define __NR_rt_sigpending 176
896#define __NR_rt_sigsuspend 179
897#endif
898#ifndef __NR_pread64
899#define __NR_pread64 180
900#endif
901#ifndef __NR_pwrite64
902#define __NR_pwrite64 181
903#endif
904#ifndef __NR_ugetrlimit
905#define __NR_ugetrlimit 191
906#endif
907#ifndef __NR_stat64
908#define __NR_stat64 195
909#endif
910#ifndef __NR_fstat64
911#define __NR_fstat64 197
912#endif
913#ifndef __NR_setresuid32
914#define __NR_setresuid32 208
915#define __NR_getresuid32 209
916#define __NR_setresgid32 210
917#define __NR_getresgid32 211
918#endif
919#ifndef __NR_setfsuid32
920#define __NR_setfsuid32 215
921#define __NR_setfsgid32 216
922#endif
923#ifndef __NR_getdents64
924#define __NR_getdents64 220
925#endif
926#ifndef __NR_gettid
927#define __NR_gettid 224
928#endif
929#ifndef __NR_readahead
930#define __NR_readahead 225
931#endif
932#ifndef __NR_setxattr
933#define __NR_setxattr 226
934#endif
935#ifndef __NR_lsetxattr
936#define __NR_lsetxattr 227
937#endif
938#ifndef __NR_getxattr
939#define __NR_getxattr 229
940#endif
941#ifndef __NR_lgetxattr
942#define __NR_lgetxattr 230
943#endif
944#ifndef __NR_listxattr
945#define __NR_listxattr 232
946#endif
947#ifndef __NR_llistxattr
948#define __NR_llistxattr 233
949#endif
950#ifndef __NR_tkill
951#define __NR_tkill 238
952#endif
953#ifndef __NR_futex
954#define __NR_futex 240
955#endif
956#ifndef __NR_sched_setaffinity
957#define __NR_sched_setaffinity 241
958#define __NR_sched_getaffinity 242
959#endif
960#ifndef __NR_set_tid_address
961#define __NR_set_tid_address 258
962#endif
963#ifndef __NR_clock_gettime
964#define __NR_clock_gettime 265
965#endif
966#ifndef __NR_clock_getres
967#define __NR_clock_getres 266
968#endif
969#ifndef __NR_statfs64
970#define __NR_statfs64 268
971#endif
972#ifndef __NR_fstatfs64
973#define __NR_fstatfs64 269
974#endif
975#ifndef __NR_fadvise64_64
976#define __NR_fadvise64_64 272
977#endif
978#ifndef __NR_ioprio_set
979#define __NR_ioprio_set 289
980#endif
981#ifndef __NR_ioprio_get
982#define __NR_ioprio_get 290
983#endif
984#ifndef __NR_openat
985#define __NR_openat 295
986#endif
987#ifndef __NR_fstatat64
988#define __NR_fstatat64 300
989#endif
990#ifndef __NR_unlinkat
991#define __NR_unlinkat 301
992#endif
993#ifndef __NR_move_pages
994#define __NR_move_pages 317
995#endif
996#ifndef __NR_getcpu
997#define __NR_getcpu 318
998#endif
999#ifndef __NR_fallocate
1000#define __NR_fallocate 324
1001#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001002#ifndef __NR_getrandom
1003#define __NR_getrandom 355
1004#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001005/* End of i386 definitions */
1006#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
1007#ifndef __NR_setresuid
1008#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
1009#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
1010#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
1011#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
1012#endif
1013#ifndef __NR_rt_sigaction
1014#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
1015#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
1016#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
1017#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
1018#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
1019#endif
1020#ifndef __NR_pread64
1021#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
1022#endif
1023#ifndef __NR_pwrite64
1024#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
1025#endif
1026#ifndef __NR_ugetrlimit
1027#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
1028#endif
1029#ifndef __NR_stat64
1030#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
1031#endif
1032#ifndef __NR_fstat64
1033#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
1034#endif
1035#ifndef __NR_setresuid32
1036#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
1037#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
1038#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
1039#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
1040#endif
1041#ifndef __NR_setfsuid32
1042#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
1043#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
1044#endif
1045#ifndef __NR_getdents64
1046#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
1047#endif
1048#ifndef __NR_gettid
1049#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1050#endif
1051#ifndef __NR_readahead
1052#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1053#endif
1054#ifndef __NR_setxattr
1055#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1056#endif
1057#ifndef __NR_lsetxattr
1058#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1059#endif
1060#ifndef __NR_getxattr
1061#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1062#endif
1063#ifndef __NR_lgetxattr
1064#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1065#endif
1066#ifndef __NR_listxattr
1067#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1068#endif
1069#ifndef __NR_llistxattr
1070#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1071#endif
1072#ifndef __NR_tkill
1073#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1074#endif
1075#ifndef __NR_futex
1076#define __NR_futex (__NR_SYSCALL_BASE + 240)
1077#endif
1078#ifndef __NR_sched_setaffinity
1079#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1080#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1081#endif
1082#ifndef __NR_set_tid_address
1083#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1084#endif
1085#ifndef __NR_clock_gettime
1086#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1087#endif
1088#ifndef __NR_clock_getres
1089#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1090#endif
1091#ifndef __NR_statfs64
1092#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1093#endif
1094#ifndef __NR_fstatfs64
1095#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1096#endif
1097#ifndef __NR_ioprio_set
1098#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1099#endif
1100#ifndef __NR_ioprio_get
1101#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1102#endif
Matthew Denton92a65a82021-04-01 13:00:07 -07001103#ifndef __NR_fstatat64
1104#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
1105#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001106#ifndef __NR_move_pages
1107#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1108#endif
1109#ifndef __NR_getcpu
1110#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1111#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001112#ifndef __NR_getrandom
1113#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
1114#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001115/* End of ARM 3/EABI definitions */
Andreas Schwab1d387f42022-02-15 16:21:13 +01001116#elif defined(__aarch64__) || defined(__riscv)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001117#ifndef __NR_setxattr
1118#define __NR_setxattr 5
1119#endif
1120#ifndef __NR_lsetxattr
1121#define __NR_lsetxattr 6
1122#endif
1123#ifndef __NR_getxattr
1124#define __NR_getxattr 8
1125#endif
1126#ifndef __NR_lgetxattr
1127#define __NR_lgetxattr 9
1128#endif
1129#ifndef __NR_listxattr
1130#define __NR_listxattr 11
1131#endif
1132#ifndef __NR_llistxattr
1133#define __NR_llistxattr 12
1134#endif
1135#ifndef __NR_ioprio_set
1136#define __NR_ioprio_set 30
1137#endif
1138#ifndef __NR_ioprio_get
1139#define __NR_ioprio_get 31
1140#endif
1141#ifndef __NR_unlinkat
1142#define __NR_unlinkat 35
1143#endif
1144#ifndef __NR_fallocate
1145#define __NR_fallocate 47
1146#endif
1147#ifndef __NR_openat
1148#define __NR_openat 56
1149#endif
1150#ifndef __NR_quotactl
1151#define __NR_quotactl 60
1152#endif
1153#ifndef __NR_getdents64
1154#define __NR_getdents64 61
1155#endif
1156#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001157// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001158#define __NR_getdents __NR_getdents64
1159#endif
1160#ifndef __NR_pread64
1161#define __NR_pread64 67
1162#endif
1163#ifndef __NR_pwrite64
1164#define __NR_pwrite64 68
1165#endif
1166#ifndef __NR_ppoll
1167#define __NR_ppoll 73
1168#endif
1169#ifndef __NR_readlinkat
1170#define __NR_readlinkat 78
1171#endif
1172#ifndef __NR_newfstatat
1173#define __NR_newfstatat 79
1174#endif
1175#ifndef __NR_set_tid_address
1176#define __NR_set_tid_address 96
1177#endif
1178#ifndef __NR_futex
1179#define __NR_futex 98
1180#endif
1181#ifndef __NR_clock_gettime
1182#define __NR_clock_gettime 113
1183#endif
1184#ifndef __NR_clock_getres
1185#define __NR_clock_getres 114
1186#endif
1187#ifndef __NR_sched_setaffinity
1188#define __NR_sched_setaffinity 122
1189#define __NR_sched_getaffinity 123
1190#endif
1191#ifndef __NR_tkill
1192#define __NR_tkill 130
1193#endif
1194#ifndef __NR_setresuid
1195#define __NR_setresuid 147
1196#define __NR_getresuid 148
1197#define __NR_setresgid 149
1198#define __NR_getresgid 150
1199#endif
1200#ifndef __NR_gettid
1201#define __NR_gettid 178
1202#endif
1203#ifndef __NR_readahead
1204#define __NR_readahead 213
1205#endif
1206#ifndef __NR_fadvise64
1207#define __NR_fadvise64 223
1208#endif
1209#ifndef __NR_move_pages
1210#define __NR_move_pages 239
1211#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001212#ifndef __NR_getrandom
1213#define __NR_getrandom 278
1214#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001215/* End of aarch64 definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001216#elif defined(__x86_64__)
1217#ifndef __NR_pread64
1218#define __NR_pread64 17
1219#endif
1220#ifndef __NR_pwrite64
1221#define __NR_pwrite64 18
1222#endif
1223#ifndef __NR_setresuid
1224#define __NR_setresuid 117
1225#define __NR_getresuid 118
1226#define __NR_setresgid 119
1227#define __NR_getresgid 120
1228#endif
1229#ifndef __NR_quotactl
1230#define __NR_quotactl 179
1231#endif
1232#ifndef __NR_gettid
1233#define __NR_gettid 186
1234#endif
1235#ifndef __NR_readahead
1236#define __NR_readahead 187
1237#endif
1238#ifndef __NR_setxattr
1239#define __NR_setxattr 188
1240#endif
1241#ifndef __NR_lsetxattr
1242#define __NR_lsetxattr 189
1243#endif
1244#ifndef __NR_getxattr
1245#define __NR_getxattr 191
1246#endif
1247#ifndef __NR_lgetxattr
1248#define __NR_lgetxattr 192
1249#endif
1250#ifndef __NR_listxattr
1251#define __NR_listxattr 194
1252#endif
1253#ifndef __NR_llistxattr
1254#define __NR_llistxattr 195
1255#endif
1256#ifndef __NR_tkill
1257#define __NR_tkill 200
1258#endif
1259#ifndef __NR_futex
1260#define __NR_futex 202
1261#endif
1262#ifndef __NR_sched_setaffinity
1263#define __NR_sched_setaffinity 203
1264#define __NR_sched_getaffinity 204
1265#endif
1266#ifndef __NR_getdents64
1267#define __NR_getdents64 217
1268#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001269#ifndef __NR_getdents
1270// when getdents is not available, getdents64 is used for both.
1271#define __NR_getdents __NR_getdents64
1272#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001273#ifndef __NR_set_tid_address
1274#define __NR_set_tid_address 218
1275#endif
1276#ifndef __NR_fadvise64
1277#define __NR_fadvise64 221
1278#endif
1279#ifndef __NR_clock_gettime
1280#define __NR_clock_gettime 228
1281#endif
1282#ifndef __NR_clock_getres
1283#define __NR_clock_getres 229
1284#endif
1285#ifndef __NR_ioprio_set
1286#define __NR_ioprio_set 251
1287#endif
1288#ifndef __NR_ioprio_get
1289#define __NR_ioprio_get 252
1290#endif
1291#ifndef __NR_openat
1292#define __NR_openat 257
1293#endif
1294#ifndef __NR_newfstatat
1295#define __NR_newfstatat 262
1296#endif
1297#ifndef __NR_unlinkat
1298#define __NR_unlinkat 263
1299#endif
1300#ifndef __NR_move_pages
1301#define __NR_move_pages 279
1302#endif
1303#ifndef __NR_fallocate
1304#define __NR_fallocate 285
1305#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001306#ifndef __NR_getrandom
1307#define __NR_getrandom 318
1308#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001309/* End of x86-64 definitions */
1310#elif defined(__mips__)
1311#if _MIPS_SIM == _MIPS_SIM_ABI32
1312#ifndef __NR_setresuid
1313#define __NR_setresuid (__NR_Linux + 185)
1314#define __NR_getresuid (__NR_Linux + 186)
1315#define __NR_setresgid (__NR_Linux + 190)
1316#define __NR_getresgid (__NR_Linux + 191)
1317#endif
1318#ifndef __NR_rt_sigaction
1319#define __NR_rt_sigreturn (__NR_Linux + 193)
1320#define __NR_rt_sigaction (__NR_Linux + 194)
1321#define __NR_rt_sigprocmask (__NR_Linux + 195)
1322#define __NR_rt_sigpending (__NR_Linux + 196)
1323#define __NR_rt_sigsuspend (__NR_Linux + 199)
1324#endif
1325#ifndef __NR_pread64
1326#define __NR_pread64 (__NR_Linux + 200)
1327#endif
1328#ifndef __NR_pwrite64
1329#define __NR_pwrite64 (__NR_Linux + 201)
1330#endif
1331#ifndef __NR_stat64
1332#define __NR_stat64 (__NR_Linux + 213)
1333#endif
1334#ifndef __NR_fstat64
1335#define __NR_fstat64 (__NR_Linux + 215)
1336#endif
1337#ifndef __NR_getdents64
1338#define __NR_getdents64 (__NR_Linux + 219)
1339#endif
1340#ifndef __NR_gettid
1341#define __NR_gettid (__NR_Linux + 222)
1342#endif
1343#ifndef __NR_readahead
1344#define __NR_readahead (__NR_Linux + 223)
1345#endif
1346#ifndef __NR_setxattr
1347#define __NR_setxattr (__NR_Linux + 224)
1348#endif
1349#ifndef __NR_lsetxattr
1350#define __NR_lsetxattr (__NR_Linux + 225)
1351#endif
1352#ifndef __NR_getxattr
1353#define __NR_getxattr (__NR_Linux + 227)
1354#endif
1355#ifndef __NR_lgetxattr
1356#define __NR_lgetxattr (__NR_Linux + 228)
1357#endif
1358#ifndef __NR_listxattr
1359#define __NR_listxattr (__NR_Linux + 230)
1360#endif
1361#ifndef __NR_llistxattr
1362#define __NR_llistxattr (__NR_Linux + 231)
1363#endif
1364#ifndef __NR_tkill
1365#define __NR_tkill (__NR_Linux + 236)
1366#endif
1367#ifndef __NR_futex
1368#define __NR_futex (__NR_Linux + 238)
1369#endif
1370#ifndef __NR_sched_setaffinity
1371#define __NR_sched_setaffinity (__NR_Linux + 239)
1372#define __NR_sched_getaffinity (__NR_Linux + 240)
1373#endif
1374#ifndef __NR_set_tid_address
1375#define __NR_set_tid_address (__NR_Linux + 252)
1376#endif
1377#ifndef __NR_statfs64
1378#define __NR_statfs64 (__NR_Linux + 255)
1379#endif
1380#ifndef __NR_fstatfs64
1381#define __NR_fstatfs64 (__NR_Linux + 256)
1382#endif
1383#ifndef __NR_clock_gettime
1384#define __NR_clock_gettime (__NR_Linux + 263)
1385#endif
1386#ifndef __NR_clock_getres
1387#define __NR_clock_getres (__NR_Linux + 264)
1388#endif
1389#ifndef __NR_openat
1390#define __NR_openat (__NR_Linux + 288)
1391#endif
1392#ifndef __NR_fstatat
1393#define __NR_fstatat (__NR_Linux + 293)
1394#endif
1395#ifndef __NR_unlinkat
1396#define __NR_unlinkat (__NR_Linux + 294)
1397#endif
1398#ifndef __NR_move_pages
1399#define __NR_move_pages (__NR_Linux + 308)
1400#endif
1401#ifndef __NR_getcpu
1402#define __NR_getcpu (__NR_Linux + 312)
1403#endif
1404#ifndef __NR_ioprio_set
1405#define __NR_ioprio_set (__NR_Linux + 314)
1406#endif
1407#ifndef __NR_ioprio_get
1408#define __NR_ioprio_get (__NR_Linux + 315)
1409#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001410#ifndef __NR_getrandom
1411#define __NR_getrandom (__NR_Linux + 353)
1412#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001413/* End of MIPS (old 32bit API) definitions */
1414#elif _MIPS_SIM == _MIPS_SIM_ABI64
1415#ifndef __NR_pread64
1416#define __NR_pread64 (__NR_Linux + 16)
1417#endif
1418#ifndef __NR_pwrite64
1419#define __NR_pwrite64 (__NR_Linux + 17)
1420#endif
1421#ifndef __NR_setresuid
1422#define __NR_setresuid (__NR_Linux + 115)
1423#define __NR_getresuid (__NR_Linux + 116)
1424#define __NR_setresgid (__NR_Linux + 117)
1425#define __NR_getresgid (__NR_Linux + 118)
1426#endif
1427#ifndef __NR_gettid
1428#define __NR_gettid (__NR_Linux + 178)
1429#endif
1430#ifndef __NR_readahead
1431#define __NR_readahead (__NR_Linux + 179)
1432#endif
1433#ifndef __NR_setxattr
1434#define __NR_setxattr (__NR_Linux + 180)
1435#endif
1436#ifndef __NR_lsetxattr
1437#define __NR_lsetxattr (__NR_Linux + 181)
1438#endif
1439#ifndef __NR_getxattr
1440#define __NR_getxattr (__NR_Linux + 183)
1441#endif
1442#ifndef __NR_lgetxattr
1443#define __NR_lgetxattr (__NR_Linux + 184)
1444#endif
1445#ifndef __NR_listxattr
1446#define __NR_listxattr (__NR_Linux + 186)
1447#endif
1448#ifndef __NR_llistxattr
1449#define __NR_llistxattr (__NR_Linux + 187)
1450#endif
1451#ifndef __NR_tkill
1452#define __NR_tkill (__NR_Linux + 192)
1453#endif
1454#ifndef __NR_futex
1455#define __NR_futex (__NR_Linux + 194)
1456#endif
1457#ifndef __NR_sched_setaffinity
1458#define __NR_sched_setaffinity (__NR_Linux + 195)
1459#define __NR_sched_getaffinity (__NR_Linux + 196)
1460#endif
1461#ifndef __NR_set_tid_address
1462#define __NR_set_tid_address (__NR_Linux + 212)
1463#endif
1464#ifndef __NR_clock_gettime
1465#define __NR_clock_gettime (__NR_Linux + 222)
1466#endif
1467#ifndef __NR_clock_getres
1468#define __NR_clock_getres (__NR_Linux + 223)
1469#endif
1470#ifndef __NR_openat
1471#define __NR_openat (__NR_Linux + 247)
1472#endif
1473#ifndef __NR_fstatat
1474#define __NR_fstatat (__NR_Linux + 252)
1475#endif
1476#ifndef __NR_unlinkat
1477#define __NR_unlinkat (__NR_Linux + 253)
1478#endif
1479#ifndef __NR_move_pages
1480#define __NR_move_pages (__NR_Linux + 267)
1481#endif
1482#ifndef __NR_getcpu
1483#define __NR_getcpu (__NR_Linux + 271)
1484#endif
1485#ifndef __NR_ioprio_set
1486#define __NR_ioprio_set (__NR_Linux + 273)
1487#endif
1488#ifndef __NR_ioprio_get
1489#define __NR_ioprio_get (__NR_Linux + 274)
1490#endif
Yu Yind9ad2962020-11-24 16:49:22 +08001491#ifndef __NR_getrandom
1492#define __NR_getrandom (__NR_Linux + 313)
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001493#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001494/* End of MIPS (64bit API) definitions */
1495#else
1496#ifndef __NR_setresuid
1497#define __NR_setresuid (__NR_Linux + 115)
1498#define __NR_getresuid (__NR_Linux + 116)
1499#define __NR_setresgid (__NR_Linux + 117)
1500#define __NR_getresgid (__NR_Linux + 118)
1501#endif
1502#ifndef __NR_gettid
1503#define __NR_gettid (__NR_Linux + 178)
1504#endif
1505#ifndef __NR_readahead
1506#define __NR_readahead (__NR_Linux + 179)
1507#endif
1508#ifndef __NR_setxattr
1509#define __NR_setxattr (__NR_Linux + 180)
1510#endif
1511#ifndef __NR_lsetxattr
1512#define __NR_lsetxattr (__NR_Linux + 181)
1513#endif
1514#ifndef __NR_getxattr
1515#define __NR_getxattr (__NR_Linux + 183)
1516#endif
1517#ifndef __NR_lgetxattr
1518#define __NR_lgetxattr (__NR_Linux + 184)
1519#endif
1520#ifndef __NR_listxattr
1521#define __NR_listxattr (__NR_Linux + 186)
1522#endif
1523#ifndef __NR_llistxattr
1524#define __NR_llistxattr (__NR_Linux + 187)
1525#endif
1526#ifndef __NR_tkill
1527#define __NR_tkill (__NR_Linux + 192)
1528#endif
1529#ifndef __NR_futex
1530#define __NR_futex (__NR_Linux + 194)
1531#endif
1532#ifndef __NR_sched_setaffinity
1533#define __NR_sched_setaffinity (__NR_Linux + 195)
1534#define __NR_sched_getaffinity (__NR_Linux + 196)
1535#endif
1536#ifndef __NR_set_tid_address
1537#define __NR_set_tid_address (__NR_Linux + 213)
1538#endif
1539#ifndef __NR_statfs64
1540#define __NR_statfs64 (__NR_Linux + 217)
1541#endif
1542#ifndef __NR_fstatfs64
1543#define __NR_fstatfs64 (__NR_Linux + 218)
1544#endif
1545#ifndef __NR_clock_gettime
1546#define __NR_clock_gettime (__NR_Linux + 226)
1547#endif
1548#ifndef __NR_clock_getres
1549#define __NR_clock_getres (__NR_Linux + 227)
1550#endif
1551#ifndef __NR_openat
1552#define __NR_openat (__NR_Linux + 251)
1553#endif
1554#ifndef __NR_fstatat
1555#define __NR_fstatat (__NR_Linux + 256)
1556#endif
1557#ifndef __NR_unlinkat
1558#define __NR_unlinkat (__NR_Linux + 257)
1559#endif
1560#ifndef __NR_move_pages
1561#define __NR_move_pages (__NR_Linux + 271)
1562#endif
1563#ifndef __NR_getcpu
1564#define __NR_getcpu (__NR_Linux + 275)
1565#endif
1566#ifndef __NR_ioprio_set
1567#define __NR_ioprio_set (__NR_Linux + 277)
1568#endif
1569#ifndef __NR_ioprio_get
1570#define __NR_ioprio_get (__NR_Linux + 278)
1571#endif
1572/* End of MIPS (new 32bit API) definitions */
1573#endif
1574/* End of MIPS definitions */
1575#elif defined(__PPC__)
1576#ifndef __NR_setfsuid
1577#define __NR_setfsuid 138
1578#define __NR_setfsgid 139
1579#endif
1580#ifndef __NR_setresuid
1581#define __NR_setresuid 164
1582#define __NR_getresuid 165
1583#define __NR_setresgid 169
1584#define __NR_getresgid 170
1585#endif
1586#ifndef __NR_rt_sigaction
1587#define __NR_rt_sigreturn 172
1588#define __NR_rt_sigaction 173
1589#define __NR_rt_sigprocmask 174
1590#define __NR_rt_sigpending 175
1591#define __NR_rt_sigsuspend 178
1592#endif
1593#ifndef __NR_pread64
1594#define __NR_pread64 179
1595#endif
1596#ifndef __NR_pwrite64
1597#define __NR_pwrite64 180
1598#endif
1599#ifndef __NR_ugetrlimit
1600#define __NR_ugetrlimit 190
1601#endif
1602#ifndef __NR_readahead
1603#define __NR_readahead 191
1604#endif
1605#ifndef __NR_stat64
1606#define __NR_stat64 195
1607#endif
1608#ifndef __NR_fstat64
1609#define __NR_fstat64 197
1610#endif
1611#ifndef __NR_getdents64
1612#define __NR_getdents64 202
1613#endif
1614#ifndef __NR_gettid
1615#define __NR_gettid 207
1616#endif
1617#ifndef __NR_tkill
1618#define __NR_tkill 208
1619#endif
1620#ifndef __NR_setxattr
1621#define __NR_setxattr 209
1622#endif
1623#ifndef __NR_lsetxattr
1624#define __NR_lsetxattr 210
1625#endif
1626#ifndef __NR_getxattr
1627#define __NR_getxattr 212
1628#endif
1629#ifndef __NR_lgetxattr
1630#define __NR_lgetxattr 213
1631#endif
1632#ifndef __NR_listxattr
1633#define __NR_listxattr 215
1634#endif
1635#ifndef __NR_llistxattr
1636#define __NR_llistxattr 216
1637#endif
1638#ifndef __NR_futex
1639#define __NR_futex 221
1640#endif
1641#ifndef __NR_sched_setaffinity
1642#define __NR_sched_setaffinity 222
1643#define __NR_sched_getaffinity 223
1644#endif
1645#ifndef __NR_set_tid_address
1646#define __NR_set_tid_address 232
1647#endif
1648#ifndef __NR_clock_gettime
1649#define __NR_clock_gettime 246
1650#endif
1651#ifndef __NR_clock_getres
1652#define __NR_clock_getres 247
1653#endif
1654#ifndef __NR_statfs64
1655#define __NR_statfs64 252
1656#endif
1657#ifndef __NR_fstatfs64
1658#define __NR_fstatfs64 253
1659#endif
1660#ifndef __NR_fadvise64_64
1661#define __NR_fadvise64_64 254
1662#endif
1663#ifndef __NR_ioprio_set
1664#define __NR_ioprio_set 273
1665#endif
1666#ifndef __NR_ioprio_get
1667#define __NR_ioprio_get 274
1668#endif
1669#ifndef __NR_openat
1670#define __NR_openat 286
1671#endif
1672#ifndef __NR_fstatat64
1673#define __NR_fstatat64 291
1674#endif
1675#ifndef __NR_unlinkat
1676#define __NR_unlinkat 292
1677#endif
1678#ifndef __NR_move_pages
1679#define __NR_move_pages 301
1680#endif
1681#ifndef __NR_getcpu
1682#define __NR_getcpu 302
1683#endif
1684/* End of powerpc defininitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001685#elif defined(__s390__)
1686#ifndef __NR_quotactl
1687#define __NR_quotactl 131
1688#endif
1689#ifndef __NR_rt_sigreturn
1690#define __NR_rt_sigreturn 173
1691#endif
1692#ifndef __NR_rt_sigaction
1693#define __NR_rt_sigaction 174
1694#endif
1695#ifndef __NR_rt_sigprocmask
1696#define __NR_rt_sigprocmask 175
1697#endif
1698#ifndef __NR_rt_sigpending
1699#define __NR_rt_sigpending 176
1700#endif
1701#ifndef __NR_rt_sigsuspend
1702#define __NR_rt_sigsuspend 179
1703#endif
1704#ifndef __NR_pread64
1705#define __NR_pread64 180
1706#endif
1707#ifndef __NR_pwrite64
1708#define __NR_pwrite64 181
1709#endif
1710#ifndef __NR_getdents64
1711#define __NR_getdents64 220
1712#endif
1713#ifndef __NR_readahead
1714#define __NR_readahead 222
1715#endif
1716#ifndef __NR_setxattr
1717#define __NR_setxattr 224
1718#endif
1719#ifndef __NR_lsetxattr
1720#define __NR_lsetxattr 225
1721#endif
1722#ifndef __NR_getxattr
1723#define __NR_getxattr 227
1724#endif
1725#ifndef __NR_lgetxattr
1726#define __NR_lgetxattr 228
1727#endif
1728#ifndef __NR_listxattr
1729#define __NR_listxattr 230
1730#endif
1731#ifndef __NR_llistxattr
1732#define __NR_llistxattr 231
1733#endif
1734#ifndef __NR_gettid
1735#define __NR_gettid 236
1736#endif
1737#ifndef __NR_tkill
1738#define __NR_tkill 237
1739#endif
1740#ifndef __NR_futex
1741#define __NR_futex 238
1742#endif
1743#ifndef __NR_sched_setaffinity
1744#define __NR_sched_setaffinity 239
1745#endif
1746#ifndef __NR_sched_getaffinity
1747#define __NR_sched_getaffinity 240
1748#endif
1749#ifndef __NR_set_tid_address
1750#define __NR_set_tid_address 252
1751#endif
1752#ifndef __NR_clock_gettime
1753#define __NR_clock_gettime 260
1754#endif
1755#ifndef __NR_clock_getres
1756#define __NR_clock_getres 261
1757#endif
1758#ifndef __NR_statfs64
1759#define __NR_statfs64 265
1760#endif
1761#ifndef __NR_fstatfs64
1762#define __NR_fstatfs64 266
1763#endif
1764#ifndef __NR_ioprio_set
1765#define __NR_ioprio_set 282
1766#endif
1767#ifndef __NR_ioprio_get
1768#define __NR_ioprio_get 283
1769#endif
1770#ifndef __NR_openat
1771#define __NR_openat 288
1772#endif
1773#ifndef __NR_unlinkat
1774#define __NR_unlinkat 294
1775#endif
1776#ifndef __NR_move_pages
1777#define __NR_move_pages 310
1778#endif
1779#ifndef __NR_getcpu
1780#define __NR_getcpu 311
1781#endif
1782#ifndef __NR_fallocate
1783#define __NR_fallocate 314
1784#endif
1785/* Some syscalls are named/numbered differently between s390 and s390x. */
1786#ifdef __s390x__
1787# ifndef __NR_getrlimit
1788# define __NR_getrlimit 191
1789# endif
1790# ifndef __NR_setresuid
1791# define __NR_setresuid 208
1792# endif
1793# ifndef __NR_getresuid
1794# define __NR_getresuid 209
1795# endif
1796# ifndef __NR_setresgid
1797# define __NR_setresgid 210
1798# endif
1799# ifndef __NR_getresgid
1800# define __NR_getresgid 211
1801# endif
1802# ifndef __NR_setfsuid
1803# define __NR_setfsuid 215
1804# endif
1805# ifndef __NR_setfsgid
1806# define __NR_setfsgid 216
1807# endif
1808# ifndef __NR_fadvise64
1809# define __NR_fadvise64 253
1810# endif
1811# ifndef __NR_newfstatat
1812# define __NR_newfstatat 293
1813# endif
1814#else /* __s390x__ */
1815# ifndef __NR_getrlimit
1816# define __NR_getrlimit 76
1817# endif
1818# ifndef __NR_setfsuid
1819# define __NR_setfsuid 138
1820# endif
1821# ifndef __NR_setfsgid
1822# define __NR_setfsgid 139
1823# endif
1824# ifndef __NR_setresuid
1825# define __NR_setresuid 164
1826# endif
1827# ifndef __NR_getresuid
1828# define __NR_getresuid 165
1829# endif
1830# ifndef __NR_setresgid
1831# define __NR_setresgid 170
1832# endif
1833# ifndef __NR_getresgid
1834# define __NR_getresgid 171
1835# endif
1836# ifndef __NR_ugetrlimit
1837# define __NR_ugetrlimit 191
1838# endif
1839# ifndef __NR_mmap2
1840# define __NR_mmap2 192
1841# endif
1842# ifndef __NR_setresuid32
1843# define __NR_setresuid32 208
1844# endif
1845# ifndef __NR_getresuid32
1846# define __NR_getresuid32 209
1847# endif
1848# ifndef __NR_setresgid32
1849# define __NR_setresgid32 210
1850# endif
1851# ifndef __NR_getresgid32
1852# define __NR_getresgid32 211
1853# endif
1854# ifndef __NR_setfsuid32
1855# define __NR_setfsuid32 215
1856# endif
1857# ifndef __NR_setfsgid32
1858# define __NR_setfsgid32 216
1859# endif
1860# ifndef __NR_fadvise64_64
1861# define __NR_fadvise64_64 264
1862# endif
1863# ifndef __NR_fstatat64
1864# define __NR_fstatat64 293
1865# endif
1866#endif /* __s390__ */
1867/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001868#endif
1869
1870
1871/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001872#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001873 #error "Need to port invocations of syscalls for bounded ptrs"
1874#else
1875 /* The core dumper and the thread lister get executed after threads
1876 * have been suspended. As a consequence, we cannot call any functions
1877 * that acquire locks. Unfortunately, libc wraps most system calls
1878 * (e.g. in order to implement pthread_atfork, and to make calls
1879 * cancellable), which means we cannot call these functions. Instead,
1880 * we have to call syscall() directly.
1881 */
1882 #undef LSS_ERRNO
1883 #ifdef SYS_ERRNO
1884 /* Allow the including file to override the location of errno. This can
1885 * be useful when using clone() with the CLONE_VM option.
1886 */
1887 #define LSS_ERRNO SYS_ERRNO
1888 #else
1889 #define LSS_ERRNO errno
1890 #endif
1891
1892 #undef LSS_INLINE
1893 #ifdef SYS_INLINE
1894 #define LSS_INLINE SYS_INLINE
1895 #else
1896 #define LSS_INLINE static inline
1897 #endif
1898
1899 /* Allow the including file to override the prefix used for all new
1900 * system calls. By default, it will be set to "sys_".
1901 */
1902 #undef LSS_NAME
1903 #ifndef SYS_PREFIX
1904 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001905 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001906 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001907 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001908 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001909 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001910 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001911 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001912 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001913 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001914 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001915 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001916 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001917 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001918 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001919 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001920 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001921 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001922 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001923 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001924 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001925 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001926 #define LSS_NAME(name) sys9_##name
1927 #endif
1928
1929 #undef LSS_RETURN
Askar Safine1e7b0a2021-04-12 14:03:02 +03001930 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
1931 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \
Andreas Schwab1d387f42022-02-15 16:21:13 +01001932 || defined(__e2k__) || defined(__riscv)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001933 /* Failing system calls return a negative result in the range of
1934 * -1..-4095. These are "errno" values with the sign inverted.
1935 */
1936 #define LSS_RETURN(type, res) \
1937 do { \
1938 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
1939 LSS_ERRNO = -(res); \
1940 res = -1; \
1941 } \
1942 return (type) (res); \
1943 } while (0)
1944 #elif defined(__mips__)
1945 /* On MIPS, failing system calls return -1, and set errno in a
1946 * separate CPU register.
1947 */
1948 #define LSS_RETURN(type, res, err) \
1949 do { \
1950 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00001951 unsigned long __errnovalue = (res); \
1952 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001953 res = -1; \
1954 } \
1955 return (type) (res); \
1956 } while (0)
1957 #elif defined(__PPC__)
1958 /* On PPC, failing system calls return -1, and set errno in a
1959 * separate CPU register. See linux/unistd.h.
1960 */
1961 #define LSS_RETURN(type, res, err) \
1962 do { \
1963 if (err & 0x10000000 ) { \
1964 LSS_ERRNO = (res); \
1965 res = -1; \
1966 } \
1967 return (type) (res); \
1968 } while (0)
1969 #endif
1970 #if defined(__i386__)
1971 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1972 * reserves ebx. Unfortunately, most distribution ship with implementations
1973 * of _syscallX() which clobber ebx.
1974 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1975 * clobbered. This causes problems with compilers, that do a better job
1976 * at optimizing across __asm__ calls.
1977 * So, we just have to redefine all of the _syscallX() macros.
1978 */
1979 #undef LSS_ENTRYPOINT
1980 #ifdef SYS_SYSCALL_ENTRYPOINT
1981 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1982 void (**entrypoint)(void);
1983 asm volatile(".bss\n"
1984 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001985 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1986 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001987 ".previous\n"
1988 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
1989 "call 0f\n"
1990 "0:pop %0\n"
1991 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001992 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001993 : "=r"(entrypoint));
1994 return entrypoint;
1995 }
1996
1997 #define LSS_ENTRYPOINT ".bss\n" \
1998 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001999 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2000 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002001 ".previous\n" \
2002 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
2003 "push %%eax\n" \
2004 "call 10000f\n" \
2005 "10000:pop %%eax\n" \
2006 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002007 "mov " SYS_SYSCALL_ENTRYPOINT \
2008 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002009 "mov 0(%%eax), %%eax\n" \
2010 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002011 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002012 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002013 "call 10001f\n" \
2014 "10001:pop %%eax\n" \
2015 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002016 "xchg 4(%%esp), %%eax\n" \
2017 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002018 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002019 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002020 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002021 #else
2022 #define LSS_ENTRYPOINT "int $0x80\n"
2023 #endif
2024 #undef LSS_BODY
2025 #define LSS_BODY(type,args...) \
2026 long __res; \
2027 __asm__ __volatile__("push %%ebx\n" \
2028 "movl %2,%%ebx\n" \
2029 LSS_ENTRYPOINT \
2030 "pop %%ebx" \
2031 args \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002032 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002033 LSS_RETURN(type,__res)
2034 #undef _syscall0
2035 #define _syscall0(type,name) \
2036 type LSS_NAME(name)(void) { \
2037 long __res; \
2038 __asm__ volatile(LSS_ENTRYPOINT \
2039 : "=a" (__res) \
2040 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08002041 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002042 LSS_RETURN(type,__res); \
2043 }
2044 #undef _syscall1
2045 #define _syscall1(type,name,type1,arg1) \
2046 type LSS_NAME(name)(type1 arg1) { \
2047 LSS_BODY(type, \
2048 : "=a" (__res) \
2049 : "0" (__NR_##name), "ri" ((long)(arg1))); \
2050 }
2051 #undef _syscall2
2052 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2053 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
2054 LSS_BODY(type, \
2055 : "=a" (__res) \
2056 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
2057 }
2058 #undef _syscall3
2059 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2060 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
2061 LSS_BODY(type, \
2062 : "=a" (__res) \
2063 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2064 "d" ((long)(arg3))); \
2065 }
2066 #undef _syscall4
2067 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2068 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2069 LSS_BODY(type, \
2070 : "=a" (__res) \
2071 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2072 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2073 }
2074 #undef _syscall5
2075 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2076 type5,arg5) \
2077 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2078 type5 arg5) { \
2079 long __res; \
2080 __asm__ __volatile__("push %%ebx\n" \
2081 "movl %2,%%ebx\n" \
2082 "movl %1,%%eax\n" \
2083 LSS_ENTRYPOINT \
2084 "pop %%ebx" \
2085 : "=a" (__res) \
2086 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2087 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2088 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002089 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002090 LSS_RETURN(type,__res); \
2091 }
2092 #undef _syscall6
2093 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2094 type5,arg5,type6,arg6) \
2095 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2096 type5 arg5, type6 arg6) { \
2097 long __res; \
2098 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2099 __asm__ __volatile__("push %%ebp\n" \
2100 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002101 "movl 4(%2),%%ebp\n" \
2102 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002103 "movl %1,%%eax\n" \
2104 LSS_ENTRYPOINT \
2105 "pop %%ebx\n" \
2106 "pop %%ebp" \
2107 : "=a" (__res) \
2108 : "i" (__NR_##name), "0" ((long)(&__s)), \
2109 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2110 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002111 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002112 LSS_RETURN(type,__res); \
2113 }
2114 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2115 int flags, void *arg, int *parent_tidptr,
2116 void *newtls, int *child_tidptr) {
2117 long __res;
2118 __asm__ __volatile__(/* if (fn == NULL)
2119 * return -EINVAL;
2120 */
2121 "movl %3,%%ecx\n"
2122 "jecxz 1f\n"
2123
2124 /* if (child_stack == NULL)
2125 * return -EINVAL;
2126 */
2127 "movl %4,%%ecx\n"
2128 "jecxz 1f\n"
2129
2130 /* Set up alignment of the child stack:
2131 * child_stack = (child_stack & ~0xF) - 20;
2132 */
2133 "andl $-16,%%ecx\n"
2134 "subl $20,%%ecx\n"
2135
2136 /* Push "arg" and "fn" onto the stack that will be
2137 * used by the child.
2138 */
2139 "movl %6,%%eax\n"
2140 "movl %%eax,4(%%ecx)\n"
2141 "movl %3,%%eax\n"
2142 "movl %%eax,(%%ecx)\n"
2143
2144 /* %eax = syscall(%eax = __NR_clone,
2145 * %ebx = flags,
2146 * %ecx = child_stack,
2147 * %edx = parent_tidptr,
2148 * %esi = newtls,
2149 * %edi = child_tidptr)
2150 * Also, make sure that %ebx gets preserved as it is
2151 * used in PIC mode.
2152 */
2153 "movl %8,%%esi\n"
2154 "movl %7,%%edx\n"
2155 "movl %5,%%eax\n"
2156 "movl %9,%%edi\n"
2157 "pushl %%ebx\n"
2158 "movl %%eax,%%ebx\n"
2159 "movl %2,%%eax\n"
2160 LSS_ENTRYPOINT
2161
2162 /* In the parent: restore %ebx
2163 * In the child: move "fn" into %ebx
2164 */
2165 "popl %%ebx\n"
2166
2167 /* if (%eax != 0)
2168 * return %eax;
2169 */
2170 "test %%eax,%%eax\n"
2171 "jnz 1f\n"
2172
2173 /* In the child, now. Terminate frame pointer chain.
2174 */
2175 "movl $0,%%ebp\n"
2176
2177 /* Call "fn". "arg" is already on the stack.
2178 */
2179 "call *%%ebx\n"
2180
2181 /* Call _exit(%ebx). Unfortunately older versions
2182 * of gcc restrict the number of arguments that can
2183 * be passed to asm(). So, we need to hard-code the
2184 * system call number.
2185 */
2186 "movl %%eax,%%ebx\n"
2187 "movl $1,%%eax\n"
2188 LSS_ENTRYPOINT
2189
2190 /* Return to parent.
2191 */
2192 "1:\n"
2193 : "=a" (__res)
2194 : "0"(-EINVAL), "i"(__NR_clone),
2195 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2196 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002197 : "memory", "ecx", "edx", "esi", "edi");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002198 LSS_RETURN(int, __res);
2199 }
2200
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002201 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2202 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2203
2204 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2205 /* On i386, the kernel does not know how to return from a signal
2206 * handler. Instead, it relies on user space to provide a
2207 * restorer function that calls the {rt_,}sigreturn() system call.
2208 * Unfortunately, we cannot just reference the glibc version of this
2209 * function, as glibc goes out of its way to make it inaccessible.
2210 */
2211 void (*res)(void);
2212 __asm__ __volatile__("call 2f\n"
2213 "0:.align 16\n"
2214 "1:movl %1,%%eax\n"
2215 LSS_ENTRYPOINT
2216 "2:popl %0\n"
2217 "addl $(1b-0b),%0\n"
2218 : "=a" (res)
2219 : "i" (__NR_rt_sigreturn));
2220 return res;
2221 }
2222 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
2223 /* On i386, the kernel does not know how to return from a signal
2224 * handler. Instead, it relies on user space to provide a
2225 * restorer function that calls the {rt_,}sigreturn() system call.
2226 * Unfortunately, we cannot just reference the glibc version of this
2227 * function, as glibc goes out of its way to make it inaccessible.
2228 */
2229 void (*res)(void);
2230 __asm__ __volatile__("call 2f\n"
2231 "0:.align 16\n"
2232 "1:pop %%eax\n"
2233 "movl %1,%%eax\n"
2234 LSS_ENTRYPOINT
2235 "2:popl %0\n"
2236 "addl $(1b-0b),%0\n"
2237 : "=a" (res)
2238 : "i" (__NR_sigreturn));
2239 return res;
2240 }
2241 #elif defined(__x86_64__)
2242 /* There are no known problems with any of the _syscallX() macros
2243 * currently shipping for x86_64, but we still need to be able to define
2244 * our own version so that we can override the location of the errno
2245 * location (e.g. when using the clone() system call with the CLONE_VM
2246 * option).
2247 */
2248 #undef LSS_ENTRYPOINT
2249 #ifdef SYS_SYSCALL_ENTRYPOINT
2250 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2251 void (**entrypoint)(void);
2252 asm volatile(".bss\n"
2253 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002254 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2255 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002256 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002257 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002258 : "=r"(entrypoint));
2259 return entrypoint;
2260 }
2261
2262 #define LSS_ENTRYPOINT \
2263 ".bss\n" \
2264 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002265 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2266 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002267 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002268 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002269 "mov 0(%%rcx), %%rcx\n" \
2270 "test %%rcx, %%rcx\n" \
2271 "jz 10001f\n" \
2272 "call *%%rcx\n" \
2273 "jmp 10002f\n" \
2274 "10001:syscall\n" \
2275 "10002:\n"
2276
2277 #else
2278 #define LSS_ENTRYPOINT "syscall\n"
2279 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002280
2281 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2282 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2283 * sign extension. We can't cast pointers directly because those are
2284 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2285 * to an integer of a different size.
2286 */
2287 #undef LSS_SYSCALL_ARG
2288 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2289 #undef _LSS_RETURN
2290 #define _LSS_RETURN(type, res, cast) \
2291 do { \
2292 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
Peter Kasting880985f2022-06-29 21:17:55 +00002293 LSS_ERRNO = (int)(-(res)); \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002294 res = -1; \
2295 } \
2296 return (type)(cast)(res); \
2297 } while (0)
2298 #undef LSS_RETURN
2299 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2300
2301 #undef _LSS_BODY
2302 #define _LSS_BODY(nr, type, name, cast, ...) \
2303 long long __res; \
2304 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2305 : "=a" (__res) \
2306 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2307 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2308 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002309 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002310 #define LSS_BODY(nr, type, name, args...) \
2311 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2312
2313 #undef LSS_BODY_ASM0
2314 #undef LSS_BODY_ASM1
2315 #undef LSS_BODY_ASM2
2316 #undef LSS_BODY_ASM3
2317 #undef LSS_BODY_ASM4
2318 #undef LSS_BODY_ASM5
2319 #undef LSS_BODY_ASM6
2320 #define LSS_BODY_ASM0
2321 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2322 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2323 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2324 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2325 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2326 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2327
2328 #undef LSS_BODY_CLOBBER0
2329 #undef LSS_BODY_CLOBBER1
2330 #undef LSS_BODY_CLOBBER2
2331 #undef LSS_BODY_CLOBBER3
2332 #undef LSS_BODY_CLOBBER4
2333 #undef LSS_BODY_CLOBBER5
2334 #undef LSS_BODY_CLOBBER6
2335 #define LSS_BODY_CLOBBER0
2336 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2337 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2338 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2339 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2340 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2341 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2342
2343 #undef LSS_BODY_ARG0
2344 #undef LSS_BODY_ARG1
2345 #undef LSS_BODY_ARG2
2346 #undef LSS_BODY_ARG3
2347 #undef LSS_BODY_ARG4
2348 #undef LSS_BODY_ARG5
2349 #undef LSS_BODY_ARG6
2350 #define LSS_BODY_ARG0()
2351 #define LSS_BODY_ARG1(arg1) \
2352 LSS_BODY_ARG0(), "D" (arg1)
2353 #define LSS_BODY_ARG2(arg1, arg2) \
2354 LSS_BODY_ARG1(arg1), "S" (arg2)
2355 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2356 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2357 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2358 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2359 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2360 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2361 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2362 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2363
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002364 #undef _syscall0
2365 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002366 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002367 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002368 }
2369 #undef _syscall1
2370 #define _syscall1(type,name,type1,arg1) \
2371 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002372 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002373 }
2374 #undef _syscall2
2375 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2376 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002377 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002378 }
2379 #undef _syscall3
2380 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2381 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002382 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2383 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002384 }
2385 #undef _syscall4
2386 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2387 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002388 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2389 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002390 }
2391 #undef _syscall5
2392 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2393 type5,arg5) \
2394 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2395 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002396 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2397 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2398 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002399 }
2400 #undef _syscall6
2401 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2402 type5,arg5,type6,arg6) \
2403 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2404 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002405 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2406 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2407 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002408 }
2409 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2410 int flags, void *arg, int *parent_tidptr,
2411 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002412 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002413 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002414 __asm__ __volatile__(/* if (fn == NULL)
2415 * return -EINVAL;
2416 */
2417 "testq %4,%4\n"
2418 "jz 1f\n"
2419
2420 /* if (child_stack == NULL)
2421 * return -EINVAL;
2422 */
2423 "testq %5,%5\n"
2424 "jz 1f\n"
2425
2426 /* childstack -= 2*sizeof(void *);
2427 */
2428 "subq $16,%5\n"
2429
2430 /* Push "arg" and "fn" onto the stack that will be
2431 * used by the child.
2432 */
2433 "movq %7,8(%5)\n"
2434 "movq %4,0(%5)\n"
2435
2436 /* %rax = syscall(%rax = __NR_clone,
2437 * %rdi = flags,
2438 * %rsi = child_stack,
2439 * %rdx = parent_tidptr,
2440 * %r8 = new_tls,
2441 * %r10 = child_tidptr)
2442 */
2443 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002444 "movq %9,%%r8\n"
2445 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002446 LSS_ENTRYPOINT
2447
2448 /* if (%rax != 0)
2449 * return;
2450 */
2451 "testq %%rax,%%rax\n"
2452 "jnz 1f\n"
2453
2454 /* In the child. Terminate frame pointer chain.
2455 */
2456 "xorq %%rbp,%%rbp\n"
2457
2458 /* Call "fn(arg)".
2459 */
2460 "popq %%rax\n"
2461 "popq %%rdi\n"
2462 "call *%%rax\n"
2463
2464 /* Call _exit(%ebx).
2465 */
2466 "movq %%rax,%%rdi\n"
2467 "movq %3,%%rax\n"
2468 LSS_ENTRYPOINT
2469
2470 /* Return to parent.
2471 */
2472 "1:\n"
2473 : "=a" (__res)
2474 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002475 "r"(LSS_SYSCALL_ARG(fn)),
2476 "S"(LSS_SYSCALL_ARG(child_stack)),
2477 "D"(LSS_SYSCALL_ARG(flags)),
2478 "r"(LSS_SYSCALL_ARG(arg)),
2479 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2480 "r"(LSS_SYSCALL_ARG(newtls)),
2481 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002482 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002483 }
2484 LSS_RETURN(int, __res);
2485 }
2486 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002487
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002488 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2489 /* On x86-64, the kernel does not know how to return from
2490 * a signal handler. Instead, it relies on user space to provide a
2491 * restorer function that calls the rt_sigreturn() system call.
2492 * Unfortunately, we cannot just reference the glibc version of this
2493 * function, as glibc goes out of its way to make it inaccessible.
2494 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002495 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002496 __asm__ __volatile__("jmp 2f\n"
2497 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002498 "1:movq %1,%%rax\n"
2499 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002500 "2:leaq 1b(%%rip),%0\n"
2501 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002502 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002503 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002504 }
2505 #elif defined(__ARM_ARCH_3__)
2506 /* Most definitions of _syscallX() neglect to mark "memory" as being
2507 * clobbered. This causes problems with compilers, that do a better job
2508 * at optimizing across __asm__ calls.
2509 * So, we just have to redefine all of the _syscallX() macros.
2510 */
2511 #undef LSS_REG
2512 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2513 #undef LSS_BODY
2514 #define LSS_BODY(type,name,args...) \
2515 register long __res_r0 __asm__("r0"); \
2516 long __res; \
2517 __asm__ __volatile__ (__syscall(name) \
2518 : "=r"(__res_r0) : args : "lr", "memory"); \
2519 __res = __res_r0; \
2520 LSS_RETURN(type, __res)
2521 #undef _syscall0
2522 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002523 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002524 LSS_BODY(type, name); \
2525 }
2526 #undef _syscall1
2527 #define _syscall1(type, name, type1, arg1) \
2528 type LSS_NAME(name)(type1 arg1) { \
2529 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2530 }
2531 #undef _syscall2
2532 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2533 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2534 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2535 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2536 }
2537 #undef _syscall3
2538 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2539 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2540 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2541 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2542 }
2543 #undef _syscall4
2544 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2545 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2546 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2547 LSS_REG(3, arg4); \
2548 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2549 }
2550 #undef _syscall5
2551 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2552 type5,arg5) \
2553 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2554 type5 arg5) { \
2555 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2556 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2557 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2558 "r"(__r4)); \
2559 }
2560 #undef _syscall6
2561 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2562 type5,arg5,type6,arg6) \
2563 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2564 type5 arg5, type6 arg6) { \
2565 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2566 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2567 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2568 "r"(__r4), "r"(__r5)); \
2569 }
2570 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2571 int flags, void *arg, int *parent_tidptr,
2572 void *newtls, int *child_tidptr) {
2573 long __res;
2574 {
2575 register int __flags __asm__("r0") = flags;
2576 register void *__stack __asm__("r1") = child_stack;
2577 register void *__ptid __asm__("r2") = parent_tidptr;
2578 register void *__tls __asm__("r3") = newtls;
2579 register int *__ctid __asm__("r4") = child_tidptr;
2580 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2581 * return -EINVAL;
2582 */
2583 "cmp %2,#0\n"
2584 "cmpne %3,#0\n"
2585 "moveq %0,%1\n"
2586 "beq 1f\n"
2587
2588 /* Push "arg" and "fn" onto the stack that will be
2589 * used by the child.
2590 */
2591 "str %5,[%3,#-4]!\n"
2592 "str %2,[%3,#-4]!\n"
2593
2594 /* %r0 = syscall(%r0 = flags,
2595 * %r1 = child_stack,
2596 * %r2 = parent_tidptr,
2597 * %r3 = newtls,
2598 * %r4 = child_tidptr)
2599 */
2600 __syscall(clone)"\n"
2601
2602 /* if (%r0 != 0)
2603 * return %r0;
2604 */
2605 "movs %0,r0\n"
2606 "bne 1f\n"
2607
2608 /* In the child, now. Call "fn(arg)".
2609 */
2610 "ldr r0,[sp, #4]\n"
2611 "mov lr,pc\n"
2612 "ldr pc,[sp]\n"
2613
2614 /* Call _exit(%r0).
2615 */
2616 __syscall(exit)"\n"
2617 "1:\n"
2618 : "=r" (__res)
2619 : "i"(-EINVAL),
2620 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2621 "r"(__ptid), "r"(__tls), "r"(__ctid)
2622 : "cc", "lr", "memory");
2623 }
2624 LSS_RETURN(int, __res);
2625 }
2626 #elif defined(__ARM_EABI__)
2627 /* Most definitions of _syscallX() neglect to mark "memory" as being
2628 * clobbered. This causes problems with compilers, that do a better job
2629 * at optimizing across __asm__ calls.
2630 * So, we just have to redefine all fo the _syscallX() macros.
2631 */
2632 #undef LSS_REG
2633 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2634 #undef LSS_BODY
2635 #define LSS_BODY(type,name,args...) \
2636 register long __res_r0 __asm__("r0"); \
2637 long __res; \
2638 __asm__ __volatile__ ("push {r7}\n" \
2639 "mov r7, %1\n" \
2640 "swi 0x0\n" \
2641 "pop {r7}\n" \
2642 : "=r"(__res_r0) \
2643 : "i"(__NR_##name) , ## args \
2644 : "lr", "memory"); \
2645 __res = __res_r0; \
2646 LSS_RETURN(type, __res)
2647 #undef _syscall0
2648 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002649 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002650 LSS_BODY(type, name); \
2651 }
2652 #undef _syscall1
2653 #define _syscall1(type, name, type1, arg1) \
2654 type LSS_NAME(name)(type1 arg1) { \
2655 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2656 }
2657 #undef _syscall2
2658 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2659 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2660 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2661 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2662 }
2663 #undef _syscall3
2664 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2665 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2666 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2667 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2668 }
2669 #undef _syscall4
2670 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2671 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2672 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2673 LSS_REG(3, arg4); \
2674 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2675 }
2676 #undef _syscall5
2677 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2678 type5,arg5) \
2679 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2680 type5 arg5) { \
2681 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2682 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2683 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2684 "r"(__r4)); \
2685 }
2686 #undef _syscall6
2687 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2688 type5,arg5,type6,arg6) \
2689 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2690 type5 arg5, type6 arg6) { \
2691 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2692 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2693 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2694 "r"(__r4), "r"(__r5)); \
2695 }
2696 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2697 int flags, void *arg, int *parent_tidptr,
2698 void *newtls, int *child_tidptr) {
2699 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002700 if (fn == NULL || child_stack == NULL) {
2701 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002702 LSS_RETURN(int, __res);
2703 }
2704
2705 /* Push "arg" and "fn" onto the stack that will be
2706 * used by the child.
2707 */
2708 {
2709 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2710 cstack[0] = (uintptr_t)fn;
2711 cstack[1] = (uintptr_t)arg;
2712 child_stack = cstack;
2713 }
2714 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002715 register int __flags __asm__("r0") = flags;
2716 register void *__stack __asm__("r1") = child_stack;
2717 register void *__ptid __asm__("r2") = parent_tidptr;
2718 register void *__tls __asm__("r3") = newtls;
2719 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002720 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002721#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002722 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002723#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002724 /* %r0 = syscall(%r0 = flags,
2725 * %r1 = child_stack,
2726 * %r2 = parent_tidptr,
2727 * %r3 = newtls,
2728 * %r4 = child_tidptr)
2729 */
2730 "mov r7, %6\n"
2731 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002732
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002733 /* if (%r0 != 0)
2734 * return %r0;
2735 */
2736 "cmp r0, #0\n"
2737 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002738
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002739 /* In the child, now. Call "fn(arg)".
2740 */
2741 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002742
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002743 "ldr lr,[sp]\n"
2744 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002745
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002746 /* Call _exit(%r0).
2747 */
2748 "mov r7, %7\n"
2749 "swi 0x0\n"
2750 /* Unreachable */
2751 "bkpt #0\n"
2752 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002753#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002754 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002755#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002756 "movs %0,r0\n"
2757 : "=r"(__res)
2758 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2759 "i"(__NR_clone), "i"(__NR_exit)
2760 : "cc", "lr", "memory"
2761#ifndef __thumb2__
2762 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002763#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002764 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002765 }
2766 LSS_RETURN(int, __res);
2767 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002768 #elif defined(__aarch64__)
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 of the _syscallX() macros.
2773 */
2774 #undef LSS_REG
2775 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2776 #undef LSS_BODY
2777 #define LSS_BODY(type,name,args...) \
2778 register int64_t __res_x0 __asm__("x0"); \
2779 int64_t __res; \
2780 __asm__ __volatile__ ("mov x8, %1\n" \
2781 "svc 0x0\n" \
2782 : "=r"(__res_x0) \
2783 : "i"(__NR_##name) , ## args \
2784 : "x8", "memory"); \
2785 __res = __res_x0; \
2786 LSS_RETURN(type, __res)
2787 #undef _syscall0
2788 #define _syscall0(type, name) \
2789 type LSS_NAME(name)(void) { \
2790 LSS_BODY(type, name); \
2791 }
2792 #undef _syscall1
2793 #define _syscall1(type, name, type1, arg1) \
2794 type LSS_NAME(name)(type1 arg1) { \
2795 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2796 }
2797 #undef _syscall2
2798 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2799 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2800 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2801 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2802 }
2803 #undef _syscall3
2804 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2805 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2806 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2807 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2808 }
2809 #undef _syscall4
2810 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2811 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2812 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2813 LSS_REG(3, arg4); \
2814 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2815 }
2816 #undef _syscall5
2817 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2818 type5,arg5) \
2819 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2820 type5 arg5) { \
2821 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2822 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2823 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2824 "r"(__r4)); \
2825 }
2826 #undef _syscall6
2827 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2828 type5,arg5,type6,arg6) \
2829 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2830 type5 arg5, type6 arg6) { \
2831 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2832 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2833 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2834 "r"(__r4), "r"(__r5)); \
2835 }
2836
2837 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2838 int flags, void *arg, int *parent_tidptr,
2839 void *newtls, int *child_tidptr) {
2840 int64_t __res;
2841 {
2842 register uint64_t __flags __asm__("x0") = flags;
2843 register void *__stack __asm__("x1") = child_stack;
2844 register void *__ptid __asm__("x2") = parent_tidptr;
2845 register void *__tls __asm__("x3") = newtls;
2846 register int *__ctid __asm__("x4") = child_tidptr;
2847 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2848 * used by the child.
2849 */
2850 "stp %1, %4, [%2, #-16]!\n"
2851
2852 /* %x0 = syscall(%x0 = flags,
2853 * %x1 = child_stack,
2854 * %x2 = parent_tidptr,
2855 * %x3 = newtls,
2856 * %x4 = child_tidptr)
2857 */
2858 "mov x8, %8\n"
2859 "svc 0x0\n"
2860
2861 /* if (%r0 != 0)
2862 * return %r0;
2863 */
2864 "mov %0, x0\n"
2865 "cbnz x0, 1f\n"
2866
2867 /* In the child, now. Call "fn(arg)".
2868 */
2869 "ldp x1, x0, [sp], #16\n"
2870 "blr x1\n"
2871
2872 /* Call _exit(%r0).
2873 */
2874 "mov x8, %9\n"
2875 "svc 0x0\n"
2876 "1:\n"
2877 : "=r" (__res)
2878 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2879 "r"(__ptid), "r"(__tls), "r"(__ctid),
2880 "i"(__NR_clone), "i"(__NR_exit)
2881 : "cc", "x8", "memory");
2882 }
2883 LSS_RETURN(int, __res);
2884 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002885 #elif defined(__mips__)
2886 #undef LSS_REG
2887 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2888 (unsigned long)(a)
2889 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002890 #undef LSS_SYSCALL_CLOBBERS
2891 #if _MIPS_SIM == _MIPS_SIM_ABI32
2892 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2893 "$11", "$12", "$13", "$14", "$15", \
2894 "$24", "$25", "hi", "lo", "memory"
2895 #else
2896 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2897 "$13", "$14", "$15", "$24", "$25", \
2898 "hi", "lo", "memory"
2899 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002900 #define LSS_BODY(type,name,r7,...) \
2901 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2902 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002903 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002904 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002905 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002906 LSS_RETURN(type, __v0, __r7)
2907 #undef _syscall0
2908 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002909 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002910 register unsigned long __r7 __asm__("$7"); \
2911 LSS_BODY(type, name, "=r"); \
2912 }
2913 #undef _syscall1
2914 #define _syscall1(type, name, type1, arg1) \
2915 type LSS_NAME(name)(type1 arg1) { \
2916 register unsigned long __r7 __asm__("$7"); \
2917 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2918 }
2919 #undef _syscall2
2920 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2921 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2922 register unsigned long __r7 __asm__("$7"); \
2923 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2924 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2925 }
2926 #undef _syscall3
2927 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2928 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2929 register unsigned long __r7 __asm__("$7"); \
2930 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2931 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2932 }
2933 #undef _syscall4
2934 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2935 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2936 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2937 LSS_REG(7, arg4); \
2938 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2939 }
2940 #undef _syscall5
2941 #if _MIPS_SIM == _MIPS_SIM_ABI32
2942 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2943 * on the stack, whereas the new APIs use registers "r8" and "r9".
2944 */
2945 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2946 type5,arg5) \
2947 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2948 type5 arg5) { \
2949 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2950 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002951 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002952 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002953 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002954 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002955 "syscall\n" \
2956 "addiu $29, 32\n" \
2957 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002958 : "+r"(__v0), "+r" (__r7) \
2959 : "r"(__r4), "r"(__r5), \
2960 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002961 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002962 "$13", "$14", "$15", "$24", "$25", \
2963 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002964 LSS_RETURN(type, __v0, __r7); \
2965 }
2966 #else
2967 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2968 type5,arg5) \
2969 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2970 type5 arg5) { \
2971 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2972 LSS_REG(7, arg4); LSS_REG(8, arg5); \
2973 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2974 "r"(__r8)); \
2975 }
2976 #endif
2977 #undef _syscall6
2978 #if _MIPS_SIM == _MIPS_SIM_ABI32
2979 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2980 * on the stack, whereas the new APIs use registers "r8" and "r9".
2981 */
2982 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2983 type5,arg5,type6,arg6) \
2984 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2985 type5 arg5, type6 arg6) { \
2986 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2987 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002988 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002989 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002990 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002991 "sw %5, 16($29)\n" \
2992 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002993 "syscall\n" \
2994 "addiu $29, 32\n" \
2995 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002996 : "+r"(__v0), "+r" (__r7) \
2997 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002998 "r"(__r6), "r" ((unsigned long)arg5), \
2999 "r" ((unsigned long)arg6) \
3000 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003001 "$13", "$14", "$15", "$24", "$25", \
3002 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003003 LSS_RETURN(type, __v0, __r7); \
3004 }
3005 #else
3006 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3007 type5,arg5,type6,arg6) \
3008 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3009 type5 arg5,type6 arg6) { \
3010 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3011 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
3012 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
3013 "r"(__r8), "r"(__r9)); \
3014 }
3015 #endif
3016 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3017 int flags, void *arg, int *parent_tidptr,
3018 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00003019 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003020 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
3021 {
3022 register int __flags __asm__("$4") = flags;
3023 register void *__stack __asm__("$5") = child_stack;
3024 register void *__ptid __asm__("$6") = parent_tidptr;
3025 register int *__ctid __asm__("$8") = child_tidptr;
3026 __asm__ __volatile__(
3027 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3028 "subu $29,24\n"
3029 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3030 "sub $29,16\n"
3031 #else
3032 "dsubu $29,16\n"
3033 #endif
3034
3035 /* if (fn == NULL || child_stack == NULL)
3036 * return -EINVAL;
3037 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003038 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003039 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003040
3041 /* Push "arg" and "fn" onto the stack that will be
3042 * used by the child.
3043 */
3044 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003045 "subu %5,32\n"
3046 "sw %4,0(%5)\n"
3047 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003048 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003049 "sub %5,32\n"
3050 "sw %4,0(%5)\n"
3051 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003052 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00003053 "dsubu %5,32\n"
3054 "sd %4,0(%5)\n"
3055 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003056 #endif
3057
3058 /* $7 = syscall($4 = flags,
3059 * $5 = child_stack,
3060 * $6 = parent_tidptr,
3061 * $7 = newtls,
3062 * $8 = child_tidptr)
3063 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003064 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003065 "syscall\n"
3066
3067 /* if ($7 != 0)
3068 * return $2;
3069 */
3070 "bnez $7,1f\n"
3071 "bnez $2,1f\n"
3072
3073 /* In the child, now. Call "fn(arg)".
3074 */
3075 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3076 "lw $25,0($29)\n"
3077 "lw $4,4($29)\n"
3078 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3079 "lw $25,0($29)\n"
3080 "lw $4,8($29)\n"
3081 #else
3082 "ld $25,0($29)\n"
3083 "ld $4,8($29)\n"
3084 #endif
3085 "jalr $25\n"
3086
3087 /* Call _exit($2)
3088 */
3089 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003090 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003091 "syscall\n"
3092
3093 "1:\n"
3094 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3095 "addu $29, 24\n"
3096 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3097 "add $29, 16\n"
3098 #else
3099 "daddu $29,16\n"
3100 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003101 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003102 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3103 "r"(__stack), "r"(__flags), "r"(arg),
3104 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003105 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003106 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003107 }
3108 LSS_RETURN(int, __v0, __r7);
3109 }
3110 #elif defined (__PPC__)
3111 #undef LSS_LOADARGS_0
3112 #define LSS_LOADARGS_0(name, dummy...) \
3113 __sc_0 = __NR_##name
3114 #undef LSS_LOADARGS_1
3115 #define LSS_LOADARGS_1(name, arg1) \
3116 LSS_LOADARGS_0(name); \
3117 __sc_3 = (unsigned long) (arg1)
3118 #undef LSS_LOADARGS_2
3119 #define LSS_LOADARGS_2(name, arg1, arg2) \
3120 LSS_LOADARGS_1(name, arg1); \
3121 __sc_4 = (unsigned long) (arg2)
3122 #undef LSS_LOADARGS_3
3123 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3124 LSS_LOADARGS_2(name, arg1, arg2); \
3125 __sc_5 = (unsigned long) (arg3)
3126 #undef LSS_LOADARGS_4
3127 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3128 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3129 __sc_6 = (unsigned long) (arg4)
3130 #undef LSS_LOADARGS_5
3131 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3132 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3133 __sc_7 = (unsigned long) (arg5)
3134 #undef LSS_LOADARGS_6
3135 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3136 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3137 __sc_8 = (unsigned long) (arg6)
3138 #undef LSS_ASMINPUT_0
3139 #define LSS_ASMINPUT_0 "0" (__sc_0)
3140 #undef LSS_ASMINPUT_1
3141 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3142 #undef LSS_ASMINPUT_2
3143 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3144 #undef LSS_ASMINPUT_3
3145 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3146 #undef LSS_ASMINPUT_4
3147 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3148 #undef LSS_ASMINPUT_5
3149 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3150 #undef LSS_ASMINPUT_6
3151 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3152 #undef LSS_BODY
3153 #define LSS_BODY(nr, type, name, args...) \
3154 long __sc_ret, __sc_err; \
3155 { \
3156 register unsigned long __sc_0 __asm__ ("r0"); \
3157 register unsigned long __sc_3 __asm__ ("r3"); \
3158 register unsigned long __sc_4 __asm__ ("r4"); \
3159 register unsigned long __sc_5 __asm__ ("r5"); \
3160 register unsigned long __sc_6 __asm__ ("r6"); \
3161 register unsigned long __sc_7 __asm__ ("r7"); \
3162 register unsigned long __sc_8 __asm__ ("r8"); \
3163 \
3164 LSS_LOADARGS_##nr(name, args); \
3165 __asm__ __volatile__ \
3166 ("sc\n\t" \
3167 "mfcr %0" \
3168 : "=&r" (__sc_0), \
3169 "=&r" (__sc_3), "=&r" (__sc_4), \
3170 "=&r" (__sc_5), "=&r" (__sc_6), \
3171 "=&r" (__sc_7), "=&r" (__sc_8) \
3172 : LSS_ASMINPUT_##nr \
3173 : "cr0", "ctr", "memory", \
3174 "r9", "r10", "r11", "r12"); \
3175 __sc_ret = __sc_3; \
3176 __sc_err = __sc_0; \
3177 } \
3178 LSS_RETURN(type, __sc_ret, __sc_err)
3179 #undef _syscall0
3180 #define _syscall0(type, name) \
3181 type LSS_NAME(name)(void) { \
3182 LSS_BODY(0, type, name); \
3183 }
3184 #undef _syscall1
3185 #define _syscall1(type, name, type1, arg1) \
3186 type LSS_NAME(name)(type1 arg1) { \
3187 LSS_BODY(1, type, name, arg1); \
3188 }
3189 #undef _syscall2
3190 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3191 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3192 LSS_BODY(2, type, name, arg1, arg2); \
3193 }
3194 #undef _syscall3
3195 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3196 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3197 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3198 }
3199 #undef _syscall4
3200 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3201 type4, arg4) \
3202 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3203 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3204 }
3205 #undef _syscall5
3206 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3207 type4, arg4, type5, arg5) \
3208 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3209 type5 arg5) { \
3210 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3211 }
3212 #undef _syscall6
3213 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3214 type4, arg4, type5, arg5, type6, arg6) \
3215 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3216 type5 arg5, type6 arg6) { \
3217 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3218 }
3219 /* clone function adapted from glibc 2.3.6 clone.S */
3220 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3221 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3222 */
3223 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3224 int flags, void *arg, int *parent_tidptr,
3225 void *newtls, int *child_tidptr) {
3226 long __ret, __err;
3227 {
3228 register int (*__fn)(void *) __asm__ ("r8") = fn;
3229 register void *__cstack __asm__ ("r4") = child_stack;
3230 register int __flags __asm__ ("r3") = flags;
3231 register void * __arg __asm__ ("r9") = arg;
3232 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3233 register void * __newtls __asm__ ("r6") = newtls;
3234 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3235 __asm__ __volatile__(
3236 /* check for fn == NULL
3237 * and child_stack == NULL
3238 */
3239 "cmpwi cr0, %6, 0\n\t"
3240 "cmpwi cr1, %7, 0\n\t"
3241 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3242 "beq- cr0, 1f\n\t"
3243
3244 /* set up stack frame for child */
3245 "clrrwi %7, %7, 4\n\t"
3246 "li 0, 0\n\t"
3247 "stwu 0, -16(%7)\n\t"
3248
3249 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3250 "mr 28, %6\n\t"
3251 "mr 29, %7\n\t"
3252 "mr 27, %9\n\t"
3253
3254 /* syscall */
3255 "li 0, %4\n\t"
3256 /* flags already in r3
3257 * child_stack already in r4
3258 * ptidptr already in r5
3259 * newtls already in r6
3260 * ctidptr already in r7
3261 */
3262 "sc\n\t"
3263
3264 /* Test if syscall was successful */
3265 "cmpwi cr1, 3, 0\n\t"
3266 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3267 "bne- cr1, 1f\n\t"
3268
3269 /* Do the function call */
3270 "mtctr 28\n\t"
3271 "mr 3, 27\n\t"
3272 "bctrl\n\t"
3273
3274 /* Call _exit(r3) */
3275 "li 0, %5\n\t"
3276 "sc\n\t"
3277
3278 /* Return to parent */
3279 "1:\n"
3280 "mfcr %1\n\t"
3281 "mr %0, 3\n\t"
3282 : "=r" (__ret), "=r" (__err)
3283 : "0" (-1), "1" (EINVAL),
3284 "i" (__NR_clone), "i" (__NR_exit),
3285 "r" (__fn), "r" (__cstack), "r" (__flags),
3286 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3287 "r" (__ctidptr)
3288 : "cr0", "cr1", "memory", "ctr",
3289 "r0", "r29", "r27", "r28");
3290 }
3291 LSS_RETURN(int, __ret, __err);
3292 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003293 #elif defined(__s390__)
3294 #undef LSS_REG
3295 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3296 #undef LSS_BODY
3297 #define LSS_BODY(type, name, args...) \
3298 register unsigned long __nr __asm__("r1") \
3299 = (unsigned long)(__NR_##name); \
3300 register long __res_r2 __asm__("r2"); \
3301 long __res; \
3302 __asm__ __volatile__ \
3303 ("svc 0\n\t" \
3304 : "=d"(__res_r2) \
3305 : "d"(__nr), ## args \
3306 : "memory"); \
3307 __res = __res_r2; \
3308 LSS_RETURN(type, __res)
3309 #undef _syscall0
3310 #define _syscall0(type, name) \
3311 type LSS_NAME(name)(void) { \
3312 LSS_BODY(type, name); \
3313 }
3314 #undef _syscall1
3315 #define _syscall1(type, name, type1, arg1) \
3316 type LSS_NAME(name)(type1 arg1) { \
3317 LSS_REG(2, arg1); \
3318 LSS_BODY(type, name, "0"(__r2)); \
3319 }
3320 #undef _syscall2
3321 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3322 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3323 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3324 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3325 }
3326 #undef _syscall3
3327 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3328 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3329 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3330 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3331 }
3332 #undef _syscall4
3333 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3334 type4, arg4) \
3335 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3336 type4 arg4) { \
3337 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3338 LSS_REG(5, arg4); \
3339 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3340 "d"(__r5)); \
3341 }
3342 #undef _syscall5
3343 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3344 type4, arg4, type5, arg5) \
3345 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3346 type4 arg4, type5 arg5) { \
3347 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3348 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3349 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3350 "d"(__r5), "d"(__r6)); \
3351 }
3352 #undef _syscall6
3353 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3354 type4, arg4, type5, arg5, type6, arg6) \
3355 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3356 type4 arg4, type5 arg5, type6 arg6) { \
3357 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3358 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3359 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3360 "d"(__r5), "d"(__r6), "d"(__r7)); \
3361 }
3362 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3363 int flags, void *arg, int *parent_tidptr,
3364 void *newtls, int *child_tidptr) {
3365 long __ret;
3366 {
3367 register int (*__fn)(void *) __asm__ ("r1") = fn;
3368 register void *__cstack __asm__ ("r2") = child_stack;
3369 register int __flags __asm__ ("r3") = flags;
3370 register void *__arg __asm__ ("r0") = arg;
3371 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3372 register void *__newtls __asm__ ("r6") = newtls;
3373 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3374 __asm__ __volatile__ (
3375 #ifndef __s390x__
3376 /* arg already in r0 */
3377 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3378 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3379 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3380 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3381 /* flags already in r3 */
3382 /* parent_tidptr already in r4 */
3383 /* child_tidptr already in r5 */
3384 /* newtls already in r6 */
3385 "svc %2\n\t" /* invoke clone syscall */
3386 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3387 "jnz 1f\n\t" /* return to parent if non-zero */
3388 /* start child thread */
3389 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3390 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3391 "xc 0(4,%%r15), 0(%%r15)\n\t"
3392 "basr %%r14, %4\n\t" /* jump to fn */
3393 "svc %3\n" /* invoke exit syscall */
3394 "1:\n"
3395 #else
3396 /* arg already in r0 */
3397 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3398 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3399 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3400 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3401 /* flags already in r3 */
3402 /* parent_tidptr already in r4 */
3403 /* child_tidptr already in r5 */
3404 /* newtls already in r6 */
3405 "svc %2\n\t" /* invoke clone syscall */
3406 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3407 "jnz 1f\n\t" /* return to parent if non-zero */
3408 /* start child thread */
3409 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3410 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3411 "xc 0(8,%%r15), 0(%%r15)\n\t"
3412 "basr %%r14, %4\n\t" /* jump to fn */
3413 "svc %3\n" /* invoke exit syscall */
3414 "1:\n"
3415 #endif
3416 : "=r" (__ret)
3417 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3418 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3419 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3420 : "cc", "r14", "memory"
3421 );
3422 }
3423 LSS_RETURN(int, __ret);
3424 }
Andreas Schwab1d387f42022-02-15 16:21:13 +01003425 #elif defined(__riscv) && __riscv_xlen == 64
3426 #undef LSS_REG
3427 #define LSS_REG(r,a) register int64_t __r##r __asm__("a"#r) = (int64_t)a
3428 #undef LSS_BODY
3429 #define LSS_BODY(type,name,args...) \
3430 register int64_t __res_a0 __asm__("a0"); \
3431 register int64_t __a7 __asm__("a7") = __NR_##name; \
3432 int64_t __res; \
3433 __asm__ __volatile__ ("scall\n" \
3434 : "=r"(__res_a0) \
3435 : "r"(__a7) , ## args \
3436 : "memory"); \
3437 __res = __res_a0; \
3438 LSS_RETURN(type, __res)
3439 #undef _syscall0
3440 #define _syscall0(type, name) \
3441 type LSS_NAME(name)(void) { \
3442 LSS_BODY(type, name); \
3443 }
3444 #undef _syscall1
3445 #define _syscall1(type, name, type1, arg1) \
3446 type LSS_NAME(name)(type1 arg1) { \
3447 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
3448 }
3449 #undef _syscall2
3450 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3451 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3452 LSS_REG(0, arg1); LSS_REG(1, arg2); \
3453 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
3454 }
3455 #undef _syscall3
3456 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3457 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3458 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3459 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
3460 }
3461 #undef _syscall4
3462 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3463 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3464 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3465 LSS_REG(3, arg4); \
3466 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
3467 }
3468 #undef _syscall5
3469 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3470 type5,arg5) \
3471 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3472 type5 arg5) { \
3473 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3474 LSS_REG(3, arg4); LSS_REG(4, arg5); \
3475 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3476 "r"(__r4)); \
3477 }
3478 #undef _syscall6
3479 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3480 type5,arg5,type6,arg6) \
3481 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3482 type5 arg5, type6 arg6) { \
3483 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3484 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
3485 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3486 "r"(__r4), "r"(__r5)); \
3487 }
3488
3489 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3490 int flags, void *arg, int *parent_tidptr,
3491 void *newtls, int *child_tidptr) {
3492 int64_t __res;
3493 {
3494 register int64_t __res_a0 __asm__("a0");
3495 register uint64_t __flags __asm__("a0") = flags;
3496 register void *__stack __asm__("a1") = child_stack;
3497 register void *__ptid __asm__("a2") = parent_tidptr;
3498 register void *__tls __asm__("a3") = newtls;
3499 register int *__ctid __asm__("a4") = child_tidptr;
3500 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
3501 * used by the child.
3502 */
3503 "addi %2,%2,-16\n"
3504 "sd %1, 0(%2)\n"
3505 "sd %4, 8(%2)\n"
3506
3507 /* %a0 = syscall(%a0 = flags,
3508 * %a1 = child_stack,
3509 * %a2 = parent_tidptr,
3510 * %a3 = newtls,
3511 * %a4 = child_tidptr)
3512 */
3513 "li a7, %8\n"
3514 "scall\n"
3515
3516 /* if (%a0 != 0)
3517 * return %a0;
3518 */
3519 "bnez %0, 1f\n"
3520
3521 /* In the child, now. Call "fn(arg)".
3522 */
3523 "ld a1, 0(sp)\n"
3524 "ld a0, 8(sp)\n"
3525 "jalr a1\n"
3526
3527 /* Call _exit(%a0).
3528 */
3529 "li a7, %9\n"
3530 "scall\n"
3531 "1:\n"
3532 : "=r" (__res_a0)
3533 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
3534 "r"(__ptid), "r"(__tls), "r"(__ctid),
3535 "i"(__NR_clone), "i"(__NR_exit)
3536 : "cc", "memory");
3537 __res = __res_a0;
3538 }
3539 LSS_RETURN(int, __res);
3540 }
Konstantin Ivlev8007b272021-01-27 18:27:42 +03003541 #elif defined(__e2k__)
3542
3543 #undef _LSS_BODY
3544 #define _LSS_BODY(nr, type, name, ...) \
3545 register unsigned long long __res; \
3546 __asm__ __volatile__ \
3547 ( \
3548 "{\n\t" \
3549 " sdisp %%ctpr1, 0x3\n\t" \
3550 " addd, s 0x0, %[sys_num], %%b[0]\n\t" \
3551 LSS_BODY_ASM##nr \
3552 "}\n\t" \
3553 "{\n\t" \
3554 " call %%ctpr1, wbs = %#\n\t" \
3555 "}\n\t" \
3556 "{\n\t" \
3557 " addd, s 0x0, %%b[0], %[res]\n\t" \
3558 "}\n\t" \
3559 : [res] "=r" (__res) \
3560 : \
3561 LSS_BODY_ARG##nr(__VA_ARGS__) \
3562 [sys_num] "ri" (__NR_##name) \
3563 : "ctpr1", "ctpr2", "ctpr3", \
3564 "b[0]", "b[1]", "b[2]", "b[3]", \
3565 "b[4]", "b[5]", "b[6]", "b[7]" \
3566 ); \
3567 LSS_RETURN(type, __res);
3568
3569 #undef LSS_BODY
3570 #define LSS_BODY(nr, type, name, args...) \
3571 _LSS_BODY(nr, type, name, ## args)
3572
3573 #undef LSS_BODY_ASM0
3574 #undef LSS_BODY_ASM1
3575 #undef LSS_BODY_ASM2
3576 #undef LSS_BODY_ASM3
3577 #undef LSS_BODY_ASM4
3578 #undef LSS_BODY_ASM5
3579 #undef LSS_BODY_ASM6
3580
3581 #define LSS_BODY_ASM0
3582 #define LSS_BODY_ASM1 LSS_BODY_ASM0 \
3583 " addd, s 0x0, %[arg1], %%b[1]\n\t"
3584 #define LSS_BODY_ASM2 LSS_BODY_ASM1 \
3585 " addd, s 0x0, %[arg2], %%b[2]\n\t"
3586 #define LSS_BODY_ASM3 LSS_BODY_ASM2 \
3587 " addd, s 0x0, %[arg3], %%b[3]\n\t"
3588 #define LSS_BODY_ASM4 LSS_BODY_ASM3 \
3589 " addd, s 0x0, %[arg4], %%b[4]\n\t"
3590 #define LSS_BODY_ASM5 LSS_BODY_ASM4 \
3591 " addd, s 0x0, %[arg5], %%b[5]\n\t"
3592 #define LSS_BODY_ASM6 LSS_BODY_ASM5 \
3593 "}\n\t" \
3594 "{\n\t" \
3595 " addd, s 0x0, %[arg6], %%b[6]\n\t"
3596
3597 #undef LSS_SYSCALL_ARG
3598 #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a))
3599
3600 #undef LSS_BODY_ARG0
3601 #undef LSS_BODY_ARG1
3602 #undef LSS_BODY_ARG2
3603 #undef LSS_BODY_ARG3
3604 #undef LSS_BODY_ARG4
3605 #undef LSS_BODY_ARG5
3606 #undef LSS_BODY_ARG6
3607
3608 #define LSS_BODY_ARG0()
3609 #define LSS_BODY_ARG1(_arg1) \
3610 [arg1] "ri" LSS_SYSCALL_ARG(_arg1),
3611 #define LSS_BODY_ARG2(_arg1, _arg2) \
3612 LSS_BODY_ARG1(_arg1) \
3613 [arg2] "ri" LSS_SYSCALL_ARG(_arg2),
3614 #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3615 LSS_BODY_ARG2(_arg1, _arg2) \
3616 [arg3] "ri" LSS_SYSCALL_ARG(_arg3),
3617 #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3618 LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3619 [arg4] "ri" LSS_SYSCALL_ARG(_arg4),
3620 #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3621 LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3622 [arg5] "ri" LSS_SYSCALL_ARG(_arg5),
3623 #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \
3624 LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3625 [arg6] "ri" LSS_SYSCALL_ARG(_arg6),
3626
3627 #undef _syscall0
3628 #define _syscall0(type, name) \
3629 type LSS_NAME(name)(void) { \
3630 LSS_BODY(0, type, name); \
3631 }
3632
3633 #undef _syscall1
3634 #define _syscall1(type, name, type1, arg1) \
3635 type LSS_NAME(name)(type1 arg1) { \
3636 LSS_BODY(1, type, name, arg1) \
3637 }
3638
3639 #undef _syscall2
3640 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3641 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3642 LSS_BODY(2, type, name, arg1, arg2) \
3643 }
3644
3645 #undef _syscall3
3646 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3647 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3648 LSS_BODY(3, type, name, arg1, arg2, arg3) \
3649 }
3650
3651 #undef _syscall4
3652 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3653 type4, arg4) \
3654 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3655 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \
3656 }
3657
3658 #undef _syscall5
3659 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3660 type4, arg4, type5, arg5) \
3661 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3662 type5 arg5) { \
3663 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \
3664 }
3665
3666 #undef _syscall6
3667 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3668 type4, arg4, type5, arg5, type6, arg6) \
3669 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3670 type5 arg5, type6 arg6) { \
3671 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \
3672 }
3673
3674 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3675 int flags, void *arg, int *parent_tidptr,
3676 void *newtls, int *child_tidptr) {
3677 unsigned long long __res;
3678
3679 __asm__ __volatile__ (
3680 "{\n\t"
3681 " addd,s 0x0, %[nr_clone], %%b[0]\n\t"
3682 " addd,s 0x0, %[flags], %%db[1]\n\t"
3683 " addd,s 0x0, %[child_stack], %%db[2]\n\t"
3684 " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t"
3685 " addd,s 0x0, %[child_tidptr], %%db[4]\n\t"
3686 " addd,s 0x0, %[newtls], %%db[5]\n\t"
3687 "}\n\t"
3688 /* if (fn == NULL)
3689 * return -EINVAL;
3690 */
3691
3692 "{\n\t"
3693 " disp %%ctpr1, .L1\n\t"
3694 "}\n\t"
3695 "{\n\t"
3696 " cmpesb,s 0x0, %[fn], %%pred0\n\t"
3697 "}\n\t"
3698 "{\n\t"
3699 " ct %%ctpr1 ? %%pred0\n\t"
3700 "}\n\t"
3701
3702 /* if (child_stack == NULL)
3703 * return -EINVAL;
3704 */
3705 "{\n\t"
3706 " cmpesb,s 0x0, %%db[2], %%pred0\n\t"
3707 "}\n\t"
3708 "{\n\t"
3709 " ct %%ctpr1 ? %%pred0\n\t"
3710 "}\n\t"
3711
3712 /* b[0] = syscall(%b[0] = __NR_clone,
3713 * %db[1] = flags,
3714 * %db[2] = child_stack,
3715 * %db[3] = parent_tidptr,
3716 * %db[4] = child_tidptr,
3717 * %db[5] = newtls)
3718 */
3719 "{\n\t"
3720 " sdisp %%ctpr1, 0x3\n\t"
3721 "}\n\t"
3722 "{\n\t"
3723 " call %%ctpr1, wbs = %#\n\t"
3724 "}\n\t"
3725
3726 /* if (%[b0] != 0)
3727 * return %b[0];
3728 */
3729 "{\n\t"
3730 " disp %%ctpr1, .L2\n\t"
3731 " cmpesb,s 0x0, %%b[0], %%pred0\n\t"
3732 "}\n\t"
3733 "{\n\t"
3734 " ct %%ctpr1 ? ~%%pred0\n\t"
3735 "}\n\t"
3736 /* In the child, now. Call "fn(arg)".
3737 */
3738
3739 "{\n\t"
3740 " movtd,s %[fn], %%ctpr1\n\t"
3741 "}\n\t"
3742 "{\n\t"
3743 " addd,s 0x0, %[arg], %%db[0]\n\t"
3744 "}\n\t"
3745 "{\n\t"
3746 " call %%ctpr1, wbs = %#\n\t"
3747 "}\n\t"
3748 /* Call _exit(%b[0]).
3749 */
3750
3751 "{\n\t"
3752 " sdisp %%ctpr1, 0x3\n\t"
3753 " addd,s 0x0, %%b[0], %%b[1]\n\t"
3754 "}\n\t"
3755 "{\n\t"
3756 " addd,s 0x0, %[nr_exit], %%b[0]\n\t"
3757 "}\n\t"
3758 "{\n\t"
3759 " call %%ctpr1, wbs = %#\n\t"
3760 "}\n\t"
3761 "{\n\t"
3762 " disp %%ctpr1, .L2\n\t"
3763 " adds,s 0x0, 0x0, %%b[0]\n\t"
3764 "}\n\t"
3765 "{\n\t"
3766 " ct %%ctpr1\n\t"
3767 "}\n\t"
3768 ".L1:\n\t"
3769 "{\n\t"
3770 " addd,s 0x0, %[einval], %%b[0]\n\t"
3771 "}\n\t"
3772 ".L2:\n\t"
3773 "{\n\t"
3774 " addd,s 0x0, %%b[0], %[res]\n\t"
3775 "}\n\t"
3776 : [res] "=r" LSS_SYSCALL_ARG(__res)
3777 : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone)
3778 [arg] "ri" LSS_SYSCALL_ARG(arg)
3779 [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit)
3780 [flags] "ri" LSS_SYSCALL_ARG(flags)
3781 [child_stack] "ri" LSS_SYSCALL_ARG(child_stack)
3782 [parent_tidptr] "ri"
3783 LSS_SYSCALL_ARG(parent_tidptr)
3784 [newtls] "ri" LSS_SYSCALL_ARG(newtls)
3785 [child_tidptr] "ri"
3786 LSS_SYSCALL_ARG(child_tidptr)
3787 [fn] "ri" LSS_SYSCALL_ARG(fn)
3788 [einval] "ri" LSS_SYSCALL_ARG(-EINVAL)
3789 : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]",
3790 "b[4]", "b[5]", "pred0");
3791 LSS_RETURN(int, __res);
3792 }
3793
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003794 #endif
3795 #define __NR__exit __NR_exit
3796 #define __NR__gettid __NR_gettid
3797 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00003798 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003799 LSS_INLINE _syscall1(int, chdir, const char *,p)
3800 LSS_INLINE _syscall1(int, close, int, f)
3801 LSS_INLINE _syscall2(int, clock_getres, int, c,
3802 struct kernel_timespec*, t)
3803 LSS_INLINE _syscall2(int, clock_gettime, int, c,
3804 struct kernel_timespec*, t)
3805 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003806 #if defined(__NR_dup2)
3807 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003808 LSS_INLINE _syscall2(int, dup2, int, s,
3809 int, d)
3810 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003811 #if defined(__NR_dup3)
3812 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3813 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003814 LSS_INLINE _syscall3(int, execve, const char*, f,
3815 const char*const*,a,const char*const*, e)
3816 LSS_INLINE _syscall1(int, _exit, int, e)
3817 LSS_INLINE _syscall1(int, exit_group, int, e)
3818 LSS_INLINE _syscall3(int, fcntl, int, f,
3819 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003820 #if defined(__NR_fork)
3821 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003822 LSS_INLINE _syscall0(pid_t, fork)
3823 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003824 LSS_INLINE _syscall2(int, fstat, int, f,
3825 struct kernel_stat*, b)
3826 LSS_INLINE _syscall2(int, fstatfs, int, f,
3827 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003828 #if defined(__x86_64__)
3829 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3830 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
3831 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
3832 }
3833 #else
3834 LSS_INLINE _syscall2(int, ftruncate, int, f,
3835 off_t, l)
3836 #endif
Mike Frysinger171a36a2019-01-26 23:05:43 -05003837 LSS_INLINE _syscall6(int, futex, int*, u,
3838 int, o, int, v,
3839 struct kernel_timespec*, t,
3840 int*, u2, int, v2)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003841 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003842 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003843 LSS_INLINE _syscall3(int, getdents64, int, f,
3844 struct kernel_dirent64*, d, int, c)
3845 LSS_INLINE _syscall0(gid_t, getegid)
3846 LSS_INLINE _syscall0(uid_t, geteuid)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003847 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003848 LSS_INLINE _syscall0(pid_t, getpgrp)
3849 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003850 LSS_INLINE _syscall0(pid_t, getpid)
3851 LSS_INLINE _syscall0(pid_t, getppid)
3852 LSS_INLINE _syscall2(int, getpriority, int, a,
3853 int, b)
3854 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
3855 gid_t *, e, gid_t *, s)
3856 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
3857 uid_t *, e, uid_t *, s)
3858#if !defined(__ARM_EABI__)
3859 LSS_INLINE _syscall2(int, getrlimit, int, r,
3860 struct kernel_rlimit*, l)
3861#endif
3862 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
3863 LSS_INLINE _syscall0(pid_t, _gettid)
3864 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
3865 void*, tz)
3866 LSS_INLINE _syscall5(int, setxattr, const char *,p,
3867 const char *, n, const void *,v,
3868 size_t, s, int, f)
3869 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
3870 const char *, n, const void *,v,
3871 size_t, s, int, f)
3872 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
3873 const char *, n, void *, v, size_t, s)
3874 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
3875 const char *, n, void *, v, size_t, s)
3876 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
3877 char *, l, size_t, s)
3878 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
3879 char *, l, size_t, s)
3880 LSS_INLINE _syscall3(int, ioctl, int, d,
3881 int, r, void *, a)
3882 LSS_INLINE _syscall2(int, ioprio_get, int, which,
3883 int, who)
3884 LSS_INLINE _syscall3(int, ioprio_set, int, which,
3885 int, who, int, ioprio)
3886 LSS_INLINE _syscall2(int, kill, pid_t, p,
3887 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003888 #if defined(__x86_64__)
3889 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3890 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
3891 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3892 LSS_SYSCALL_ARG(w));
3893 }
3894 #else
3895 LSS_INLINE _syscall3(off_t, lseek, int, f,
3896 off_t, o, int, w)
3897 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003898 LSS_INLINE _syscall2(int, munmap, void*, s,
3899 size_t, l)
3900 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
3901 unsigned long, n, void **,g, int *, d,
3902 int *, s, int, f)
3903 LSS_INLINE _syscall3(int, mprotect, const void *,a,
3904 size_t, l, int, p)
3905 LSS_INLINE _syscall5(void*, _mremap, void*, o,
3906 size_t, os, size_t, ns,
3907 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003908 #if defined(__NR_open)
3909 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003910 LSS_INLINE _syscall3(int, open, const char*, p,
3911 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003912 #endif
3913 #if defined(__NR_poll)
3914 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003915 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
3916 unsigned int, n, int, t)
3917 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003918 #if defined(__NR_ppoll)
3919 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
3920 unsigned int, n, const struct kernel_timespec *, t,
3921 const struct kernel_sigset_t *, sigmask, size_t, s)
3922 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00003923 LSS_INLINE _syscall5(int, prctl, int, option,
3924 unsigned long, arg2,
3925 unsigned long, arg3,
3926 unsigned long, arg4,
3927 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003928 LSS_INLINE _syscall4(long, ptrace, int, r,
3929 pid_t, p, void *, a, void *, d)
3930 #if defined(__NR_quotactl)
3931 // Defined on x86_64 / i386 only
3932 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
3933 int, id, caddr_t, addr)
3934 #endif
3935 LSS_INLINE _syscall3(ssize_t, read, int, f,
3936 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003937 #if defined(__NR_readlink)
3938 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003939 LSS_INLINE _syscall3(int, readlink, const char*, p,
3940 char*, b, size_t, s)
3941 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003942 #if defined(__NR_readlinkat)
3943 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
3944 size_t, s)
3945 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003946 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
3947 const struct kernel_sigaction*, a,
3948 struct kernel_sigaction*, o, size_t, c)
3949 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
3950 size_t, c)
3951 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
3952 const struct kernel_sigset_t*, s,
3953 struct kernel_sigset_t*, o, size_t, c)
3954 LSS_INLINE _syscall2(int, rt_sigsuspend,
3955 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08003956 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
3957 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003958 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
3959 unsigned int, l, unsigned long *, m)
3960 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
3961 unsigned int, l, unsigned long *, m)
3962 LSS_INLINE _syscall0(int, sched_yield)
3963 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
3964 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
3965 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
3966 LSS_INLINE _syscall1(int, setuid, uid_t, u)
3967 LSS_INLINE _syscall1(int, setgid, gid_t, g)
3968 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
3969 pid_t, g)
3970 LSS_INLINE _syscall3(int, setpriority, int, a,
3971 int, b, int, p)
3972 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
3973 gid_t, e, gid_t, s)
3974 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
3975 uid_t, e, uid_t, s)
3976 LSS_INLINE _syscall2(int, setrlimit, int, r,
3977 const struct kernel_rlimit*, l)
3978 LSS_INLINE _syscall0(pid_t, setsid)
3979 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
3980 const stack_t*, o)
3981 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003982 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003983 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003984 #if defined(__NR_stat)
Matthew Denton92a65a82021-04-01 13:00:07 -07003985 // stat and lstat are polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003986 LSS_INLINE _syscall2(int, stat, const char*, f,
3987 struct kernel_stat*, b)
3988 #endif
Matthew Denton92a65a82021-04-01 13:00:07 -07003989 #if defined(__NR_lstat)
3990 LSS_INLINE _syscall2(int, lstat, const char*, f,
3991 struct kernel_stat*, b)
3992 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003993 LSS_INLINE _syscall2(int, statfs, const char*, f,
3994 struct kernel_statfs*, b)
3995 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
3996 pid_t, t, int, s)
3997 LSS_INLINE _syscall2(int, tkill, pid_t, p,
3998 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003999 #if defined(__NR_unlink)
4000 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004001 LSS_INLINE _syscall1(int, unlink, const char*, f)
4002 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004003 LSS_INLINE _syscall3(ssize_t, write, int, f,
4004 const void *, b, size_t, c)
4005 LSS_INLINE _syscall3(ssize_t, writev, int, f,
4006 const struct kernel_iovec*, v, size_t, c)
4007 #if defined(__NR_getcpu)
4008 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00004009 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004010 #endif
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004011 #if defined(__x86_64__) || defined(__e2k__) || \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004012 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
4013 LSS_INLINE _syscall3(int, recvmsg, int, s,
4014 struct kernel_msghdr*, m, int, f)
4015 LSS_INLINE _syscall3(int, sendmsg, int, s,
4016 const struct kernel_msghdr*, m, int, f)
4017 LSS_INLINE _syscall6(int, sendto, int, s,
4018 const void*, m, size_t, l,
4019 int, f,
4020 const struct kernel_sockaddr*, a, int, t)
4021 LSS_INLINE _syscall2(int, shutdown, int, s,
4022 int, h)
4023 LSS_INLINE _syscall3(int, socket, int, d,
4024 int, t, int, p)
4025 LSS_INLINE _syscall4(int, socketpair, int, d,
4026 int, t, int, p, int*, s)
4027 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004028 #if defined(__NR_fadvise64)
4029 #if defined(__x86_64__)
4030 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4031 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
4032 int advice) {
4033 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
4034 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
4035 }
4036 #else
4037 LSS_INLINE _syscall4(int, fadvise64,
4038 int, fd, loff_t, offset, loff_t, len, int, advice)
4039 #endif
4040 #elif defined(__i386__)
4041 #define __NR__fadvise64_64 __NR_fadvise64_64
4042 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
4043 unsigned, offset_lo, unsigned, offset_hi,
4044 unsigned, len_lo, unsigned, len_hi,
4045 int, advice)
4046
4047 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4048 loff_t len, int advice) {
4049 return LSS_NAME(_fadvise64_64)(fd,
4050 (unsigned)offset, (unsigned)(offset >>32),
4051 (unsigned)len, (unsigned)(len >> 32),
4052 advice);
4053 }
4054
4055 #elif defined(__s390__) && !defined(__s390x__)
4056 #define __NR__fadvise64_64 __NR_fadvise64_64
4057 struct kernel_fadvise64_64_args {
4058 int fd;
4059 long long offset;
4060 long long len;
4061 int advice;
4062 };
4063
4064 LSS_INLINE _syscall1(int, _fadvise64_64,
4065 struct kernel_fadvise64_64_args *args)
4066
4067 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4068 loff_t len, int advice) {
4069 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
4070 return LSS_NAME(_fadvise64_64)(&args);
4071 }
4072 #endif
4073 #if defined(__NR_fallocate)
4074 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004075 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4076 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
4077 loff_t len) {
4078 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
4079 (uint64_t)(offset), (uint64_t)(len));
4080 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08004081 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
4082 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
4083 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
4084 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04004085 #define __NR__fallocate __NR_fallocate
4086 LSS_INLINE _syscall6(int, _fallocate, int, fd,
4087 int, mode,
4088 unsigned, offset_lo, unsigned, offset_hi,
4089 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004090
Bryan Chan3f6478a2016-06-14 08:38:17 -04004091 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
4092 loff_t offset, loff_t len) {
4093 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
4094 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
4095 }
4096 #else
4097 LSS_INLINE _syscall4(int, fallocate,
4098 int, f, int, mode, loff_t, offset, loff_t, len)
4099 #endif
4100 #endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07004101 #if defined(__NR_getrandom)
4102 LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length,
4103 unsigned int, flags)
4104 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004105 #if defined(__NR_newfstatat)
4106 LSS_INLINE _syscall4(int, newfstatat, int, d,
4107 const char *, p,
4108 struct kernel_stat*, b, int, f)
4109 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004110 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004111 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4112 gid_t *egid,
4113 gid_t *sgid) {
4114 return LSS_NAME(getresgid)(rgid, egid, sgid);
4115 }
4116
4117 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4118 uid_t *euid,
4119 uid_t *suid) {
4120 return LSS_NAME(getresuid)(ruid, euid, suid);
4121 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004122
4123 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4124 return LSS_NAME(setfsgid)(gid);
4125 }
4126
4127 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4128 return LSS_NAME(setfsuid)(uid);
4129 }
4130
4131 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4132 return LSS_NAME(setresgid)(rgid, egid, sgid);
4133 }
4134
4135 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4136 return LSS_NAME(setresuid)(ruid, euid, suid);
4137 }
4138
4139 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4140 const struct kernel_sigaction *act,
4141 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04004142 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004143 /* On x86_64, the kernel requires us to always set our own
4144 * SA_RESTORER in order to be able to return from a signal handler.
4145 * This function must have a "magic" signature that the "gdb"
4146 * (and maybe the kernel?) can recognize.
4147 */
4148 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
4149 struct kernel_sigaction a = *act;
4150 a.sa_flags |= SA_RESTORER;
4151 a.sa_restorer = LSS_NAME(restore_rt)();
4152 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
4153 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04004154 } else
4155 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004156 return LSS_NAME(rt_sigaction)(signum, act, oldact,
4157 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004158 }
4159
4160 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4161 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4162 }
4163
Joshua Peraza726d71e2019-11-13 12:21:13 -08004164 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4165 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4166 }
4167 #endif
4168 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004169 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
4170 const struct kernel_sigset_t *set,
4171 struct kernel_sigset_t *oldset) {
4172 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
4173 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08004174 #endif
4175 #if defined(__NR_rt_sigtimedwait)
4176 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
4177 siginfo_t *info,
4178 const struct timespec *timeout) {
4179 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004180 }
4181 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004182 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004183 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
4184 int*, s, int, o,
4185 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004186 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004187 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004188 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004189 #endif
4190 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004191 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
4192 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004193 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4194 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004195 #define __NR__getresgid32 __NR_getresgid32
4196 #define __NR__getresuid32 __NR_getresuid32
4197 #define __NR__setfsgid32 __NR_setfsgid32
4198 #define __NR__setfsuid32 __NR_setfsuid32
4199 #define __NR__setresgid32 __NR_setresgid32
4200 #define __NR__setresuid32 __NR_setresuid32
4201#if defined(__ARM_EABI__)
4202 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
4203 struct kernel_rlimit*, l)
4204#endif
4205 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
4206 gid_t *, e, gid_t *, s)
4207 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
4208 uid_t *, e, uid_t *, s)
4209 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
4210 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
4211 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
4212 gid_t, e, gid_t, s)
4213 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
4214 uid_t, e, uid_t, s)
4215
4216 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4217 gid_t *egid,
4218 gid_t *sgid) {
4219 int rc;
4220 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
4221 LSS_ERRNO == ENOSYS) {
4222 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
4223 return EFAULT;
4224 }
4225 // Clear the high bits first, since getresgid only sets 16 bits
4226 *rgid = *egid = *sgid = 0;
4227 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
4228 }
4229 return rc;
4230 }
4231
4232 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4233 uid_t *euid,
4234 uid_t *suid) {
4235 int rc;
4236 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
4237 LSS_ERRNO == ENOSYS) {
4238 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
4239 return EFAULT;
4240 }
4241 // Clear the high bits first, since getresuid only sets 16 bits
4242 *ruid = *euid = *suid = 0;
4243 rc = LSS_NAME(getresuid)(ruid, euid, suid);
4244 }
4245 return rc;
4246 }
4247
4248 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4249 int rc;
4250 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
4251 LSS_ERRNO == ENOSYS) {
4252 if ((unsigned int)gid & ~0xFFFFu) {
4253 rc = EINVAL;
4254 } else {
4255 rc = LSS_NAME(setfsgid)(gid);
4256 }
4257 }
4258 return rc;
4259 }
4260
4261 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4262 int rc;
4263 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
4264 LSS_ERRNO == ENOSYS) {
4265 if ((unsigned int)uid & ~0xFFFFu) {
4266 rc = EINVAL;
4267 } else {
4268 rc = LSS_NAME(setfsuid)(uid);
4269 }
4270 }
4271 return rc;
4272 }
4273
4274 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4275 int rc;
4276 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
4277 LSS_ERRNO == ENOSYS) {
4278 if ((unsigned int)rgid & ~0xFFFFu ||
4279 (unsigned int)egid & ~0xFFFFu ||
4280 (unsigned int)sgid & ~0xFFFFu) {
4281 rc = EINVAL;
4282 } else {
4283 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
4284 }
4285 }
4286 return rc;
4287 }
4288
4289 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4290 int rc;
4291 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
4292 LSS_ERRNO == ENOSYS) {
4293 if ((unsigned int)ruid & ~0xFFFFu ||
4294 (unsigned int)euid & ~0xFFFFu ||
4295 (unsigned int)suid & ~0xFFFFu) {
4296 rc = EINVAL;
4297 } else {
4298 rc = LSS_NAME(setresuid)(ruid, euid, suid);
4299 }
4300 }
4301 return rc;
4302 }
4303 #endif
4304 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
4305 memset(&set->sig, 0, sizeof(set->sig));
4306 return 0;
4307 }
4308
4309 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
4310 memset(&set->sig, -1, sizeof(set->sig));
4311 return 0;
4312 }
4313
4314 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
4315 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004316 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004317 LSS_ERRNO = EINVAL;
4318 return -1;
4319 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004320 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4321 |= 1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004322 return 0;
4323 }
4324 }
4325
4326 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
4327 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004328 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004329 LSS_ERRNO = EINVAL;
4330 return -1;
4331 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004332 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4333 &= ~(1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004334 return 0;
4335 }
4336 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004337
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004338 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
4339 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004340 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004341 LSS_ERRNO = EINVAL;
4342 return -1;
4343 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004344 return !!(set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] &
4345 (1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004346 }
4347 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04004348 #if defined(__i386__) || \
4349 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4350 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4351 defined(__PPC__) || \
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004352 (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004353 #define __NR__sigaction __NR_sigaction
4354 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004355 #define __NR__sigsuspend __NR_sigsuspend
4356 #define __NR__socketcall __NR_socketcall
4357 LSS_INLINE _syscall2(int, fstat64, int, f,
4358 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00004359 LSS_INLINE _syscall5(int, _llseek, uint, fd,
4360 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004361 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004362#if defined(__s390__) && !defined(__s390x__)
4363 /* On s390, mmap2() arguments are passed in memory. */
4364 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
4365 off_t o) {
4366 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4367 (unsigned long) p, (unsigned long) f,
4368 (unsigned long) d, (unsigned long) o };
4369 LSS_REG(2, buf);
4370 LSS_BODY(void*, mmap2, "0"(__r2));
4371 }
4372#else
4373 #define __NR__mmap2 __NR_mmap2
4374 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004375 size_t, l, int, p,
4376 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04004377 off_t, o)
4378#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004379 LSS_INLINE _syscall3(int, _sigaction, int, s,
4380 const struct kernel_old_sigaction*, a,
4381 struct kernel_old_sigaction*, o)
4382 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004383 #ifdef __PPC__
4384 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
4385 #else
4386 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
4387 int, b,
4388 unsigned long, s)
4389 #endif
4390 LSS_INLINE _syscall2(int, stat64, const char *, p,
4391 struct kernel_stat64 *, b)
4392
4393 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4394 const struct kernel_sigaction *act,
4395 struct kernel_sigaction *oldact) {
4396 int old_errno = LSS_ERRNO;
4397 int rc;
4398 struct kernel_sigaction a;
4399 if (act != NULL) {
4400 a = *act;
4401 #ifdef __i386__
4402 /* On i386, the kernel requires us to always set our own
4403 * SA_RESTORER when using realtime signals. Otherwise, it does not
4404 * know how to return from a signal handler. This function must have
4405 * a "magic" signature that the "gdb" (and maybe the kernel?) can
4406 * recognize.
4407 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
4408 * using non-realtime signals.
4409 *
4410 * TODO: Test whether ARM needs a restorer
4411 */
4412 if (!(a.sa_flags & SA_RESTORER)) {
4413 a.sa_flags |= SA_RESTORER;
4414 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
4415 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
4416 }
4417 #endif
4418 }
4419 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
4420 (KERNEL_NSIG+7)/8);
4421 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4422 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
4423 if (!act) {
4424 ptr_a = NULL;
4425 } else {
4426 oa.sa_handler_ = act->sa_handler_;
4427 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
4428 #ifndef __mips__
4429 oa.sa_restorer = act->sa_restorer;
4430 #endif
4431 oa.sa_flags = act->sa_flags;
4432 }
4433 if (!oldact) {
4434 ptr_oa = NULL;
4435 }
4436 LSS_ERRNO = old_errno;
4437 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
4438 if (rc == 0 && oldact) {
4439 if (act) {
4440 memcpy(oldact, act, sizeof(*act));
4441 } else {
4442 memset(oldact, 0, sizeof(*oldact));
4443 }
4444 oldact->sa_handler_ = ptr_oa->sa_handler_;
4445 oldact->sa_flags = ptr_oa->sa_flags;
4446 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4447 #ifndef __mips__
4448 oldact->sa_restorer = ptr_oa->sa_restorer;
4449 #endif
4450 }
4451 }
4452 return rc;
4453 }
4454
4455 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4456 int old_errno = LSS_ERRNO;
4457 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4458 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4459 LSS_ERRNO = old_errno;
4460 LSS_NAME(sigemptyset)(set);
4461 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4462 }
4463 return rc;
4464 }
4465
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004466 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4467 int olderrno = LSS_ERRNO;
4468 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4469 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4470 LSS_ERRNO = olderrno;
4471 rc = LSS_NAME(_sigsuspend)(
4472 #ifndef __PPC__
4473 set, 0,
4474 #endif
4475 set->sig[0]);
4476 }
4477 return rc;
4478 }
4479 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004480 #if defined(__i386__) || \
4481 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4482 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4483 defined(__PPC__) || \
4484 (defined(__s390__) && !defined(__s390x__))
4485 /* On these architectures, implement mmap() with mmap2(). */
4486 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4487 int64_t o) {
4488 if (o % 4096) {
4489 LSS_ERRNO = EINVAL;
4490 return (void *) -1;
4491 }
4492 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4493 }
4494 #elif defined(__s390x__)
4495 /* On s390x, mmap() arguments are passed in memory. */
4496 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4497 int64_t o) {
4498 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4499 (unsigned long) p, (unsigned long) f,
4500 (unsigned long) d, (unsigned long) o };
4501 LSS_REG(2, buf);
4502 LSS_BODY(void*, mmap, "0"(__r2));
4503 }
4504 #elif defined(__x86_64__)
4505 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4506 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4507 int64_t o) {
4508 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4509 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4510 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4511 }
4512 #else
4513 /* Remaining 64-bit architectures. */
4514 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4515 int, flags, int, fd, int64_t, offset)
4516 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004517 #if defined(__PPC__)
4518 #undef LSS_SC_LOADARGS_0
4519 #define LSS_SC_LOADARGS_0(dummy...)
4520 #undef LSS_SC_LOADARGS_1
4521 #define LSS_SC_LOADARGS_1(arg1) \
4522 __sc_4 = (unsigned long) (arg1)
4523 #undef LSS_SC_LOADARGS_2
4524 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4525 LSS_SC_LOADARGS_1(arg1); \
4526 __sc_5 = (unsigned long) (arg2)
4527 #undef LSS_SC_LOADARGS_3
4528 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4529 LSS_SC_LOADARGS_2(arg1, arg2); \
4530 __sc_6 = (unsigned long) (arg3)
4531 #undef LSS_SC_LOADARGS_4
4532 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4533 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4534 __sc_7 = (unsigned long) (arg4)
4535 #undef LSS_SC_LOADARGS_5
4536 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4537 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4538 __sc_8 = (unsigned long) (arg5)
4539 #undef LSS_SC_BODY
4540 #define LSS_SC_BODY(nr, type, opt, args...) \
4541 long __sc_ret, __sc_err; \
4542 { \
4543 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4544 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4545 register unsigned long __sc_4 __asm__ ("r4"); \
4546 register unsigned long __sc_5 __asm__ ("r5"); \
4547 register unsigned long __sc_6 __asm__ ("r6"); \
4548 register unsigned long __sc_7 __asm__ ("r7"); \
4549 register unsigned long __sc_8 __asm__ ("r8"); \
4550 LSS_SC_LOADARGS_##nr(args); \
4551 __asm__ __volatile__ \
4552 ("stwu 1, -48(1)\n\t" \
4553 "stw 4, 20(1)\n\t" \
4554 "stw 5, 24(1)\n\t" \
4555 "stw 6, 28(1)\n\t" \
4556 "stw 7, 32(1)\n\t" \
4557 "stw 8, 36(1)\n\t" \
4558 "addi 4, 1, 20\n\t" \
4559 "sc\n\t" \
4560 "mfcr %0" \
4561 : "=&r" (__sc_0), \
4562 "=&r" (__sc_3), "=&r" (__sc_4), \
4563 "=&r" (__sc_5), "=&r" (__sc_6), \
4564 "=&r" (__sc_7), "=&r" (__sc_8) \
4565 : LSS_ASMINPUT_##nr \
4566 : "cr0", "ctr", "memory"); \
4567 __sc_ret = __sc_3; \
4568 __sc_err = __sc_0; \
4569 } \
4570 LSS_RETURN(type, __sc_ret, __sc_err)
4571
4572 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4573 int flags){
4574 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4575 }
4576
4577 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4578 const struct kernel_msghdr *msg,
4579 int flags) {
4580 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4581 }
4582
4583 // TODO(csilvers): why is this ifdef'ed out?
4584#if 0
4585 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4586 int flags,
4587 const struct kernel_sockaddr *to,
4588 unsigned int tolen) {
4589 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4590 }
4591#endif
4592
4593 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4594 LSS_SC_BODY(2, int, 13, s, how);
4595 }
4596
4597 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4598 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4599 }
4600
4601 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4602 int sv[2]) {
4603 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4604 }
4605 #endif
Andreas Schwab1d387f42022-02-15 16:21:13 +01004606 #if defined(__ARM_EABI__) || defined (__aarch64__) || defined(__riscv)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004607 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4608 int, flags)
4609 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4610 msg, int, flags)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004611 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4612 int, flags, const struct kernel_sockaddr*, to,
4613 unsigned int, tolen)
4614 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
4615 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
4616 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4617 int*, sv)
4618 #endif
4619 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004620 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4621 defined(__s390__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004622 #define __NR__socketcall __NR_socketcall
4623 LSS_INLINE _syscall2(int, _socketcall, int, c,
4624 va_list, a)
4625 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4626 int rc;
4627 va_list ap;
4628 va_start(ap, op);
4629 rc = LSS_NAME(_socketcall)(op, ap);
4630 va_end(ap);
4631 return rc;
4632 }
4633
4634 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4635 int flags){
4636 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4637 }
4638
4639 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4640 const struct kernel_msghdr *msg,
4641 int flags) {
4642 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4643 }
4644
4645 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4646 int flags,
4647 const struct kernel_sockaddr *to,
4648 unsigned int tolen) {
4649 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4650 }
4651
4652 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4653 return LSS_NAME(socketcall)(13, s, how);
4654 }
4655
4656 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4657 return LSS_NAME(socketcall)(1, domain, type, protocol);
4658 }
4659
4660 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4661 int sv[2]) {
4662 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4663 }
4664 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004665 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004666 LSS_INLINE _syscall4(int, fstatat64, int, d,
4667 const char *, p,
4668 struct kernel_stat64 *, b, int, f)
4669 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004670 #if defined(__NR_waitpid)
4671 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004672 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4673 int*, s, int, o)
4674 #endif
4675 #if defined(__mips__)
4676 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4677 * both file handles through CPU registers.
4678 */
4679 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4680 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4681 register unsigned long __v1 __asm__("$3");
4682 register unsigned long __r7 __asm__("$7");
4683 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004684 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004685 : "0"(__v0)
4686 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004687 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004688 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004689 unsigned long __errnovalue = __v0;
4690 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004691 return -1;
4692 } else {
4693 p[0] = __v0;
4694 p[1] = __v1;
4695 return 0;
4696 }
4697 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004698 #elif defined(__NR_pipe)
4699 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004700 LSS_INLINE _syscall1(int, pipe, int *, p)
4701 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004702 #if defined(__NR_pipe2)
4703 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4704 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004705 /* TODO(csilvers): see if ppc can/should support this as well */
4706 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004707 defined(__ARM_EABI__) || \
4708 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4709 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004710 #define __NR__statfs64 __NR_statfs64
4711 #define __NR__fstatfs64 __NR_fstatfs64
4712 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4713 size_t, s,struct kernel_statfs64*, b)
4714 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4715 size_t, s,struct kernel_statfs64*, b)
4716 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
4717 struct kernel_statfs64 *b) {
4718 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
4719 }
4720 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
4721 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
4722 }
4723 #endif
4724
4725 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
4726 extern char **environ;
4727 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
4728 }
4729
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004730 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004731 pid_t tid = LSS_NAME(_gettid)();
4732 if (tid != -1) {
4733 return tid;
4734 }
4735 return LSS_NAME(getpid)();
4736 }
4737
4738 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
4739 size_t new_size, int flags, ...) {
4740 va_list ap;
4741 void *new_address, *rc;
4742 va_start(ap, flags);
4743 new_address = va_arg(ap, void *);
4744 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
Peter Kasting880985f2022-06-29 21:17:55 +00004745 (unsigned long)flags, new_address);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004746 va_end(ap);
4747 return rc;
4748 }
4749
Peter Kasting880985f2022-06-29 21:17:55 +00004750 LSS_INLINE long LSS_NAME(ptrace_detach)(pid_t pid) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004751 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
4752 * then sends job control signals to the real parent, rather than to
4753 * the tracer. We reduce the risk of this happening by starting a
4754 * whole new time slice, and then quickly sending a SIGCONT signal
4755 * right after detaching from the tracee.
4756 *
4757 * We use tkill to ensure that we only issue a wakeup for the thread being
4758 * detached. Large multi threaded apps can take a long time in the kernel
4759 * processing SIGCONT.
4760 */
Peter Kasting880985f2022-06-29 21:17:55 +00004761 long rc;
4762 int err;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004763 LSS_NAME(sched_yield)();
4764 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
4765 err = LSS_ERRNO;
4766 LSS_NAME(tkill)(pid, SIGCONT);
4767 /* Old systems don't have tkill */
4768 if (LSS_ERRNO == ENOSYS)
4769 LSS_NAME(kill)(pid, SIGCONT);
4770 LSS_ERRNO = err;
4771 return rc;
4772 }
4773
4774 LSS_INLINE int LSS_NAME(raise)(int sig) {
4775 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
4776 }
4777
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004778 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004779 return LSS_NAME(setpgid)(0, 0);
4780 }
4781
vapier@chromium.org2273e812013-04-01 17:52:44 +00004782 #if defined(__x86_64__)
4783 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4784 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
4785 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4786 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4787 }
4788
4789 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
4790 loff_t o) {
4791 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4792 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4793 }
4794
4795 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) {
4796 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4797 LSS_SYSCALL_ARG(c));
4798 }
4799 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004800 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
4801 void *, b, size_t, c,
4802 loff_t, o)
4803 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
4804 const void *, b, size_t, c,
4805 loff_t, o)
4806 LSS_INLINE _syscall3(int, readahead, int, f,
4807 loff_t, o, unsigned, c)
4808 #else
4809 #define __NR__pread64 __NR_pread64
4810 #define __NR__pwrite64 __NR_pwrite64
4811 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00004812 #if defined(__ARM_EABI__) || defined(__mips__)
4813 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
4814 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004815 * fifth and sixth make such a pair (r4,r5).
4816 */
4817 #define LSS_LLARG_PAD 0,
4818 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
4819 void *, b, size_t, c,
4820 unsigned, skip, unsigned, o1, unsigned, o2)
4821 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
4822 const void *, b, size_t, c,
4823 unsigned, skip, unsigned, o1, unsigned, o2)
4824 LSS_INLINE _syscall5(int, _readahead, int, f,
4825 unsigned, skip,
4826 unsigned, o1, unsigned, o2, size_t, c)
4827 #else
4828 #define LSS_LLARG_PAD
4829 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
4830 void *, b, size_t, c, unsigned, o1,
4831 unsigned, o2)
4832 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
4833 const void *, b, size_t, c, unsigned, o1,
4834 long, o2)
4835 LSS_INLINE _syscall4(int, _readahead, int, f,
4836 unsigned, o1, unsigned, o2, size_t, c)
4837 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004838 /* We force 64bit-wide parameters onto the stack, then access each
4839 * 32-bit component individually. This guarantees that we build the
4840 * correct parameters independent of the native byte-order of the
4841 * underlying architecture.
4842 */
4843 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
4844 loff_t off) {
4845 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004846 return LSS_NAME(_pread64)(fd, buf, count,
4847 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004848 }
4849 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
4850 size_t count, loff_t off) {
4851 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004852 return LSS_NAME(_pwrite64)(fd, buf, count,
4853 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004854 }
4855 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {
4856 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004857 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004858 }
4859 #endif
4860#endif
4861
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004862/*
4863 * Polyfills for deprecated syscalls.
4864 */
4865
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004866#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004867 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
4868 return LSS_NAME(dup3)(s, d, 0);
4869 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004870#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004871
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004872#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004873 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
4874 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
4875 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004876#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004877
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004878#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004879 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
4880 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
4881 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004882#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004883
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004884#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004885 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
4886 size_t size) {
4887 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
4888 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004889#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004890
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004891#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05004892 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004893 return LSS_NAME(pipe2)(pipefd, 0);
4894 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004895#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004896
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004897#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004898 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
4899 int timeout) {
4900 struct kernel_timespec timeout_ts;
4901 struct kernel_timespec *timeout_ts_p = NULL;
4902
4903 if (timeout >= 0) {
4904 timeout_ts.tv_sec = timeout / 1000;
4905 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
4906 timeout_ts_p = &timeout_ts;
4907 }
4908 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
4909 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004910#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004911
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004912#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004913 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
4914 struct kernel_stat *buf) {
4915 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
4916 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004917#endif
Matthew Denton92a65a82021-04-01 13:00:07 -07004918#if !defined(__NR_lstat)
4919 LSS_INLINE int LSS_NAME(lstat)(const char *pathname,
4920 struct kernel_stat *buf) {
4921 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW);
4922 }
4923#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004924
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004925#if !defined(__NR_waitpid)
4926 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
4927 return LSS_NAME(wait4)(pid, status, options, 0);
4928 }
4929#endif
4930
4931#if !defined(__NR_fork)
4932// TODO: define this in an arch-independant way instead of inlining the clone
4933// syscall body.
4934
Andreas Schwab1d387f42022-02-15 16:21:13 +01004935# if defined(__aarch64__) || defined(__riscv)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004936 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4937 // No fork syscall on aarch64 - implement by means of the clone syscall.
4938 // Note that this does not reset glibc's cached view of the PID/TID, so
4939 // some glibc interfaces might go wrong in the forked subprocess.
4940 int flags = SIGCHLD;
4941 void *child_stack = NULL;
4942 void *parent_tidptr = NULL;
4943 void *newtls = NULL;
4944 void *child_tidptr = NULL;
4945
4946 LSS_REG(0, flags);
4947 LSS_REG(1, child_stack);
4948 LSS_REG(2, parent_tidptr);
4949 LSS_REG(3, newtls);
4950 LSS_REG(4, child_tidptr);
4951 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
4952 "r"(__r4));
4953 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004954# elif defined(__x86_64__)
4955 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4956 // Android disallows the fork syscall on x86_64 - implement by means of the
4957 // clone syscall as above for aarch64.
4958 int flags = SIGCHLD;
4959 void *child_stack = NULL;
4960 void *parent_tidptr = NULL;
4961 void *newtls = NULL;
4962 void *child_tidptr = NULL;
4963
4964 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
4965 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
4966 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
4967 }
4968# else
4969# error missing fork polyfill for this architecture
4970# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004971#endif
4972
Michael Forneyf70e2f12020-01-22 19:19:38 -08004973/* These restore the original values of these macros saved by the
4974 * corresponding #pragma push_macro near the top of this file. */
4975#pragma pop_macro("stat64")
4976#pragma pop_macro("fstat64")
4977#pragma pop_macro("lstat64")
4978#pragma pop_macro("pread64")
4979#pragma pop_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -07004980#pragma pop_macro("getdents64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00004981
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004982#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
4983}
4984#endif
4985
4986#endif
4987#endif