blob: 2664b72ee7c6323c838130010011241db04057fb [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__) || \
mingtaoxt xtc0c96892022-08-11 16:53:21 +080092 (defined(__riscv) && __riscv_xlen == 64) || defined(__loongarch_lp64)) \
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
Doug Kwan32a80cd2022-07-01 17:52:39 +0000270/* include/linux/time.h */
271struct kernel_itimerval {
272 struct kernel_timeval it_interval;
273 struct kernel_timeval it_value;
274};
275
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000276/* include/linux/resource.h */
277struct kernel_rusage {
278 struct kernel_timeval ru_utime;
279 struct kernel_timeval ru_stime;
280 long ru_maxrss;
281 long ru_ixrss;
282 long ru_idrss;
283 long ru_isrss;
284 long ru_minflt;
285 long ru_majflt;
286 long ru_nswap;
287 long ru_inblock;
288 long ru_oublock;
289 long ru_msgsnd;
290 long ru_msgrcv;
291 long ru_nsignals;
292 long ru_nvcsw;
293 long ru_nivcsw;
294};
295
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000296#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300297 || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) \
298 || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000299
300/* include/asm-{arm,i386,mips,ppc}/signal.h */
301struct kernel_old_sigaction {
302 union {
303 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000304 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000305 };
306 unsigned long sa_mask;
307 unsigned long sa_flags;
308 void (*sa_restorer)(void);
309} __attribute__((packed,aligned(4)));
310#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
311 #define kernel_old_sigaction kernel_sigaction
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800312#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
313 // No kernel_old_sigaction defined for arm64 riscv and loongarch64.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000314#endif
315
316/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
317 * exactly match the size of the signal set, even though the API was
318 * intended to be extensible. We define our own KERNEL_NSIG to deal with
319 * this.
320 * Please note that glibc provides signals [1.._NSIG-1], whereas the
321 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
322 * actual number of signals is obviously the same, but the constants
323 * differ by one.
324 */
325#ifdef __mips__
326#define KERNEL_NSIG 128
327#else
328#define KERNEL_NSIG 64
329#endif
330
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000331/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000332struct kernel_sigset_t {
333 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
334 (8*sizeof(unsigned long))];
335};
336
337/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
338struct kernel_sigaction {
339#ifdef __mips__
340 unsigned long sa_flags;
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 struct kernel_sigset_t sa_mask;
346#else
347 union {
348 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000349 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000350 };
351 unsigned long sa_flags;
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800352#if !defined(__riscv) && !defined(__loongarch_lp64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000353 void (*sa_restorer)(void);
Andreas Schwab1d387f42022-02-15 16:21:13 +0100354#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000355 struct kernel_sigset_t sa_mask;
356#endif
357};
358
359/* include/linux/socket.h */
360struct kernel_sockaddr {
361 unsigned short sa_family;
362 char sa_data[14];
363};
364
Bryan Chan3f6478a2016-06-14 08:38:17 -0400365/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000366#ifdef __mips__
367#if _MIPS_SIM == _MIPS_SIM_ABI64
368struct kernel_stat {
369#else
370struct kernel_stat64 {
371#endif
372 unsigned st_dev;
373 unsigned __pad0[3];
374 unsigned long long st_ino;
375 unsigned st_mode;
376 unsigned st_nlink;
377 unsigned st_uid;
378 unsigned st_gid;
379 unsigned st_rdev;
380 unsigned __pad1[3];
381 long long st_size;
382 unsigned st_atime_;
383 unsigned st_atime_nsec_;
384 unsigned st_mtime_;
385 unsigned st_mtime_nsec_;
386 unsigned st_ctime_;
387 unsigned st_ctime_nsec_;
388 unsigned st_blksize;
389 unsigned __pad2;
390 unsigned long long st_blocks;
391};
392#elif defined __PPC__
393struct kernel_stat64 {
394 unsigned long long st_dev;
395 unsigned long long st_ino;
396 unsigned st_mode;
397 unsigned st_nlink;
398 unsigned st_uid;
399 unsigned st_gid;
400 unsigned long long st_rdev;
401 unsigned short int __pad2;
402 long long st_size;
403 long st_blksize;
404 long long st_blocks;
405 long st_atime_;
406 unsigned long st_atime_nsec_;
407 long st_mtime_;
408 unsigned long st_mtime_nsec_;
409 long st_ctime_;
410 unsigned long st_ctime_nsec_;
411 unsigned long __unused4;
412 unsigned long __unused5;
413};
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300414#elif defined(__e2k__)
415struct kernel_stat64 {
416 unsigned long long st_dev;
417 unsigned long long st_ino;
418 unsigned int st_mode;
419 unsigned int st_nlink;
420 unsigned int st_uid;
421 unsigned int st_gid;
422 unsigned long long st_rdev;
423 long long st_size;
424 int st_blksize;
425 int __pad2;
426 unsigned long long st_blocks;
427 int st_atime_;
428 unsigned int st_atime_nsec_;
429 int st_mtime_;
430 unsigned int st_mtime_nsec_;
431 int st_ctime_;
432 unsigned int st_ctime_nsec_;
433 unsigned int __unused4;
434 unsigned int __unused5;
435};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000436#else
437struct kernel_stat64 {
438 unsigned long long st_dev;
439 unsigned char __pad0[4];
440 unsigned __st_ino;
441 unsigned st_mode;
442 unsigned st_nlink;
443 unsigned st_uid;
444 unsigned st_gid;
445 unsigned long long st_rdev;
446 unsigned char __pad3[4];
447 long long st_size;
448 unsigned st_blksize;
449 unsigned long long st_blocks;
450 unsigned st_atime_;
451 unsigned st_atime_nsec_;
452 unsigned st_mtime_;
453 unsigned st_mtime_nsec_;
454 unsigned st_ctime_;
455 unsigned st_ctime_nsec_;
456 unsigned long long st_ino;
457};
458#endif
459
Bryan Chan3f6478a2016-06-14 08:38:17 -0400460/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000461#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
462struct kernel_stat {
463 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
464 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
465 * format. In reality, we do not see useful data in the top bits. So,
466 * we'll leave the padding in here, until we find a better solution.
467 */
468 unsigned short st_dev;
469 short pad1;
470 unsigned st_ino;
471 unsigned short st_mode;
472 unsigned short st_nlink;
473 unsigned short st_uid;
474 unsigned short st_gid;
475 unsigned short st_rdev;
476 short pad2;
477 unsigned st_size;
478 unsigned st_blksize;
479 unsigned st_blocks;
480 unsigned st_atime_;
481 unsigned st_atime_nsec_;
482 unsigned st_mtime_;
483 unsigned st_mtime_nsec_;
484 unsigned st_ctime_;
485 unsigned st_ctime_nsec_;
486 unsigned __unused4;
487 unsigned __unused5;
488};
489#elif defined(__x86_64__)
490struct kernel_stat {
vapier@chromium.org2273e812013-04-01 17:52:44 +0000491 uint64_t st_dev;
492 uint64_t st_ino;
493 uint64_t st_nlink;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000494 unsigned st_mode;
495 unsigned st_uid;
496 unsigned st_gid;
497 unsigned __pad0;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000498 uint64_t st_rdev;
499 int64_t st_size;
500 int64_t st_blksize;
501 int64_t st_blocks;
502 uint64_t st_atime_;
503 uint64_t st_atime_nsec_;
504 uint64_t st_mtime_;
505 uint64_t st_mtime_nsec_;
506 uint64_t st_ctime_;
507 uint64_t st_ctime_nsec_;
anton@chromium.org43de0522014-04-04 11:20:46 +0000508 int64_t __unused4[3];
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000509};
510#elif defined(__PPC__)
511struct kernel_stat {
512 unsigned st_dev;
513 unsigned long st_ino; // ino_t
514 unsigned long st_mode; // mode_t
515 unsigned short st_nlink; // nlink_t
516 unsigned st_uid; // uid_t
517 unsigned st_gid; // gid_t
518 unsigned st_rdev;
519 long st_size; // off_t
520 unsigned long st_blksize;
521 unsigned long st_blocks;
522 unsigned long st_atime_;
523 unsigned long st_atime_nsec_;
524 unsigned long st_mtime_;
525 unsigned long st_mtime_nsec_;
526 unsigned long st_ctime_;
527 unsigned long st_ctime_nsec_;
528 unsigned long __unused4;
529 unsigned long __unused5;
530};
531#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
532struct kernel_stat {
533 unsigned st_dev;
534 int st_pad1[3];
535 unsigned st_ino;
536 unsigned st_mode;
537 unsigned st_nlink;
538 unsigned st_uid;
539 unsigned st_gid;
540 unsigned st_rdev;
541 int st_pad2[2];
542 long st_size;
543 int st_pad3;
544 long st_atime_;
545 long st_atime_nsec_;
546 long st_mtime_;
547 long st_mtime_nsec_;
548 long st_ctime_;
549 long st_ctime_nsec_;
550 int st_blksize;
551 int st_blocks;
552 int st_pad4[14];
553};
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800554#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000555struct kernel_stat {
556 unsigned long st_dev;
557 unsigned long st_ino;
558 unsigned int st_mode;
559 unsigned int st_nlink;
560 unsigned int st_uid;
561 unsigned int st_gid;
562 unsigned long st_rdev;
563 unsigned long __pad1;
564 long st_size;
565 int st_blksize;
566 int __pad2;
567 long st_blocks;
568 long st_atime_;
569 unsigned long st_atime_nsec_;
570 long st_mtime_;
571 unsigned long st_mtime_nsec_;
572 long st_ctime_;
573 unsigned long st_ctime_nsec_;
574 unsigned int __unused4;
575 unsigned int __unused5;
576};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400577#elif defined(__s390x__)
578struct kernel_stat {
579 unsigned long st_dev;
580 unsigned long st_ino;
581 unsigned long st_nlink;
582 unsigned int st_mode;
583 unsigned int st_uid;
584 unsigned int st_gid;
585 unsigned int __pad1;
586 unsigned long st_rdev;
587 unsigned long st_size;
588 unsigned long st_atime_;
589 unsigned long st_atime_nsec_;
590 unsigned long st_mtime_;
591 unsigned long st_mtime_nsec_;
592 unsigned long st_ctime_;
593 unsigned long st_ctime_nsec_;
594 unsigned long st_blksize;
595 long st_blocks;
596 unsigned long __unused[3];
597};
598#elif defined(__s390__)
599struct kernel_stat {
600 unsigned short st_dev;
601 unsigned short __pad1;
602 unsigned long st_ino;
603 unsigned short st_mode;
604 unsigned short st_nlink;
605 unsigned short st_uid;
606 unsigned short st_gid;
607 unsigned short st_rdev;
608 unsigned short __pad2;
609 unsigned long st_size;
610 unsigned long st_blksize;
611 unsigned long st_blocks;
612 unsigned long st_atime_;
613 unsigned long st_atime_nsec_;
614 unsigned long st_mtime_;
615 unsigned long st_mtime_nsec_;
616 unsigned long st_ctime_;
617 unsigned long st_ctime_nsec_;
618 unsigned long __unused4;
619 unsigned long __unused5;
620};
Konstantin Ivlev8007b272021-01-27 18:27:42 +0300621#elif defined(__e2k__)
622struct kernel_stat {
623 unsigned long st_dev;
624 unsigned long st_ino;
625 unsigned int st_mode;
626 unsigned long st_nlink;
627 unsigned int st_uid;
628 unsigned int st_gid;
629 unsigned long st_rdev;
630 unsigned long st_size;
631 unsigned long st_blksize;
632 unsigned long st_blocks;
633 unsigned long st_atime_;
634 unsigned long st_atime_nsec_;
635 unsigned long st_mtime_;
636 unsigned long st_mtime_nsec_;
637 unsigned long st_ctime_;
638 unsigned long st_ctime_nsec_;
639};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000640#endif
641
Bryan Chan3f6478a2016-06-14 08:38:17 -0400642/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000643#ifdef __mips__
644#if _MIPS_SIM != _MIPS_SIM_ABI64
645struct kernel_statfs64 {
646 unsigned long f_type;
647 unsigned long f_bsize;
648 unsigned long f_frsize;
649 unsigned long __pad;
650 unsigned long long f_blocks;
651 unsigned long long f_bfree;
652 unsigned long long f_files;
653 unsigned long long f_ffree;
654 unsigned long long f_bavail;
655 struct { int val[2]; } f_fsid;
656 unsigned long f_namelen;
657 unsigned long f_spare[6];
658};
659#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -0400660#elif defined(__s390__)
661/* See also arch/s390/include/asm/compat.h */
662struct kernel_statfs64 {
663 unsigned int f_type;
664 unsigned int f_bsize;
665 unsigned long long f_blocks;
666 unsigned long long f_bfree;
667 unsigned long long f_bavail;
668 unsigned long long f_files;
669 unsigned long long f_ffree;
670 struct { int val[2]; } f_fsid;
671 unsigned int f_namelen;
672 unsigned int f_frsize;
673 unsigned int f_flags;
674 unsigned int f_spare[4];
675};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000676#elif !defined(__x86_64__)
677struct kernel_statfs64 {
678 unsigned long f_type;
679 unsigned long f_bsize;
680 unsigned long long f_blocks;
681 unsigned long long f_bfree;
682 unsigned long long f_bavail;
683 unsigned long long f_files;
684 unsigned long long f_ffree;
685 struct { int val[2]; } f_fsid;
686 unsigned long f_namelen;
687 unsigned long f_frsize;
688 unsigned long f_spare[5];
689};
690#endif
691
Bryan Chan3f6478a2016-06-14 08:38:17 -0400692/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000693#ifdef __mips__
694struct kernel_statfs {
695 long f_type;
696 long f_bsize;
697 long f_frsize;
698 long f_blocks;
699 long f_bfree;
700 long f_files;
701 long f_ffree;
702 long f_bavail;
703 struct { int val[2]; } f_fsid;
704 long f_namelen;
705 long f_spare[6];
706};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000707#elif defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000708struct kernel_statfs {
709 /* x86_64 actually defines all these fields as signed, whereas all other */
710 /* platforms define them as unsigned. Leaving them at unsigned should not */
vapier@chromium.org2273e812013-04-01 17:52:44 +0000711 /* cause any problems. Make sure these are 64-bit even on x32. */
712 uint64_t f_type;
713 uint64_t f_bsize;
714 uint64_t f_blocks;
715 uint64_t f_bfree;
716 uint64_t f_bavail;
717 uint64_t f_files;
718 uint64_t f_ffree;
719 struct { int val[2]; } f_fsid;
720 uint64_t f_namelen;
721 uint64_t f_frsize;
722 uint64_t f_spare[5];
723};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400724#elif defined(__s390__)
725struct kernel_statfs {
726 unsigned int f_type;
727 unsigned int f_bsize;
728 unsigned long f_blocks;
729 unsigned long f_bfree;
730 unsigned long f_bavail;
731 unsigned long f_files;
732 unsigned long f_ffree;
733 struct { int val[2]; } f_fsid;
734 unsigned int f_namelen;
735 unsigned int f_frsize;
736 unsigned int f_flags;
737 unsigned int f_spare[4];
738};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000739#else
740struct kernel_statfs {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000741 unsigned long f_type;
742 unsigned long f_bsize;
743 unsigned long f_blocks;
744 unsigned long f_bfree;
745 unsigned long f_bavail;
746 unsigned long f_files;
747 unsigned long f_ffree;
748 struct { int val[2]; } f_fsid;
749 unsigned long f_namelen;
750 unsigned long f_frsize;
751 unsigned long f_spare[5];
752};
753#endif
754
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800755struct kernel_statx_timestamp {
756 int64_t tv_sec;
757 uint32_t tv_nsec;
758 int32_t __reserved;
759};
760
761struct kernel_statx {
762 uint32_t stx_mask;
763 uint32_t stx_blksize;
764 uint64_t stx_attributes;
765 uint32_t stx_nlink;
766 uint32_t stx_uid;
767 uint32_t stx_gid;
768 uint16_t stx_mode;
769 uint16_t __spare0[1];
770 uint64_t stx_ino;
771 uint64_t stx_size;
772 uint64_t stx_blocks;
773 uint64_t stx_attributes_mask;
774 struct kernel_statx_timestamp stx_atime;
775 struct kernel_statx_timestamp stx_btime;
776 struct kernel_statx_timestamp stx_ctime;
777 struct kernel_statx_timestamp stx_mtime;
778 uint32_t stx_rdev_major;
779 uint32_t stx_rdev_minor;
780 uint32_t stx_dev_major;
781 uint32_t stx_dev_minor;
782 uint64_t stx_mnt_id;
783 uint64_t __spare2;
784 uint64_t __spare3[12];
785};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000786
787/* Definitions missing from the standard header files */
788#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000789#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000790#define O_DIRECTORY 0040000
791#else
792#define O_DIRECTORY 0200000
793#endif
794#endif
795#ifndef NT_PRXFPREG
796#define NT_PRXFPREG 0x46e62b7f
797#endif
798#ifndef PTRACE_GETFPXREGS
799#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
800#endif
801#ifndef PR_GET_DUMPABLE
802#define PR_GET_DUMPABLE 3
803#endif
804#ifndef PR_SET_DUMPABLE
805#define PR_SET_DUMPABLE 4
806#endif
807#ifndef PR_GET_SECCOMP
808#define PR_GET_SECCOMP 21
809#endif
810#ifndef PR_SET_SECCOMP
811#define PR_SET_SECCOMP 22
812#endif
813#ifndef AT_FDCWD
814#define AT_FDCWD (-100)
815#endif
816#ifndef AT_SYMLINK_NOFOLLOW
817#define AT_SYMLINK_NOFOLLOW 0x100
818#endif
819#ifndef AT_REMOVEDIR
820#define AT_REMOVEDIR 0x200
821#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +0800822#ifndef AT_NO_AUTOMOUNT
823#define AT_NO_AUTOMOUNT 0x800
824#endif
825#ifndef AT_EMPTY_PATH
826#define AT_EMPTY_PATH 0x1000
827#endif
828#ifndef STATX_BASIC_STATS
829#define STATX_BASIC_STATS 0x000007ffU
830#endif
831#ifndef AT_STATX_SYNC_AS_STAT
832#define AT_STATX_SYNC_AS_STAT 0x0000
833#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000834#ifndef MREMAP_FIXED
835#define MREMAP_FIXED 2
836#endif
837#ifndef SA_RESTORER
838#define SA_RESTORER 0x04000000
839#endif
840#ifndef CPUCLOCK_PROF
841#define CPUCLOCK_PROF 0
842#endif
843#ifndef CPUCLOCK_VIRT
844#define CPUCLOCK_VIRT 1
845#endif
846#ifndef CPUCLOCK_SCHED
847#define CPUCLOCK_SCHED 2
848#endif
849#ifndef CPUCLOCK_PERTHREAD_MASK
850#define CPUCLOCK_PERTHREAD_MASK 4
851#endif
852#ifndef MAKE_PROCESS_CPUCLOCK
853#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400854 ((int)(~(unsigned)(pid) << 3) | (int)(clock))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000855#endif
856#ifndef MAKE_THREAD_CPUCLOCK
857#define MAKE_THREAD_CPUCLOCK(tid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400858 ((int)(~(unsigned)(tid) << 3) | \
859 (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000860#endif
861
862#ifndef FUTEX_WAIT
863#define FUTEX_WAIT 0
864#endif
865#ifndef FUTEX_WAKE
866#define FUTEX_WAKE 1
867#endif
868#ifndef FUTEX_FD
869#define FUTEX_FD 2
870#endif
871#ifndef FUTEX_REQUEUE
872#define FUTEX_REQUEUE 3
873#endif
874#ifndef FUTEX_CMP_REQUEUE
875#define FUTEX_CMP_REQUEUE 4
876#endif
877#ifndef FUTEX_WAKE_OP
878#define FUTEX_WAKE_OP 5
879#endif
880#ifndef FUTEX_LOCK_PI
881#define FUTEX_LOCK_PI 6
882#endif
883#ifndef FUTEX_UNLOCK_PI
884#define FUTEX_UNLOCK_PI 7
885#endif
886#ifndef FUTEX_TRYLOCK_PI
887#define FUTEX_TRYLOCK_PI 8
888#endif
889#ifndef FUTEX_PRIVATE_FLAG
890#define FUTEX_PRIVATE_FLAG 128
891#endif
892#ifndef FUTEX_CMD_MASK
893#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
894#endif
895#ifndef FUTEX_WAIT_PRIVATE
896#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
897#endif
898#ifndef FUTEX_WAKE_PRIVATE
899#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
900#endif
901#ifndef FUTEX_REQUEUE_PRIVATE
902#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
903#endif
904#ifndef FUTEX_CMP_REQUEUE_PRIVATE
905#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
906#endif
907#ifndef FUTEX_WAKE_OP_PRIVATE
908#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
909#endif
910#ifndef FUTEX_LOCK_PI_PRIVATE
911#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
912#endif
913#ifndef FUTEX_UNLOCK_PI_PRIVATE
914#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
915#endif
916#ifndef FUTEX_TRYLOCK_PI_PRIVATE
917#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
918#endif
919
920
921#if defined(__x86_64__)
922#ifndef ARCH_SET_GS
923#define ARCH_SET_GS 0x1001
924#endif
925#ifndef ARCH_GET_GS
926#define ARCH_GET_GS 0x1004
927#endif
928#endif
929
930#if defined(__i386__)
931#ifndef __NR_quotactl
932#define __NR_quotactl 131
933#endif
934#ifndef __NR_setresuid
935#define __NR_setresuid 164
936#define __NR_getresuid 165
937#define __NR_setresgid 170
938#define __NR_getresgid 171
939#endif
940#ifndef __NR_rt_sigaction
941#define __NR_rt_sigreturn 173
942#define __NR_rt_sigaction 174
943#define __NR_rt_sigprocmask 175
944#define __NR_rt_sigpending 176
945#define __NR_rt_sigsuspend 179
946#endif
947#ifndef __NR_pread64
948#define __NR_pread64 180
949#endif
950#ifndef __NR_pwrite64
951#define __NR_pwrite64 181
952#endif
953#ifndef __NR_ugetrlimit
954#define __NR_ugetrlimit 191
955#endif
956#ifndef __NR_stat64
957#define __NR_stat64 195
958#endif
959#ifndef __NR_fstat64
960#define __NR_fstat64 197
961#endif
962#ifndef __NR_setresuid32
963#define __NR_setresuid32 208
964#define __NR_getresuid32 209
965#define __NR_setresgid32 210
966#define __NR_getresgid32 211
967#endif
968#ifndef __NR_setfsuid32
969#define __NR_setfsuid32 215
970#define __NR_setfsgid32 216
971#endif
972#ifndef __NR_getdents64
973#define __NR_getdents64 220
974#endif
975#ifndef __NR_gettid
976#define __NR_gettid 224
977#endif
978#ifndef __NR_readahead
979#define __NR_readahead 225
980#endif
981#ifndef __NR_setxattr
982#define __NR_setxattr 226
983#endif
984#ifndef __NR_lsetxattr
985#define __NR_lsetxattr 227
986#endif
987#ifndef __NR_getxattr
988#define __NR_getxattr 229
989#endif
990#ifndef __NR_lgetxattr
991#define __NR_lgetxattr 230
992#endif
993#ifndef __NR_listxattr
994#define __NR_listxattr 232
995#endif
996#ifndef __NR_llistxattr
997#define __NR_llistxattr 233
998#endif
999#ifndef __NR_tkill
1000#define __NR_tkill 238
1001#endif
1002#ifndef __NR_futex
1003#define __NR_futex 240
1004#endif
1005#ifndef __NR_sched_setaffinity
1006#define __NR_sched_setaffinity 241
1007#define __NR_sched_getaffinity 242
1008#endif
1009#ifndef __NR_set_tid_address
1010#define __NR_set_tid_address 258
1011#endif
1012#ifndef __NR_clock_gettime
1013#define __NR_clock_gettime 265
1014#endif
1015#ifndef __NR_clock_getres
1016#define __NR_clock_getres 266
1017#endif
1018#ifndef __NR_statfs64
1019#define __NR_statfs64 268
1020#endif
1021#ifndef __NR_fstatfs64
1022#define __NR_fstatfs64 269
1023#endif
1024#ifndef __NR_fadvise64_64
1025#define __NR_fadvise64_64 272
1026#endif
1027#ifndef __NR_ioprio_set
1028#define __NR_ioprio_set 289
1029#endif
1030#ifndef __NR_ioprio_get
1031#define __NR_ioprio_get 290
1032#endif
1033#ifndef __NR_openat
1034#define __NR_openat 295
1035#endif
1036#ifndef __NR_fstatat64
1037#define __NR_fstatat64 300
1038#endif
1039#ifndef __NR_unlinkat
1040#define __NR_unlinkat 301
1041#endif
1042#ifndef __NR_move_pages
1043#define __NR_move_pages 317
1044#endif
1045#ifndef __NR_getcpu
1046#define __NR_getcpu 318
1047#endif
1048#ifndef __NR_fallocate
1049#define __NR_fallocate 324
1050#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001051#ifndef __NR_getrandom
1052#define __NR_getrandom 355
1053#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001054/* End of i386 definitions */
1055#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
1056#ifndef __NR_setresuid
1057#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
1058#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
1059#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
1060#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
1061#endif
1062#ifndef __NR_rt_sigaction
1063#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
1064#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
1065#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
1066#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
1067#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
1068#endif
1069#ifndef __NR_pread64
1070#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
1071#endif
1072#ifndef __NR_pwrite64
1073#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
1074#endif
1075#ifndef __NR_ugetrlimit
1076#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
1077#endif
1078#ifndef __NR_stat64
1079#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
1080#endif
1081#ifndef __NR_fstat64
1082#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
1083#endif
1084#ifndef __NR_setresuid32
1085#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
1086#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
1087#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
1088#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
1089#endif
1090#ifndef __NR_setfsuid32
1091#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
1092#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
1093#endif
1094#ifndef __NR_getdents64
1095#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
1096#endif
1097#ifndef __NR_gettid
1098#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1099#endif
1100#ifndef __NR_readahead
1101#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1102#endif
1103#ifndef __NR_setxattr
1104#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1105#endif
1106#ifndef __NR_lsetxattr
1107#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1108#endif
1109#ifndef __NR_getxattr
1110#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1111#endif
1112#ifndef __NR_lgetxattr
1113#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1114#endif
1115#ifndef __NR_listxattr
1116#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1117#endif
1118#ifndef __NR_llistxattr
1119#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1120#endif
1121#ifndef __NR_tkill
1122#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1123#endif
1124#ifndef __NR_futex
1125#define __NR_futex (__NR_SYSCALL_BASE + 240)
1126#endif
1127#ifndef __NR_sched_setaffinity
1128#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1129#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1130#endif
1131#ifndef __NR_set_tid_address
1132#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1133#endif
1134#ifndef __NR_clock_gettime
1135#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1136#endif
1137#ifndef __NR_clock_getres
1138#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1139#endif
1140#ifndef __NR_statfs64
1141#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1142#endif
1143#ifndef __NR_fstatfs64
1144#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1145#endif
1146#ifndef __NR_ioprio_set
1147#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1148#endif
1149#ifndef __NR_ioprio_get
1150#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1151#endif
Matthew Denton92a65a82021-04-01 13:00:07 -07001152#ifndef __NR_fstatat64
1153#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
1154#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001155#ifndef __NR_move_pages
1156#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1157#endif
1158#ifndef __NR_getcpu
1159#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1160#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001161#ifndef __NR_getrandom
1162#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
1163#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001164/* End of ARM 3/EABI definitions */
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001165#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001166#ifndef __NR_setxattr
1167#define __NR_setxattr 5
1168#endif
1169#ifndef __NR_lsetxattr
1170#define __NR_lsetxattr 6
1171#endif
1172#ifndef __NR_getxattr
1173#define __NR_getxattr 8
1174#endif
1175#ifndef __NR_lgetxattr
1176#define __NR_lgetxattr 9
1177#endif
1178#ifndef __NR_listxattr
1179#define __NR_listxattr 11
1180#endif
1181#ifndef __NR_llistxattr
1182#define __NR_llistxattr 12
1183#endif
1184#ifndef __NR_ioprio_set
1185#define __NR_ioprio_set 30
1186#endif
1187#ifndef __NR_ioprio_get
1188#define __NR_ioprio_get 31
1189#endif
1190#ifndef __NR_unlinkat
1191#define __NR_unlinkat 35
1192#endif
1193#ifndef __NR_fallocate
1194#define __NR_fallocate 47
1195#endif
1196#ifndef __NR_openat
1197#define __NR_openat 56
1198#endif
1199#ifndef __NR_quotactl
1200#define __NR_quotactl 60
1201#endif
1202#ifndef __NR_getdents64
1203#define __NR_getdents64 61
1204#endif
1205#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001206// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001207#define __NR_getdents __NR_getdents64
1208#endif
1209#ifndef __NR_pread64
1210#define __NR_pread64 67
1211#endif
1212#ifndef __NR_pwrite64
1213#define __NR_pwrite64 68
1214#endif
1215#ifndef __NR_ppoll
1216#define __NR_ppoll 73
1217#endif
1218#ifndef __NR_readlinkat
1219#define __NR_readlinkat 78
1220#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001221#if !defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001222#ifndef __NR_newfstatat
1223#define __NR_newfstatat 79
1224#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001225#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001226#ifndef __NR_set_tid_address
1227#define __NR_set_tid_address 96
1228#endif
1229#ifndef __NR_futex
1230#define __NR_futex 98
1231#endif
1232#ifndef __NR_clock_gettime
1233#define __NR_clock_gettime 113
1234#endif
1235#ifndef __NR_clock_getres
1236#define __NR_clock_getres 114
1237#endif
1238#ifndef __NR_sched_setaffinity
1239#define __NR_sched_setaffinity 122
1240#define __NR_sched_getaffinity 123
1241#endif
1242#ifndef __NR_tkill
1243#define __NR_tkill 130
1244#endif
1245#ifndef __NR_setresuid
1246#define __NR_setresuid 147
1247#define __NR_getresuid 148
1248#define __NR_setresgid 149
1249#define __NR_getresgid 150
1250#endif
1251#ifndef __NR_gettid
1252#define __NR_gettid 178
1253#endif
1254#ifndef __NR_readahead
1255#define __NR_readahead 213
1256#endif
1257#ifndef __NR_fadvise64
1258#define __NR_fadvise64 223
1259#endif
1260#ifndef __NR_move_pages
1261#define __NR_move_pages 239
1262#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001263#ifndef __NR_getrandom
1264#define __NR_getrandom 278
1265#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001266#ifndef __NR_statx
1267#define __NR_statx 291
1268#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001269#elif defined(__x86_64__)
1270#ifndef __NR_pread64
1271#define __NR_pread64 17
1272#endif
1273#ifndef __NR_pwrite64
1274#define __NR_pwrite64 18
1275#endif
1276#ifndef __NR_setresuid
1277#define __NR_setresuid 117
1278#define __NR_getresuid 118
1279#define __NR_setresgid 119
1280#define __NR_getresgid 120
1281#endif
1282#ifndef __NR_quotactl
1283#define __NR_quotactl 179
1284#endif
1285#ifndef __NR_gettid
1286#define __NR_gettid 186
1287#endif
1288#ifndef __NR_readahead
1289#define __NR_readahead 187
1290#endif
1291#ifndef __NR_setxattr
1292#define __NR_setxattr 188
1293#endif
1294#ifndef __NR_lsetxattr
1295#define __NR_lsetxattr 189
1296#endif
1297#ifndef __NR_getxattr
1298#define __NR_getxattr 191
1299#endif
1300#ifndef __NR_lgetxattr
1301#define __NR_lgetxattr 192
1302#endif
1303#ifndef __NR_listxattr
1304#define __NR_listxattr 194
1305#endif
1306#ifndef __NR_llistxattr
1307#define __NR_llistxattr 195
1308#endif
1309#ifndef __NR_tkill
1310#define __NR_tkill 200
1311#endif
1312#ifndef __NR_futex
1313#define __NR_futex 202
1314#endif
1315#ifndef __NR_sched_setaffinity
1316#define __NR_sched_setaffinity 203
1317#define __NR_sched_getaffinity 204
1318#endif
1319#ifndef __NR_getdents64
1320#define __NR_getdents64 217
1321#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001322#ifndef __NR_getdents
1323// when getdents is not available, getdents64 is used for both.
1324#define __NR_getdents __NR_getdents64
1325#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001326#ifndef __NR_set_tid_address
1327#define __NR_set_tid_address 218
1328#endif
1329#ifndef __NR_fadvise64
1330#define __NR_fadvise64 221
1331#endif
1332#ifndef __NR_clock_gettime
1333#define __NR_clock_gettime 228
1334#endif
1335#ifndef __NR_clock_getres
1336#define __NR_clock_getres 229
1337#endif
1338#ifndef __NR_ioprio_set
1339#define __NR_ioprio_set 251
1340#endif
1341#ifndef __NR_ioprio_get
1342#define __NR_ioprio_get 252
1343#endif
1344#ifndef __NR_openat
1345#define __NR_openat 257
1346#endif
1347#ifndef __NR_newfstatat
1348#define __NR_newfstatat 262
1349#endif
1350#ifndef __NR_unlinkat
1351#define __NR_unlinkat 263
1352#endif
1353#ifndef __NR_move_pages
1354#define __NR_move_pages 279
1355#endif
1356#ifndef __NR_fallocate
1357#define __NR_fallocate 285
1358#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001359#ifndef __NR_getrandom
1360#define __NR_getrandom 318
1361#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001362/* End of x86-64 definitions */
1363#elif defined(__mips__)
1364#if _MIPS_SIM == _MIPS_SIM_ABI32
1365#ifndef __NR_setresuid
1366#define __NR_setresuid (__NR_Linux + 185)
1367#define __NR_getresuid (__NR_Linux + 186)
1368#define __NR_setresgid (__NR_Linux + 190)
1369#define __NR_getresgid (__NR_Linux + 191)
1370#endif
1371#ifndef __NR_rt_sigaction
1372#define __NR_rt_sigreturn (__NR_Linux + 193)
1373#define __NR_rt_sigaction (__NR_Linux + 194)
1374#define __NR_rt_sigprocmask (__NR_Linux + 195)
1375#define __NR_rt_sigpending (__NR_Linux + 196)
1376#define __NR_rt_sigsuspend (__NR_Linux + 199)
1377#endif
1378#ifndef __NR_pread64
1379#define __NR_pread64 (__NR_Linux + 200)
1380#endif
1381#ifndef __NR_pwrite64
1382#define __NR_pwrite64 (__NR_Linux + 201)
1383#endif
1384#ifndef __NR_stat64
1385#define __NR_stat64 (__NR_Linux + 213)
1386#endif
1387#ifndef __NR_fstat64
1388#define __NR_fstat64 (__NR_Linux + 215)
1389#endif
1390#ifndef __NR_getdents64
1391#define __NR_getdents64 (__NR_Linux + 219)
1392#endif
1393#ifndef __NR_gettid
1394#define __NR_gettid (__NR_Linux + 222)
1395#endif
1396#ifndef __NR_readahead
1397#define __NR_readahead (__NR_Linux + 223)
1398#endif
1399#ifndef __NR_setxattr
1400#define __NR_setxattr (__NR_Linux + 224)
1401#endif
1402#ifndef __NR_lsetxattr
1403#define __NR_lsetxattr (__NR_Linux + 225)
1404#endif
1405#ifndef __NR_getxattr
1406#define __NR_getxattr (__NR_Linux + 227)
1407#endif
1408#ifndef __NR_lgetxattr
1409#define __NR_lgetxattr (__NR_Linux + 228)
1410#endif
1411#ifndef __NR_listxattr
1412#define __NR_listxattr (__NR_Linux + 230)
1413#endif
1414#ifndef __NR_llistxattr
1415#define __NR_llistxattr (__NR_Linux + 231)
1416#endif
1417#ifndef __NR_tkill
1418#define __NR_tkill (__NR_Linux + 236)
1419#endif
1420#ifndef __NR_futex
1421#define __NR_futex (__NR_Linux + 238)
1422#endif
1423#ifndef __NR_sched_setaffinity
1424#define __NR_sched_setaffinity (__NR_Linux + 239)
1425#define __NR_sched_getaffinity (__NR_Linux + 240)
1426#endif
1427#ifndef __NR_set_tid_address
1428#define __NR_set_tid_address (__NR_Linux + 252)
1429#endif
1430#ifndef __NR_statfs64
1431#define __NR_statfs64 (__NR_Linux + 255)
1432#endif
1433#ifndef __NR_fstatfs64
1434#define __NR_fstatfs64 (__NR_Linux + 256)
1435#endif
1436#ifndef __NR_clock_gettime
1437#define __NR_clock_gettime (__NR_Linux + 263)
1438#endif
1439#ifndef __NR_clock_getres
1440#define __NR_clock_getres (__NR_Linux + 264)
1441#endif
1442#ifndef __NR_openat
1443#define __NR_openat (__NR_Linux + 288)
1444#endif
1445#ifndef __NR_fstatat
1446#define __NR_fstatat (__NR_Linux + 293)
1447#endif
1448#ifndef __NR_unlinkat
1449#define __NR_unlinkat (__NR_Linux + 294)
1450#endif
1451#ifndef __NR_move_pages
1452#define __NR_move_pages (__NR_Linux + 308)
1453#endif
1454#ifndef __NR_getcpu
1455#define __NR_getcpu (__NR_Linux + 312)
1456#endif
1457#ifndef __NR_ioprio_set
1458#define __NR_ioprio_set (__NR_Linux + 314)
1459#endif
1460#ifndef __NR_ioprio_get
1461#define __NR_ioprio_get (__NR_Linux + 315)
1462#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001463#ifndef __NR_getrandom
1464#define __NR_getrandom (__NR_Linux + 353)
1465#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001466/* End of MIPS (old 32bit API) definitions */
1467#elif _MIPS_SIM == _MIPS_SIM_ABI64
1468#ifndef __NR_pread64
1469#define __NR_pread64 (__NR_Linux + 16)
1470#endif
1471#ifndef __NR_pwrite64
1472#define __NR_pwrite64 (__NR_Linux + 17)
1473#endif
1474#ifndef __NR_setresuid
1475#define __NR_setresuid (__NR_Linux + 115)
1476#define __NR_getresuid (__NR_Linux + 116)
1477#define __NR_setresgid (__NR_Linux + 117)
1478#define __NR_getresgid (__NR_Linux + 118)
1479#endif
1480#ifndef __NR_gettid
1481#define __NR_gettid (__NR_Linux + 178)
1482#endif
1483#ifndef __NR_readahead
1484#define __NR_readahead (__NR_Linux + 179)
1485#endif
1486#ifndef __NR_setxattr
1487#define __NR_setxattr (__NR_Linux + 180)
1488#endif
1489#ifndef __NR_lsetxattr
1490#define __NR_lsetxattr (__NR_Linux + 181)
1491#endif
1492#ifndef __NR_getxattr
1493#define __NR_getxattr (__NR_Linux + 183)
1494#endif
1495#ifndef __NR_lgetxattr
1496#define __NR_lgetxattr (__NR_Linux + 184)
1497#endif
1498#ifndef __NR_listxattr
1499#define __NR_listxattr (__NR_Linux + 186)
1500#endif
1501#ifndef __NR_llistxattr
1502#define __NR_llistxattr (__NR_Linux + 187)
1503#endif
1504#ifndef __NR_tkill
1505#define __NR_tkill (__NR_Linux + 192)
1506#endif
1507#ifndef __NR_futex
1508#define __NR_futex (__NR_Linux + 194)
1509#endif
1510#ifndef __NR_sched_setaffinity
1511#define __NR_sched_setaffinity (__NR_Linux + 195)
1512#define __NR_sched_getaffinity (__NR_Linux + 196)
1513#endif
1514#ifndef __NR_set_tid_address
1515#define __NR_set_tid_address (__NR_Linux + 212)
1516#endif
1517#ifndef __NR_clock_gettime
1518#define __NR_clock_gettime (__NR_Linux + 222)
1519#endif
1520#ifndef __NR_clock_getres
1521#define __NR_clock_getres (__NR_Linux + 223)
1522#endif
1523#ifndef __NR_openat
1524#define __NR_openat (__NR_Linux + 247)
1525#endif
1526#ifndef __NR_fstatat
1527#define __NR_fstatat (__NR_Linux + 252)
1528#endif
1529#ifndef __NR_unlinkat
1530#define __NR_unlinkat (__NR_Linux + 253)
1531#endif
1532#ifndef __NR_move_pages
1533#define __NR_move_pages (__NR_Linux + 267)
1534#endif
1535#ifndef __NR_getcpu
1536#define __NR_getcpu (__NR_Linux + 271)
1537#endif
1538#ifndef __NR_ioprio_set
1539#define __NR_ioprio_set (__NR_Linux + 273)
1540#endif
1541#ifndef __NR_ioprio_get
1542#define __NR_ioprio_get (__NR_Linux + 274)
1543#endif
Yu Yind9ad2962020-11-24 16:49:22 +08001544#ifndef __NR_getrandom
1545#define __NR_getrandom (__NR_Linux + 313)
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001546#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001547/* End of MIPS (64bit API) definitions */
1548#else
1549#ifndef __NR_setresuid
1550#define __NR_setresuid (__NR_Linux + 115)
1551#define __NR_getresuid (__NR_Linux + 116)
1552#define __NR_setresgid (__NR_Linux + 117)
1553#define __NR_getresgid (__NR_Linux + 118)
1554#endif
1555#ifndef __NR_gettid
1556#define __NR_gettid (__NR_Linux + 178)
1557#endif
1558#ifndef __NR_readahead
1559#define __NR_readahead (__NR_Linux + 179)
1560#endif
1561#ifndef __NR_setxattr
1562#define __NR_setxattr (__NR_Linux + 180)
1563#endif
1564#ifndef __NR_lsetxattr
1565#define __NR_lsetxattr (__NR_Linux + 181)
1566#endif
1567#ifndef __NR_getxattr
1568#define __NR_getxattr (__NR_Linux + 183)
1569#endif
1570#ifndef __NR_lgetxattr
1571#define __NR_lgetxattr (__NR_Linux + 184)
1572#endif
1573#ifndef __NR_listxattr
1574#define __NR_listxattr (__NR_Linux + 186)
1575#endif
1576#ifndef __NR_llistxattr
1577#define __NR_llistxattr (__NR_Linux + 187)
1578#endif
1579#ifndef __NR_tkill
1580#define __NR_tkill (__NR_Linux + 192)
1581#endif
1582#ifndef __NR_futex
1583#define __NR_futex (__NR_Linux + 194)
1584#endif
1585#ifndef __NR_sched_setaffinity
1586#define __NR_sched_setaffinity (__NR_Linux + 195)
1587#define __NR_sched_getaffinity (__NR_Linux + 196)
1588#endif
1589#ifndef __NR_set_tid_address
1590#define __NR_set_tid_address (__NR_Linux + 213)
1591#endif
1592#ifndef __NR_statfs64
1593#define __NR_statfs64 (__NR_Linux + 217)
1594#endif
1595#ifndef __NR_fstatfs64
1596#define __NR_fstatfs64 (__NR_Linux + 218)
1597#endif
1598#ifndef __NR_clock_gettime
1599#define __NR_clock_gettime (__NR_Linux + 226)
1600#endif
1601#ifndef __NR_clock_getres
1602#define __NR_clock_getres (__NR_Linux + 227)
1603#endif
1604#ifndef __NR_openat
1605#define __NR_openat (__NR_Linux + 251)
1606#endif
1607#ifndef __NR_fstatat
1608#define __NR_fstatat (__NR_Linux + 256)
1609#endif
1610#ifndef __NR_unlinkat
1611#define __NR_unlinkat (__NR_Linux + 257)
1612#endif
1613#ifndef __NR_move_pages
1614#define __NR_move_pages (__NR_Linux + 271)
1615#endif
1616#ifndef __NR_getcpu
1617#define __NR_getcpu (__NR_Linux + 275)
1618#endif
1619#ifndef __NR_ioprio_set
1620#define __NR_ioprio_set (__NR_Linux + 277)
1621#endif
1622#ifndef __NR_ioprio_get
1623#define __NR_ioprio_get (__NR_Linux + 278)
1624#endif
1625/* End of MIPS (new 32bit API) definitions */
1626#endif
1627/* End of MIPS definitions */
1628#elif defined(__PPC__)
1629#ifndef __NR_setfsuid
1630#define __NR_setfsuid 138
1631#define __NR_setfsgid 139
1632#endif
1633#ifndef __NR_setresuid
1634#define __NR_setresuid 164
1635#define __NR_getresuid 165
1636#define __NR_setresgid 169
1637#define __NR_getresgid 170
1638#endif
1639#ifndef __NR_rt_sigaction
1640#define __NR_rt_sigreturn 172
1641#define __NR_rt_sigaction 173
1642#define __NR_rt_sigprocmask 174
1643#define __NR_rt_sigpending 175
1644#define __NR_rt_sigsuspend 178
1645#endif
1646#ifndef __NR_pread64
1647#define __NR_pread64 179
1648#endif
1649#ifndef __NR_pwrite64
1650#define __NR_pwrite64 180
1651#endif
1652#ifndef __NR_ugetrlimit
1653#define __NR_ugetrlimit 190
1654#endif
1655#ifndef __NR_readahead
1656#define __NR_readahead 191
1657#endif
1658#ifndef __NR_stat64
1659#define __NR_stat64 195
1660#endif
1661#ifndef __NR_fstat64
1662#define __NR_fstat64 197
1663#endif
1664#ifndef __NR_getdents64
1665#define __NR_getdents64 202
1666#endif
1667#ifndef __NR_gettid
1668#define __NR_gettid 207
1669#endif
1670#ifndef __NR_tkill
1671#define __NR_tkill 208
1672#endif
1673#ifndef __NR_setxattr
1674#define __NR_setxattr 209
1675#endif
1676#ifndef __NR_lsetxattr
1677#define __NR_lsetxattr 210
1678#endif
1679#ifndef __NR_getxattr
1680#define __NR_getxattr 212
1681#endif
1682#ifndef __NR_lgetxattr
1683#define __NR_lgetxattr 213
1684#endif
1685#ifndef __NR_listxattr
1686#define __NR_listxattr 215
1687#endif
1688#ifndef __NR_llistxattr
1689#define __NR_llistxattr 216
1690#endif
1691#ifndef __NR_futex
1692#define __NR_futex 221
1693#endif
1694#ifndef __NR_sched_setaffinity
1695#define __NR_sched_setaffinity 222
1696#define __NR_sched_getaffinity 223
1697#endif
1698#ifndef __NR_set_tid_address
1699#define __NR_set_tid_address 232
1700#endif
1701#ifndef __NR_clock_gettime
1702#define __NR_clock_gettime 246
1703#endif
1704#ifndef __NR_clock_getres
1705#define __NR_clock_getres 247
1706#endif
1707#ifndef __NR_statfs64
1708#define __NR_statfs64 252
1709#endif
1710#ifndef __NR_fstatfs64
1711#define __NR_fstatfs64 253
1712#endif
1713#ifndef __NR_fadvise64_64
1714#define __NR_fadvise64_64 254
1715#endif
1716#ifndef __NR_ioprio_set
1717#define __NR_ioprio_set 273
1718#endif
1719#ifndef __NR_ioprio_get
1720#define __NR_ioprio_get 274
1721#endif
1722#ifndef __NR_openat
1723#define __NR_openat 286
1724#endif
1725#ifndef __NR_fstatat64
1726#define __NR_fstatat64 291
1727#endif
1728#ifndef __NR_unlinkat
1729#define __NR_unlinkat 292
1730#endif
1731#ifndef __NR_move_pages
1732#define __NR_move_pages 301
1733#endif
1734#ifndef __NR_getcpu
1735#define __NR_getcpu 302
1736#endif
1737/* End of powerpc defininitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001738#elif defined(__s390__)
1739#ifndef __NR_quotactl
1740#define __NR_quotactl 131
1741#endif
1742#ifndef __NR_rt_sigreturn
1743#define __NR_rt_sigreturn 173
1744#endif
1745#ifndef __NR_rt_sigaction
1746#define __NR_rt_sigaction 174
1747#endif
1748#ifndef __NR_rt_sigprocmask
1749#define __NR_rt_sigprocmask 175
1750#endif
1751#ifndef __NR_rt_sigpending
1752#define __NR_rt_sigpending 176
1753#endif
1754#ifndef __NR_rt_sigsuspend
1755#define __NR_rt_sigsuspend 179
1756#endif
1757#ifndef __NR_pread64
1758#define __NR_pread64 180
1759#endif
1760#ifndef __NR_pwrite64
1761#define __NR_pwrite64 181
1762#endif
1763#ifndef __NR_getdents64
1764#define __NR_getdents64 220
1765#endif
1766#ifndef __NR_readahead
1767#define __NR_readahead 222
1768#endif
1769#ifndef __NR_setxattr
1770#define __NR_setxattr 224
1771#endif
1772#ifndef __NR_lsetxattr
1773#define __NR_lsetxattr 225
1774#endif
1775#ifndef __NR_getxattr
1776#define __NR_getxattr 227
1777#endif
1778#ifndef __NR_lgetxattr
1779#define __NR_lgetxattr 228
1780#endif
1781#ifndef __NR_listxattr
1782#define __NR_listxattr 230
1783#endif
1784#ifndef __NR_llistxattr
1785#define __NR_llistxattr 231
1786#endif
1787#ifndef __NR_gettid
1788#define __NR_gettid 236
1789#endif
1790#ifndef __NR_tkill
1791#define __NR_tkill 237
1792#endif
1793#ifndef __NR_futex
1794#define __NR_futex 238
1795#endif
1796#ifndef __NR_sched_setaffinity
1797#define __NR_sched_setaffinity 239
1798#endif
1799#ifndef __NR_sched_getaffinity
1800#define __NR_sched_getaffinity 240
1801#endif
1802#ifndef __NR_set_tid_address
1803#define __NR_set_tid_address 252
1804#endif
1805#ifndef __NR_clock_gettime
1806#define __NR_clock_gettime 260
1807#endif
1808#ifndef __NR_clock_getres
1809#define __NR_clock_getres 261
1810#endif
1811#ifndef __NR_statfs64
1812#define __NR_statfs64 265
1813#endif
1814#ifndef __NR_fstatfs64
1815#define __NR_fstatfs64 266
1816#endif
1817#ifndef __NR_ioprio_set
1818#define __NR_ioprio_set 282
1819#endif
1820#ifndef __NR_ioprio_get
1821#define __NR_ioprio_get 283
1822#endif
1823#ifndef __NR_openat
1824#define __NR_openat 288
1825#endif
1826#ifndef __NR_unlinkat
1827#define __NR_unlinkat 294
1828#endif
1829#ifndef __NR_move_pages
1830#define __NR_move_pages 310
1831#endif
1832#ifndef __NR_getcpu
1833#define __NR_getcpu 311
1834#endif
1835#ifndef __NR_fallocate
1836#define __NR_fallocate 314
1837#endif
1838/* Some syscalls are named/numbered differently between s390 and s390x. */
1839#ifdef __s390x__
1840# ifndef __NR_getrlimit
1841# define __NR_getrlimit 191
1842# endif
1843# ifndef __NR_setresuid
1844# define __NR_setresuid 208
1845# endif
1846# ifndef __NR_getresuid
1847# define __NR_getresuid 209
1848# endif
1849# ifndef __NR_setresgid
1850# define __NR_setresgid 210
1851# endif
1852# ifndef __NR_getresgid
1853# define __NR_getresgid 211
1854# endif
1855# ifndef __NR_setfsuid
1856# define __NR_setfsuid 215
1857# endif
1858# ifndef __NR_setfsgid
1859# define __NR_setfsgid 216
1860# endif
1861# ifndef __NR_fadvise64
1862# define __NR_fadvise64 253
1863# endif
1864# ifndef __NR_newfstatat
1865# define __NR_newfstatat 293
1866# endif
1867#else /* __s390x__ */
1868# ifndef __NR_getrlimit
1869# define __NR_getrlimit 76
1870# endif
1871# ifndef __NR_setfsuid
1872# define __NR_setfsuid 138
1873# endif
1874# ifndef __NR_setfsgid
1875# define __NR_setfsgid 139
1876# endif
1877# ifndef __NR_setresuid
1878# define __NR_setresuid 164
1879# endif
1880# ifndef __NR_getresuid
1881# define __NR_getresuid 165
1882# endif
1883# ifndef __NR_setresgid
1884# define __NR_setresgid 170
1885# endif
1886# ifndef __NR_getresgid
1887# define __NR_getresgid 171
1888# endif
1889# ifndef __NR_ugetrlimit
1890# define __NR_ugetrlimit 191
1891# endif
1892# ifndef __NR_mmap2
1893# define __NR_mmap2 192
1894# endif
1895# ifndef __NR_setresuid32
1896# define __NR_setresuid32 208
1897# endif
1898# ifndef __NR_getresuid32
1899# define __NR_getresuid32 209
1900# endif
1901# ifndef __NR_setresgid32
1902# define __NR_setresgid32 210
1903# endif
1904# ifndef __NR_getresgid32
1905# define __NR_getresgid32 211
1906# endif
1907# ifndef __NR_setfsuid32
1908# define __NR_setfsuid32 215
1909# endif
1910# ifndef __NR_setfsgid32
1911# define __NR_setfsgid32 216
1912# endif
1913# ifndef __NR_fadvise64_64
1914# define __NR_fadvise64_64 264
1915# endif
1916# ifndef __NR_fstatat64
1917# define __NR_fstatat64 293
1918# endif
1919#endif /* __s390__ */
1920/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001921#endif
1922
1923
1924/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001925#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001926 #error "Need to port invocations of syscalls for bounded ptrs"
1927#else
1928 /* The core dumper and the thread lister get executed after threads
1929 * have been suspended. As a consequence, we cannot call any functions
1930 * that acquire locks. Unfortunately, libc wraps most system calls
1931 * (e.g. in order to implement pthread_atfork, and to make calls
1932 * cancellable), which means we cannot call these functions. Instead,
1933 * we have to call syscall() directly.
1934 */
1935 #undef LSS_ERRNO
1936 #ifdef SYS_ERRNO
1937 /* Allow the including file to override the location of errno. This can
1938 * be useful when using clone() with the CLONE_VM option.
1939 */
1940 #define LSS_ERRNO SYS_ERRNO
1941 #else
1942 #define LSS_ERRNO errno
1943 #endif
1944
1945 #undef LSS_INLINE
1946 #ifdef SYS_INLINE
1947 #define LSS_INLINE SYS_INLINE
1948 #else
1949 #define LSS_INLINE static inline
1950 #endif
1951
1952 /* Allow the including file to override the prefix used for all new
1953 * system calls. By default, it will be set to "sys_".
1954 */
1955 #undef LSS_NAME
1956 #ifndef SYS_PREFIX
1957 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001958 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001959 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001960 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001961 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001962 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001963 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001964 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001965 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001966 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001967 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001968 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001969 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001970 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001971 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001972 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001973 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001974 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001975 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001976 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001977 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001978 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001979 #define LSS_NAME(name) sys9_##name
1980 #endif
1981
1982 #undef LSS_RETURN
Askar Safine1e7b0a2021-04-12 14:03:02 +03001983 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
1984 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \
mingtaoxt xtc0c96892022-08-11 16:53:21 +08001985 || defined(__e2k__) || defined(__riscv) || defined(__loongarch_lp64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001986 /* Failing system calls return a negative result in the range of
1987 * -1..-4095. These are "errno" values with the sign inverted.
1988 */
1989 #define LSS_RETURN(type, res) \
1990 do { \
1991 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
Peter Kasting0d6435b2022-07-20 20:21:35 +00001992 LSS_ERRNO = (int)(-(res)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001993 res = -1; \
1994 } \
1995 return (type) (res); \
1996 } while (0)
1997 #elif defined(__mips__)
1998 /* On MIPS, failing system calls return -1, and set errno in a
1999 * separate CPU register.
2000 */
2001 #define LSS_RETURN(type, res, err) \
2002 do { \
2003 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002004 unsigned long __errnovalue = (res); \
2005 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002006 res = -1; \
2007 } \
2008 return (type) (res); \
2009 } while (0)
2010 #elif defined(__PPC__)
2011 /* On PPC, failing system calls return -1, and set errno in a
2012 * separate CPU register. See linux/unistd.h.
2013 */
2014 #define LSS_RETURN(type, res, err) \
2015 do { \
2016 if (err & 0x10000000 ) { \
2017 LSS_ERRNO = (res); \
2018 res = -1; \
2019 } \
2020 return (type) (res); \
2021 } while (0)
2022 #endif
2023 #if defined(__i386__)
2024 /* In PIC mode (e.g. when building shared libraries), gcc for i386
2025 * reserves ebx. Unfortunately, most distribution ship with implementations
2026 * of _syscallX() which clobber ebx.
2027 * Also, most definitions of _syscallX() neglect to mark "memory" as being
2028 * clobbered. This causes problems with compilers, that do a better job
2029 * at optimizing across __asm__ calls.
2030 * So, we just have to redefine all of the _syscallX() macros.
2031 */
2032 #undef LSS_ENTRYPOINT
2033 #ifdef SYS_SYSCALL_ENTRYPOINT
2034 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2035 void (**entrypoint)(void);
2036 asm volatile(".bss\n"
2037 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002038 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2039 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002040 ".previous\n"
2041 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
2042 "call 0f\n"
2043 "0:pop %0\n"
2044 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002045 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002046 : "=r"(entrypoint));
2047 return entrypoint;
2048 }
2049
2050 #define LSS_ENTRYPOINT ".bss\n" \
2051 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002052 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2053 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002054 ".previous\n" \
2055 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
2056 "push %%eax\n" \
2057 "call 10000f\n" \
2058 "10000:pop %%eax\n" \
2059 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002060 "mov " SYS_SYSCALL_ENTRYPOINT \
2061 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002062 "mov 0(%%eax), %%eax\n" \
2063 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002064 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002065 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002066 "call 10001f\n" \
2067 "10001:pop %%eax\n" \
2068 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002069 "xchg 4(%%esp), %%eax\n" \
2070 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002071 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002072 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002073 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002074 #else
2075 #define LSS_ENTRYPOINT "int $0x80\n"
2076 #endif
2077 #undef LSS_BODY
2078 #define LSS_BODY(type,args...) \
2079 long __res; \
2080 __asm__ __volatile__("push %%ebx\n" \
2081 "movl %2,%%ebx\n" \
2082 LSS_ENTRYPOINT \
2083 "pop %%ebx" \
2084 args \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002085 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002086 LSS_RETURN(type,__res)
2087 #undef _syscall0
2088 #define _syscall0(type,name) \
2089 type LSS_NAME(name)(void) { \
2090 long __res; \
2091 __asm__ volatile(LSS_ENTRYPOINT \
2092 : "=a" (__res) \
2093 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08002094 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002095 LSS_RETURN(type,__res); \
2096 }
2097 #undef _syscall1
2098 #define _syscall1(type,name,type1,arg1) \
2099 type LSS_NAME(name)(type1 arg1) { \
2100 LSS_BODY(type, \
2101 : "=a" (__res) \
2102 : "0" (__NR_##name), "ri" ((long)(arg1))); \
2103 }
2104 #undef _syscall2
2105 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2106 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
2107 LSS_BODY(type, \
2108 : "=a" (__res) \
2109 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
2110 }
2111 #undef _syscall3
2112 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2113 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
2114 LSS_BODY(type, \
2115 : "=a" (__res) \
2116 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2117 "d" ((long)(arg3))); \
2118 }
2119 #undef _syscall4
2120 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2121 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2122 LSS_BODY(type, \
2123 : "=a" (__res) \
2124 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2125 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2126 }
2127 #undef _syscall5
2128 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2129 type5,arg5) \
2130 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2131 type5 arg5) { \
2132 long __res; \
2133 __asm__ __volatile__("push %%ebx\n" \
2134 "movl %2,%%ebx\n" \
2135 "movl %1,%%eax\n" \
2136 LSS_ENTRYPOINT \
2137 "pop %%ebx" \
2138 : "=a" (__res) \
2139 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2140 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2141 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002142 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002143 LSS_RETURN(type,__res); \
2144 }
2145 #undef _syscall6
2146 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2147 type5,arg5,type6,arg6) \
2148 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2149 type5 arg5, type6 arg6) { \
2150 long __res; \
2151 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2152 __asm__ __volatile__("push %%ebp\n" \
2153 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002154 "movl 4(%2),%%ebp\n" \
2155 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002156 "movl %1,%%eax\n" \
2157 LSS_ENTRYPOINT \
2158 "pop %%ebx\n" \
2159 "pop %%ebp" \
2160 : "=a" (__res) \
2161 : "i" (__NR_##name), "0" ((long)(&__s)), \
2162 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2163 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002164 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002165 LSS_RETURN(type,__res); \
2166 }
2167 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2168 int flags, void *arg, int *parent_tidptr,
2169 void *newtls, int *child_tidptr) {
2170 long __res;
2171 __asm__ __volatile__(/* if (fn == NULL)
2172 * return -EINVAL;
2173 */
2174 "movl %3,%%ecx\n"
2175 "jecxz 1f\n"
2176
2177 /* if (child_stack == NULL)
2178 * return -EINVAL;
2179 */
2180 "movl %4,%%ecx\n"
2181 "jecxz 1f\n"
2182
2183 /* Set up alignment of the child stack:
2184 * child_stack = (child_stack & ~0xF) - 20;
2185 */
2186 "andl $-16,%%ecx\n"
2187 "subl $20,%%ecx\n"
2188
2189 /* Push "arg" and "fn" onto the stack that will be
2190 * used by the child.
2191 */
2192 "movl %6,%%eax\n"
2193 "movl %%eax,4(%%ecx)\n"
2194 "movl %3,%%eax\n"
2195 "movl %%eax,(%%ecx)\n"
2196
2197 /* %eax = syscall(%eax = __NR_clone,
2198 * %ebx = flags,
2199 * %ecx = child_stack,
2200 * %edx = parent_tidptr,
2201 * %esi = newtls,
2202 * %edi = child_tidptr)
2203 * Also, make sure that %ebx gets preserved as it is
2204 * used in PIC mode.
2205 */
2206 "movl %8,%%esi\n"
2207 "movl %7,%%edx\n"
2208 "movl %5,%%eax\n"
2209 "movl %9,%%edi\n"
2210 "pushl %%ebx\n"
2211 "movl %%eax,%%ebx\n"
2212 "movl %2,%%eax\n"
2213 LSS_ENTRYPOINT
2214
2215 /* In the parent: restore %ebx
2216 * In the child: move "fn" into %ebx
2217 */
2218 "popl %%ebx\n"
2219
2220 /* if (%eax != 0)
2221 * return %eax;
2222 */
2223 "test %%eax,%%eax\n"
2224 "jnz 1f\n"
2225
2226 /* In the child, now. Terminate frame pointer chain.
2227 */
2228 "movl $0,%%ebp\n"
2229
2230 /* Call "fn". "arg" is already on the stack.
2231 */
2232 "call *%%ebx\n"
2233
2234 /* Call _exit(%ebx). Unfortunately older versions
2235 * of gcc restrict the number of arguments that can
2236 * be passed to asm(). So, we need to hard-code the
2237 * system call number.
2238 */
2239 "movl %%eax,%%ebx\n"
2240 "movl $1,%%eax\n"
2241 LSS_ENTRYPOINT
2242
2243 /* Return to parent.
2244 */
2245 "1:\n"
2246 : "=a" (__res)
2247 : "0"(-EINVAL), "i"(__NR_clone),
2248 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2249 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002250 : "memory", "ecx", "edx", "esi", "edi");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002251 LSS_RETURN(int, __res);
2252 }
2253
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002254 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2255 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2256
2257 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2258 /* On i386, the kernel does not know how to return from a signal
2259 * handler. Instead, it relies on user space to provide a
2260 * restorer function that calls the {rt_,}sigreturn() system call.
2261 * Unfortunately, we cannot just reference the glibc version of this
2262 * function, as glibc goes out of its way to make it inaccessible.
2263 */
2264 void (*res)(void);
2265 __asm__ __volatile__("call 2f\n"
2266 "0:.align 16\n"
2267 "1:movl %1,%%eax\n"
2268 LSS_ENTRYPOINT
2269 "2:popl %0\n"
2270 "addl $(1b-0b),%0\n"
2271 : "=a" (res)
2272 : "i" (__NR_rt_sigreturn));
2273 return res;
2274 }
2275 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
2276 /* On i386, the kernel does not know how to return from a signal
2277 * handler. Instead, it relies on user space to provide a
2278 * restorer function that calls the {rt_,}sigreturn() system call.
2279 * Unfortunately, we cannot just reference the glibc version of this
2280 * function, as glibc goes out of its way to make it inaccessible.
2281 */
2282 void (*res)(void);
2283 __asm__ __volatile__("call 2f\n"
2284 "0:.align 16\n"
2285 "1:pop %%eax\n"
2286 "movl %1,%%eax\n"
2287 LSS_ENTRYPOINT
2288 "2:popl %0\n"
2289 "addl $(1b-0b),%0\n"
2290 : "=a" (res)
2291 : "i" (__NR_sigreturn));
2292 return res;
2293 }
2294 #elif defined(__x86_64__)
2295 /* There are no known problems with any of the _syscallX() macros
2296 * currently shipping for x86_64, but we still need to be able to define
2297 * our own version so that we can override the location of the errno
2298 * location (e.g. when using the clone() system call with the CLONE_VM
2299 * option).
2300 */
2301 #undef LSS_ENTRYPOINT
2302 #ifdef SYS_SYSCALL_ENTRYPOINT
2303 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2304 void (**entrypoint)(void);
2305 asm volatile(".bss\n"
2306 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002307 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2308 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002309 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002310 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002311 : "=r"(entrypoint));
2312 return entrypoint;
2313 }
2314
2315 #define LSS_ENTRYPOINT \
2316 ".bss\n" \
2317 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002318 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2319 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002320 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002321 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002322 "mov 0(%%rcx), %%rcx\n" \
2323 "test %%rcx, %%rcx\n" \
2324 "jz 10001f\n" \
2325 "call *%%rcx\n" \
2326 "jmp 10002f\n" \
2327 "10001:syscall\n" \
2328 "10002:\n"
2329
2330 #else
2331 #define LSS_ENTRYPOINT "syscall\n"
2332 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002333
2334 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2335 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2336 * sign extension. We can't cast pointers directly because those are
2337 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2338 * to an integer of a different size.
2339 */
2340 #undef LSS_SYSCALL_ARG
2341 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2342 #undef _LSS_RETURN
2343 #define _LSS_RETURN(type, res, cast) \
2344 do { \
2345 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
Peter Kasting880985f2022-06-29 21:17:55 +00002346 LSS_ERRNO = (int)(-(res)); \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002347 res = -1; \
2348 } \
2349 return (type)(cast)(res); \
2350 } while (0)
2351 #undef LSS_RETURN
2352 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2353
2354 #undef _LSS_BODY
2355 #define _LSS_BODY(nr, type, name, cast, ...) \
2356 long long __res; \
2357 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2358 : "=a" (__res) \
2359 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2360 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2361 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002362 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002363 #define LSS_BODY(nr, type, name, args...) \
2364 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2365
2366 #undef LSS_BODY_ASM0
2367 #undef LSS_BODY_ASM1
2368 #undef LSS_BODY_ASM2
2369 #undef LSS_BODY_ASM3
2370 #undef LSS_BODY_ASM4
2371 #undef LSS_BODY_ASM5
2372 #undef LSS_BODY_ASM6
2373 #define LSS_BODY_ASM0
2374 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2375 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2376 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2377 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2378 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2379 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2380
2381 #undef LSS_BODY_CLOBBER0
2382 #undef LSS_BODY_CLOBBER1
2383 #undef LSS_BODY_CLOBBER2
2384 #undef LSS_BODY_CLOBBER3
2385 #undef LSS_BODY_CLOBBER4
2386 #undef LSS_BODY_CLOBBER5
2387 #undef LSS_BODY_CLOBBER6
2388 #define LSS_BODY_CLOBBER0
2389 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2390 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2391 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2392 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2393 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2394 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2395
2396 #undef LSS_BODY_ARG0
2397 #undef LSS_BODY_ARG1
2398 #undef LSS_BODY_ARG2
2399 #undef LSS_BODY_ARG3
2400 #undef LSS_BODY_ARG4
2401 #undef LSS_BODY_ARG5
2402 #undef LSS_BODY_ARG6
2403 #define LSS_BODY_ARG0()
2404 #define LSS_BODY_ARG1(arg1) \
2405 LSS_BODY_ARG0(), "D" (arg1)
2406 #define LSS_BODY_ARG2(arg1, arg2) \
2407 LSS_BODY_ARG1(arg1), "S" (arg2)
2408 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2409 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2410 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2411 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2412 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2413 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2414 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2415 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2416
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002417 #undef _syscall0
2418 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002419 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002420 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002421 }
2422 #undef _syscall1
2423 #define _syscall1(type,name,type1,arg1) \
2424 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002425 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002426 }
2427 #undef _syscall2
2428 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2429 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002430 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002431 }
2432 #undef _syscall3
2433 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2434 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002435 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2436 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002437 }
2438 #undef _syscall4
2439 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2440 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002441 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2442 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002443 }
2444 #undef _syscall5
2445 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2446 type5,arg5) \
2447 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2448 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002449 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2450 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2451 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002452 }
2453 #undef _syscall6
2454 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2455 type5,arg5,type6,arg6) \
2456 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2457 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002458 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2459 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2460 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002461 }
2462 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2463 int flags, void *arg, int *parent_tidptr,
2464 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002465 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002466 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002467 __asm__ __volatile__(/* if (fn == NULL)
2468 * return -EINVAL;
2469 */
2470 "testq %4,%4\n"
2471 "jz 1f\n"
2472
2473 /* if (child_stack == NULL)
2474 * return -EINVAL;
2475 */
2476 "testq %5,%5\n"
2477 "jz 1f\n"
2478
2479 /* childstack -= 2*sizeof(void *);
2480 */
2481 "subq $16,%5\n"
2482
2483 /* Push "arg" and "fn" onto the stack that will be
2484 * used by the child.
2485 */
2486 "movq %7,8(%5)\n"
2487 "movq %4,0(%5)\n"
2488
2489 /* %rax = syscall(%rax = __NR_clone,
2490 * %rdi = flags,
2491 * %rsi = child_stack,
2492 * %rdx = parent_tidptr,
2493 * %r8 = new_tls,
2494 * %r10 = child_tidptr)
2495 */
2496 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002497 "movq %9,%%r8\n"
2498 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002499 LSS_ENTRYPOINT
2500
2501 /* if (%rax != 0)
2502 * return;
2503 */
2504 "testq %%rax,%%rax\n"
2505 "jnz 1f\n"
2506
2507 /* In the child. Terminate frame pointer chain.
2508 */
2509 "xorq %%rbp,%%rbp\n"
2510
2511 /* Call "fn(arg)".
2512 */
2513 "popq %%rax\n"
2514 "popq %%rdi\n"
2515 "call *%%rax\n"
2516
2517 /* Call _exit(%ebx).
2518 */
2519 "movq %%rax,%%rdi\n"
2520 "movq %3,%%rax\n"
2521 LSS_ENTRYPOINT
2522
2523 /* Return to parent.
2524 */
2525 "1:\n"
2526 : "=a" (__res)
2527 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002528 "r"(LSS_SYSCALL_ARG(fn)),
2529 "S"(LSS_SYSCALL_ARG(child_stack)),
2530 "D"(LSS_SYSCALL_ARG(flags)),
2531 "r"(LSS_SYSCALL_ARG(arg)),
2532 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2533 "r"(LSS_SYSCALL_ARG(newtls)),
2534 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002535 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002536 }
2537 LSS_RETURN(int, __res);
2538 }
2539 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002540
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002541 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2542 /* On x86-64, the kernel does not know how to return from
2543 * a signal handler. Instead, it relies on user space to provide a
2544 * restorer function that calls the rt_sigreturn() system call.
2545 * Unfortunately, we cannot just reference the glibc version of this
2546 * function, as glibc goes out of its way to make it inaccessible.
2547 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002548 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002549 __asm__ __volatile__("jmp 2f\n"
2550 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002551 "1:movq %1,%%rax\n"
2552 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002553 "2:leaq 1b(%%rip),%0\n"
2554 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002555 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002556 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002557 }
2558 #elif defined(__ARM_ARCH_3__)
2559 /* Most definitions of _syscallX() neglect to mark "memory" as being
2560 * clobbered. This causes problems with compilers, that do a better job
2561 * at optimizing across __asm__ calls.
2562 * So, we just have to redefine all of the _syscallX() macros.
2563 */
2564 #undef LSS_REG
2565 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2566 #undef LSS_BODY
2567 #define LSS_BODY(type,name,args...) \
2568 register long __res_r0 __asm__("r0"); \
2569 long __res; \
2570 __asm__ __volatile__ (__syscall(name) \
2571 : "=r"(__res_r0) : args : "lr", "memory"); \
2572 __res = __res_r0; \
2573 LSS_RETURN(type, __res)
2574 #undef _syscall0
2575 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002576 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002577 LSS_BODY(type, name); \
2578 }
2579 #undef _syscall1
2580 #define _syscall1(type, name, type1, arg1) \
2581 type LSS_NAME(name)(type1 arg1) { \
2582 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2583 }
2584 #undef _syscall2
2585 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2586 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2587 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2588 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2589 }
2590 #undef _syscall3
2591 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2592 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2593 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2594 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2595 }
2596 #undef _syscall4
2597 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2598 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2599 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2600 LSS_REG(3, arg4); \
2601 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2602 }
2603 #undef _syscall5
2604 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2605 type5,arg5) \
2606 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2607 type5 arg5) { \
2608 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2609 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2610 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2611 "r"(__r4)); \
2612 }
2613 #undef _syscall6
2614 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2615 type5,arg5,type6,arg6) \
2616 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2617 type5 arg5, type6 arg6) { \
2618 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2619 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2620 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2621 "r"(__r4), "r"(__r5)); \
2622 }
2623 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2624 int flags, void *arg, int *parent_tidptr,
2625 void *newtls, int *child_tidptr) {
2626 long __res;
2627 {
2628 register int __flags __asm__("r0") = flags;
2629 register void *__stack __asm__("r1") = child_stack;
2630 register void *__ptid __asm__("r2") = parent_tidptr;
2631 register void *__tls __asm__("r3") = newtls;
2632 register int *__ctid __asm__("r4") = child_tidptr;
2633 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2634 * return -EINVAL;
2635 */
2636 "cmp %2,#0\n"
2637 "cmpne %3,#0\n"
2638 "moveq %0,%1\n"
2639 "beq 1f\n"
2640
2641 /* Push "arg" and "fn" onto the stack that will be
2642 * used by the child.
2643 */
2644 "str %5,[%3,#-4]!\n"
2645 "str %2,[%3,#-4]!\n"
2646
2647 /* %r0 = syscall(%r0 = flags,
2648 * %r1 = child_stack,
2649 * %r2 = parent_tidptr,
2650 * %r3 = newtls,
2651 * %r4 = child_tidptr)
2652 */
2653 __syscall(clone)"\n"
2654
2655 /* if (%r0 != 0)
2656 * return %r0;
2657 */
2658 "movs %0,r0\n"
2659 "bne 1f\n"
2660
2661 /* In the child, now. Call "fn(arg)".
2662 */
2663 "ldr r0,[sp, #4]\n"
2664 "mov lr,pc\n"
2665 "ldr pc,[sp]\n"
2666
2667 /* Call _exit(%r0).
2668 */
2669 __syscall(exit)"\n"
2670 "1:\n"
2671 : "=r" (__res)
2672 : "i"(-EINVAL),
2673 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2674 "r"(__ptid), "r"(__tls), "r"(__ctid)
2675 : "cc", "lr", "memory");
2676 }
2677 LSS_RETURN(int, __res);
2678 }
2679 #elif defined(__ARM_EABI__)
2680 /* Most definitions of _syscallX() neglect to mark "memory" as being
2681 * clobbered. This causes problems with compilers, that do a better job
2682 * at optimizing across __asm__ calls.
2683 * So, we just have to redefine all fo the _syscallX() macros.
2684 */
2685 #undef LSS_REG
2686 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2687 #undef LSS_BODY
2688 #define LSS_BODY(type,name,args...) \
2689 register long __res_r0 __asm__("r0"); \
2690 long __res; \
2691 __asm__ __volatile__ ("push {r7}\n" \
2692 "mov r7, %1\n" \
2693 "swi 0x0\n" \
2694 "pop {r7}\n" \
2695 : "=r"(__res_r0) \
2696 : "i"(__NR_##name) , ## args \
2697 : "lr", "memory"); \
2698 __res = __res_r0; \
2699 LSS_RETURN(type, __res)
2700 #undef _syscall0
2701 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002702 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002703 LSS_BODY(type, name); \
2704 }
2705 #undef _syscall1
2706 #define _syscall1(type, name, type1, arg1) \
2707 type LSS_NAME(name)(type1 arg1) { \
2708 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2709 }
2710 #undef _syscall2
2711 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2712 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2713 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2714 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2715 }
2716 #undef _syscall3
2717 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2718 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2719 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2720 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2721 }
2722 #undef _syscall4
2723 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2724 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2725 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2726 LSS_REG(3, arg4); \
2727 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2728 }
2729 #undef _syscall5
2730 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2731 type5,arg5) \
2732 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2733 type5 arg5) { \
2734 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2735 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2736 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2737 "r"(__r4)); \
2738 }
2739 #undef _syscall6
2740 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2741 type5,arg5,type6,arg6) \
2742 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2743 type5 arg5, type6 arg6) { \
2744 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2745 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2746 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2747 "r"(__r4), "r"(__r5)); \
2748 }
2749 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2750 int flags, void *arg, int *parent_tidptr,
2751 void *newtls, int *child_tidptr) {
2752 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002753 if (fn == NULL || child_stack == NULL) {
2754 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002755 LSS_RETURN(int, __res);
2756 }
2757
2758 /* Push "arg" and "fn" onto the stack that will be
2759 * used by the child.
2760 */
2761 {
2762 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2763 cstack[0] = (uintptr_t)fn;
2764 cstack[1] = (uintptr_t)arg;
2765 child_stack = cstack;
2766 }
2767 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002768 register int __flags __asm__("r0") = flags;
2769 register void *__stack __asm__("r1") = child_stack;
2770 register void *__ptid __asm__("r2") = parent_tidptr;
2771 register void *__tls __asm__("r3") = newtls;
2772 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002773 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002774#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002775 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002776#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002777 /* %r0 = syscall(%r0 = flags,
2778 * %r1 = child_stack,
2779 * %r2 = parent_tidptr,
2780 * %r3 = newtls,
2781 * %r4 = child_tidptr)
2782 */
2783 "mov r7, %6\n"
2784 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002785
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002786 /* if (%r0 != 0)
2787 * return %r0;
2788 */
2789 "cmp r0, #0\n"
2790 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002791
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002792 /* In the child, now. Call "fn(arg)".
2793 */
2794 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002795
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002796 "ldr lr,[sp]\n"
2797 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002798
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002799 /* Call _exit(%r0).
2800 */
2801 "mov r7, %7\n"
2802 "swi 0x0\n"
2803 /* Unreachable */
2804 "bkpt #0\n"
2805 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002806#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002807 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002808#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002809 "movs %0,r0\n"
2810 : "=r"(__res)
2811 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2812 "i"(__NR_clone), "i"(__NR_exit)
2813 : "cc", "lr", "memory"
2814#ifndef __thumb2__
2815 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002816#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002817 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002818 }
2819 LSS_RETURN(int, __res);
2820 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002821 #elif defined(__aarch64__)
2822 /* Most definitions of _syscallX() neglect to mark "memory" as being
2823 * clobbered. This causes problems with compilers, that do a better job
2824 * at optimizing across __asm__ calls.
2825 * So, we just have to redefine all of the _syscallX() macros.
2826 */
2827 #undef LSS_REG
2828 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2829 #undef LSS_BODY
2830 #define LSS_BODY(type,name,args...) \
2831 register int64_t __res_x0 __asm__("x0"); \
2832 int64_t __res; \
2833 __asm__ __volatile__ ("mov x8, %1\n" \
2834 "svc 0x0\n" \
2835 : "=r"(__res_x0) \
2836 : "i"(__NR_##name) , ## args \
2837 : "x8", "memory"); \
2838 __res = __res_x0; \
2839 LSS_RETURN(type, __res)
2840 #undef _syscall0
2841 #define _syscall0(type, name) \
2842 type LSS_NAME(name)(void) { \
2843 LSS_BODY(type, name); \
2844 }
2845 #undef _syscall1
2846 #define _syscall1(type, name, type1, arg1) \
2847 type LSS_NAME(name)(type1 arg1) { \
2848 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2849 }
2850 #undef _syscall2
2851 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2852 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2853 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2854 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2855 }
2856 #undef _syscall3
2857 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2858 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2859 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2860 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2861 }
2862 #undef _syscall4
2863 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2864 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2865 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2866 LSS_REG(3, arg4); \
2867 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2868 }
2869 #undef _syscall5
2870 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2871 type5,arg5) \
2872 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2873 type5 arg5) { \
2874 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2875 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2876 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2877 "r"(__r4)); \
2878 }
2879 #undef _syscall6
2880 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2881 type5,arg5,type6,arg6) \
2882 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2883 type5 arg5, type6 arg6) { \
2884 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2885 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2886 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2887 "r"(__r4), "r"(__r5)); \
2888 }
2889
2890 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2891 int flags, void *arg, int *parent_tidptr,
2892 void *newtls, int *child_tidptr) {
2893 int64_t __res;
2894 {
Peter Kasting0d6435b2022-07-20 20:21:35 +00002895 register uint64_t __flags __asm__("x0") = (uint64_t)flags;
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002896 register void *__stack __asm__("x1") = child_stack;
2897 register void *__ptid __asm__("x2") = parent_tidptr;
2898 register void *__tls __asm__("x3") = newtls;
2899 register int *__ctid __asm__("x4") = child_tidptr;
2900 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2901 * used by the child.
2902 */
2903 "stp %1, %4, [%2, #-16]!\n"
2904
2905 /* %x0 = syscall(%x0 = flags,
2906 * %x1 = child_stack,
2907 * %x2 = parent_tidptr,
2908 * %x3 = newtls,
2909 * %x4 = child_tidptr)
2910 */
2911 "mov x8, %8\n"
2912 "svc 0x0\n"
2913
2914 /* if (%r0 != 0)
2915 * return %r0;
2916 */
2917 "mov %0, x0\n"
2918 "cbnz x0, 1f\n"
2919
2920 /* In the child, now. Call "fn(arg)".
2921 */
2922 "ldp x1, x0, [sp], #16\n"
2923 "blr x1\n"
2924
2925 /* Call _exit(%r0).
2926 */
2927 "mov x8, %9\n"
2928 "svc 0x0\n"
2929 "1:\n"
2930 : "=r" (__res)
2931 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2932 "r"(__ptid), "r"(__tls), "r"(__ctid),
2933 "i"(__NR_clone), "i"(__NR_exit)
2934 : "cc", "x8", "memory");
2935 }
2936 LSS_RETURN(int, __res);
2937 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002938 #elif defined(__mips__)
2939 #undef LSS_REG
2940 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2941 (unsigned long)(a)
2942 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002943 #undef LSS_SYSCALL_CLOBBERS
2944 #if _MIPS_SIM == _MIPS_SIM_ABI32
2945 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2946 "$11", "$12", "$13", "$14", "$15", \
2947 "$24", "$25", "hi", "lo", "memory"
2948 #else
2949 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2950 "$13", "$14", "$15", "$24", "$25", \
2951 "hi", "lo", "memory"
2952 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002953 #define LSS_BODY(type,name,r7,...) \
2954 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2955 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002956 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002957 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002958 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002959 LSS_RETURN(type, __v0, __r7)
2960 #undef _syscall0
2961 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002962 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002963 register unsigned long __r7 __asm__("$7"); \
2964 LSS_BODY(type, name, "=r"); \
2965 }
2966 #undef _syscall1
2967 #define _syscall1(type, name, type1, arg1) \
2968 type LSS_NAME(name)(type1 arg1) { \
2969 register unsigned long __r7 __asm__("$7"); \
2970 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2971 }
2972 #undef _syscall2
2973 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2974 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2975 register unsigned long __r7 __asm__("$7"); \
2976 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2977 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2978 }
2979 #undef _syscall3
2980 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2981 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2982 register unsigned long __r7 __asm__("$7"); \
2983 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2984 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2985 }
2986 #undef _syscall4
2987 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2988 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2989 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2990 LSS_REG(7, arg4); \
2991 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2992 }
2993 #undef _syscall5
2994 #if _MIPS_SIM == _MIPS_SIM_ABI32
2995 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2996 * on the stack, whereas the new APIs use registers "r8" and "r9".
2997 */
2998 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2999 type5,arg5) \
3000 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3001 type5 arg5) { \
3002 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3003 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003004 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003005 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003006 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003007 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003008 "syscall\n" \
3009 "addiu $29, 32\n" \
3010 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003011 : "+r"(__v0), "+r" (__r7) \
3012 : "r"(__r4), "r"(__r5), \
3013 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003014 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003015 "$13", "$14", "$15", "$24", "$25", \
3016 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003017 LSS_RETURN(type, __v0, __r7); \
3018 }
3019 #else
3020 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3021 type5,arg5) \
3022 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3023 type5 arg5) { \
3024 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3025 LSS_REG(7, arg4); LSS_REG(8, arg5); \
3026 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
3027 "r"(__r8)); \
3028 }
3029 #endif
3030 #undef _syscall6
3031 #if _MIPS_SIM == _MIPS_SIM_ABI32
3032 /* The old 32bit MIPS system call API passes the fifth and sixth argument
3033 * on the stack, whereas the new APIs use registers "r8" and "r9".
3034 */
3035 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3036 type5,arg5,type6,arg6) \
3037 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3038 type5 arg5, type6 arg6) { \
3039 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3040 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003041 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003042 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003043 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003044 "sw %5, 16($29)\n" \
3045 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003046 "syscall\n" \
3047 "addiu $29, 32\n" \
3048 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003049 : "+r"(__v0), "+r" (__r7) \
3050 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003051 "r"(__r6), "r" ((unsigned long)arg5), \
3052 "r" ((unsigned long)arg6) \
3053 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003054 "$13", "$14", "$15", "$24", "$25", \
3055 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003056 LSS_RETURN(type, __v0, __r7); \
3057 }
3058 #else
3059 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3060 type5,arg5,type6,arg6) \
3061 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3062 type5 arg5,type6 arg6) { \
3063 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3064 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
3065 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
3066 "r"(__r8), "r"(__r9)); \
3067 }
3068 #endif
3069 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3070 int flags, void *arg, int *parent_tidptr,
3071 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00003072 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003073 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
3074 {
3075 register int __flags __asm__("$4") = flags;
3076 register void *__stack __asm__("$5") = child_stack;
3077 register void *__ptid __asm__("$6") = parent_tidptr;
3078 register int *__ctid __asm__("$8") = child_tidptr;
3079 __asm__ __volatile__(
3080 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3081 "subu $29,24\n"
3082 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3083 "sub $29,16\n"
3084 #else
3085 "dsubu $29,16\n"
3086 #endif
3087
3088 /* if (fn == NULL || child_stack == NULL)
3089 * return -EINVAL;
3090 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003091 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003092 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003093
3094 /* Push "arg" and "fn" onto the stack that will be
3095 * used by the child.
3096 */
3097 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003098 "subu %5,32\n"
3099 "sw %4,0(%5)\n"
3100 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003101 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003102 "sub %5,32\n"
3103 "sw %4,0(%5)\n"
3104 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003105 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00003106 "dsubu %5,32\n"
3107 "sd %4,0(%5)\n"
3108 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003109 #endif
3110
3111 /* $7 = syscall($4 = flags,
3112 * $5 = child_stack,
3113 * $6 = parent_tidptr,
3114 * $7 = newtls,
3115 * $8 = child_tidptr)
3116 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003117 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003118 "syscall\n"
3119
3120 /* if ($7 != 0)
3121 * return $2;
3122 */
3123 "bnez $7,1f\n"
3124 "bnez $2,1f\n"
3125
3126 /* In the child, now. Call "fn(arg)".
3127 */
3128 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3129 "lw $25,0($29)\n"
3130 "lw $4,4($29)\n"
3131 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3132 "lw $25,0($29)\n"
3133 "lw $4,8($29)\n"
3134 #else
3135 "ld $25,0($29)\n"
3136 "ld $4,8($29)\n"
3137 #endif
3138 "jalr $25\n"
3139
3140 /* Call _exit($2)
3141 */
3142 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003143 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003144 "syscall\n"
3145
3146 "1:\n"
3147 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3148 "addu $29, 24\n"
3149 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3150 "add $29, 16\n"
3151 #else
3152 "daddu $29,16\n"
3153 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003154 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003155 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3156 "r"(__stack), "r"(__flags), "r"(arg),
3157 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003158 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003159 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003160 }
3161 LSS_RETURN(int, __v0, __r7);
3162 }
3163 #elif defined (__PPC__)
3164 #undef LSS_LOADARGS_0
3165 #define LSS_LOADARGS_0(name, dummy...) \
3166 __sc_0 = __NR_##name
3167 #undef LSS_LOADARGS_1
3168 #define LSS_LOADARGS_1(name, arg1) \
3169 LSS_LOADARGS_0(name); \
3170 __sc_3 = (unsigned long) (arg1)
3171 #undef LSS_LOADARGS_2
3172 #define LSS_LOADARGS_2(name, arg1, arg2) \
3173 LSS_LOADARGS_1(name, arg1); \
3174 __sc_4 = (unsigned long) (arg2)
3175 #undef LSS_LOADARGS_3
3176 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3177 LSS_LOADARGS_2(name, arg1, arg2); \
3178 __sc_5 = (unsigned long) (arg3)
3179 #undef LSS_LOADARGS_4
3180 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3181 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3182 __sc_6 = (unsigned long) (arg4)
3183 #undef LSS_LOADARGS_5
3184 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3185 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3186 __sc_7 = (unsigned long) (arg5)
3187 #undef LSS_LOADARGS_6
3188 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3189 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3190 __sc_8 = (unsigned long) (arg6)
3191 #undef LSS_ASMINPUT_0
3192 #define LSS_ASMINPUT_0 "0" (__sc_0)
3193 #undef LSS_ASMINPUT_1
3194 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3195 #undef LSS_ASMINPUT_2
3196 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3197 #undef LSS_ASMINPUT_3
3198 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3199 #undef LSS_ASMINPUT_4
3200 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3201 #undef LSS_ASMINPUT_5
3202 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3203 #undef LSS_ASMINPUT_6
3204 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3205 #undef LSS_BODY
3206 #define LSS_BODY(nr, type, name, args...) \
3207 long __sc_ret, __sc_err; \
3208 { \
3209 register unsigned long __sc_0 __asm__ ("r0"); \
3210 register unsigned long __sc_3 __asm__ ("r3"); \
3211 register unsigned long __sc_4 __asm__ ("r4"); \
3212 register unsigned long __sc_5 __asm__ ("r5"); \
3213 register unsigned long __sc_6 __asm__ ("r6"); \
3214 register unsigned long __sc_7 __asm__ ("r7"); \
3215 register unsigned long __sc_8 __asm__ ("r8"); \
3216 \
3217 LSS_LOADARGS_##nr(name, args); \
3218 __asm__ __volatile__ \
3219 ("sc\n\t" \
3220 "mfcr %0" \
3221 : "=&r" (__sc_0), \
3222 "=&r" (__sc_3), "=&r" (__sc_4), \
3223 "=&r" (__sc_5), "=&r" (__sc_6), \
3224 "=&r" (__sc_7), "=&r" (__sc_8) \
3225 : LSS_ASMINPUT_##nr \
3226 : "cr0", "ctr", "memory", \
3227 "r9", "r10", "r11", "r12"); \
3228 __sc_ret = __sc_3; \
3229 __sc_err = __sc_0; \
3230 } \
3231 LSS_RETURN(type, __sc_ret, __sc_err)
3232 #undef _syscall0
3233 #define _syscall0(type, name) \
3234 type LSS_NAME(name)(void) { \
3235 LSS_BODY(0, type, name); \
3236 }
3237 #undef _syscall1
3238 #define _syscall1(type, name, type1, arg1) \
3239 type LSS_NAME(name)(type1 arg1) { \
3240 LSS_BODY(1, type, name, arg1); \
3241 }
3242 #undef _syscall2
3243 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3244 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3245 LSS_BODY(2, type, name, arg1, arg2); \
3246 }
3247 #undef _syscall3
3248 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3249 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3250 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3251 }
3252 #undef _syscall4
3253 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3254 type4, arg4) \
3255 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3256 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3257 }
3258 #undef _syscall5
3259 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3260 type4, arg4, type5, arg5) \
3261 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3262 type5 arg5) { \
3263 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3264 }
3265 #undef _syscall6
3266 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3267 type4, arg4, type5, arg5, type6, arg6) \
3268 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3269 type5 arg5, type6 arg6) { \
3270 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3271 }
3272 /* clone function adapted from glibc 2.3.6 clone.S */
3273 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3274 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3275 */
3276 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3277 int flags, void *arg, int *parent_tidptr,
3278 void *newtls, int *child_tidptr) {
3279 long __ret, __err;
3280 {
3281 register int (*__fn)(void *) __asm__ ("r8") = fn;
3282 register void *__cstack __asm__ ("r4") = child_stack;
3283 register int __flags __asm__ ("r3") = flags;
3284 register void * __arg __asm__ ("r9") = arg;
3285 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3286 register void * __newtls __asm__ ("r6") = newtls;
3287 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3288 __asm__ __volatile__(
3289 /* check for fn == NULL
3290 * and child_stack == NULL
3291 */
3292 "cmpwi cr0, %6, 0\n\t"
3293 "cmpwi cr1, %7, 0\n\t"
3294 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3295 "beq- cr0, 1f\n\t"
3296
3297 /* set up stack frame for child */
3298 "clrrwi %7, %7, 4\n\t"
3299 "li 0, 0\n\t"
3300 "stwu 0, -16(%7)\n\t"
3301
3302 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3303 "mr 28, %6\n\t"
3304 "mr 29, %7\n\t"
3305 "mr 27, %9\n\t"
3306
3307 /* syscall */
3308 "li 0, %4\n\t"
3309 /* flags already in r3
3310 * child_stack already in r4
3311 * ptidptr already in r5
3312 * newtls already in r6
3313 * ctidptr already in r7
3314 */
3315 "sc\n\t"
3316
3317 /* Test if syscall was successful */
3318 "cmpwi cr1, 3, 0\n\t"
3319 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3320 "bne- cr1, 1f\n\t"
3321
3322 /* Do the function call */
3323 "mtctr 28\n\t"
3324 "mr 3, 27\n\t"
3325 "bctrl\n\t"
3326
3327 /* Call _exit(r3) */
3328 "li 0, %5\n\t"
3329 "sc\n\t"
3330
3331 /* Return to parent */
3332 "1:\n"
3333 "mfcr %1\n\t"
3334 "mr %0, 3\n\t"
3335 : "=r" (__ret), "=r" (__err)
3336 : "0" (-1), "1" (EINVAL),
3337 "i" (__NR_clone), "i" (__NR_exit),
3338 "r" (__fn), "r" (__cstack), "r" (__flags),
3339 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3340 "r" (__ctidptr)
3341 : "cr0", "cr1", "memory", "ctr",
3342 "r0", "r29", "r27", "r28");
3343 }
3344 LSS_RETURN(int, __ret, __err);
3345 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003346 #elif defined(__s390__)
3347 #undef LSS_REG
3348 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3349 #undef LSS_BODY
3350 #define LSS_BODY(type, name, args...) \
3351 register unsigned long __nr __asm__("r1") \
3352 = (unsigned long)(__NR_##name); \
3353 register long __res_r2 __asm__("r2"); \
3354 long __res; \
3355 __asm__ __volatile__ \
3356 ("svc 0\n\t" \
3357 : "=d"(__res_r2) \
3358 : "d"(__nr), ## args \
3359 : "memory"); \
3360 __res = __res_r2; \
3361 LSS_RETURN(type, __res)
3362 #undef _syscall0
3363 #define _syscall0(type, name) \
3364 type LSS_NAME(name)(void) { \
3365 LSS_BODY(type, name); \
3366 }
3367 #undef _syscall1
3368 #define _syscall1(type, name, type1, arg1) \
3369 type LSS_NAME(name)(type1 arg1) { \
3370 LSS_REG(2, arg1); \
3371 LSS_BODY(type, name, "0"(__r2)); \
3372 }
3373 #undef _syscall2
3374 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3375 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3376 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3377 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3378 }
3379 #undef _syscall3
3380 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3381 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3382 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3383 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3384 }
3385 #undef _syscall4
3386 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3387 type4, arg4) \
3388 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3389 type4 arg4) { \
3390 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3391 LSS_REG(5, arg4); \
3392 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3393 "d"(__r5)); \
3394 }
3395 #undef _syscall5
3396 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3397 type4, arg4, type5, arg5) \
3398 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3399 type4 arg4, type5 arg5) { \
3400 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3401 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3402 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3403 "d"(__r5), "d"(__r6)); \
3404 }
3405 #undef _syscall6
3406 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3407 type4, arg4, type5, arg5, type6, arg6) \
3408 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3409 type4 arg4, type5 arg5, type6 arg6) { \
3410 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3411 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3412 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3413 "d"(__r5), "d"(__r6), "d"(__r7)); \
3414 }
3415 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3416 int flags, void *arg, int *parent_tidptr,
3417 void *newtls, int *child_tidptr) {
3418 long __ret;
3419 {
3420 register int (*__fn)(void *) __asm__ ("r1") = fn;
3421 register void *__cstack __asm__ ("r2") = child_stack;
3422 register int __flags __asm__ ("r3") = flags;
3423 register void *__arg __asm__ ("r0") = arg;
3424 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3425 register void *__newtls __asm__ ("r6") = newtls;
3426 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3427 __asm__ __volatile__ (
3428 #ifndef __s390x__
3429 /* arg already in r0 */
3430 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3431 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3432 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3433 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3434 /* flags already in r3 */
3435 /* parent_tidptr already in r4 */
3436 /* child_tidptr already in r5 */
3437 /* newtls already in r6 */
3438 "svc %2\n\t" /* invoke clone syscall */
3439 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3440 "jnz 1f\n\t" /* return to parent if non-zero */
3441 /* start child thread */
3442 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3443 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3444 "xc 0(4,%%r15), 0(%%r15)\n\t"
3445 "basr %%r14, %4\n\t" /* jump to fn */
3446 "svc %3\n" /* invoke exit syscall */
3447 "1:\n"
3448 #else
3449 /* arg already in r0 */
3450 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3451 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3452 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3453 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3454 /* flags already in r3 */
3455 /* parent_tidptr already in r4 */
3456 /* child_tidptr already in r5 */
3457 /* newtls already in r6 */
3458 "svc %2\n\t" /* invoke clone syscall */
3459 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3460 "jnz 1f\n\t" /* return to parent if non-zero */
3461 /* start child thread */
3462 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3463 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3464 "xc 0(8,%%r15), 0(%%r15)\n\t"
3465 "basr %%r14, %4\n\t" /* jump to fn */
3466 "svc %3\n" /* invoke exit syscall */
3467 "1:\n"
3468 #endif
3469 : "=r" (__ret)
3470 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3471 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3472 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3473 : "cc", "r14", "memory"
3474 );
3475 }
3476 LSS_RETURN(int, __ret);
3477 }
Andreas Schwab1d387f42022-02-15 16:21:13 +01003478 #elif defined(__riscv) && __riscv_xlen == 64
3479 #undef LSS_REG
3480 #define LSS_REG(r,a) register int64_t __r##r __asm__("a"#r) = (int64_t)a
3481 #undef LSS_BODY
3482 #define LSS_BODY(type,name,args...) \
3483 register int64_t __res_a0 __asm__("a0"); \
3484 register int64_t __a7 __asm__("a7") = __NR_##name; \
3485 int64_t __res; \
3486 __asm__ __volatile__ ("scall\n" \
3487 : "=r"(__res_a0) \
3488 : "r"(__a7) , ## args \
3489 : "memory"); \
3490 __res = __res_a0; \
3491 LSS_RETURN(type, __res)
3492 #undef _syscall0
3493 #define _syscall0(type, name) \
3494 type LSS_NAME(name)(void) { \
3495 LSS_BODY(type, name); \
3496 }
3497 #undef _syscall1
3498 #define _syscall1(type, name, type1, arg1) \
3499 type LSS_NAME(name)(type1 arg1) { \
3500 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
3501 }
3502 #undef _syscall2
3503 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3504 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3505 LSS_REG(0, arg1); LSS_REG(1, arg2); \
3506 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
3507 }
3508 #undef _syscall3
3509 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3510 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3511 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3512 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
3513 }
3514 #undef _syscall4
3515 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3516 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3517 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3518 LSS_REG(3, arg4); \
3519 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
3520 }
3521 #undef _syscall5
3522 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3523 type5,arg5) \
3524 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3525 type5 arg5) { \
3526 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3527 LSS_REG(3, arg4); LSS_REG(4, arg5); \
3528 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3529 "r"(__r4)); \
3530 }
3531 #undef _syscall6
3532 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3533 type5,arg5,type6,arg6) \
3534 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3535 type5 arg5, type6 arg6) { \
3536 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3537 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
3538 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3539 "r"(__r4), "r"(__r5)); \
3540 }
3541
3542 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3543 int flags, void *arg, int *parent_tidptr,
3544 void *newtls, int *child_tidptr) {
3545 int64_t __res;
3546 {
3547 register int64_t __res_a0 __asm__("a0");
3548 register uint64_t __flags __asm__("a0") = flags;
3549 register void *__stack __asm__("a1") = child_stack;
3550 register void *__ptid __asm__("a2") = parent_tidptr;
3551 register void *__tls __asm__("a3") = newtls;
3552 register int *__ctid __asm__("a4") = child_tidptr;
3553 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
3554 * used by the child.
3555 */
3556 "addi %2,%2,-16\n"
3557 "sd %1, 0(%2)\n"
3558 "sd %4, 8(%2)\n"
3559
3560 /* %a0 = syscall(%a0 = flags,
3561 * %a1 = child_stack,
3562 * %a2 = parent_tidptr,
3563 * %a3 = newtls,
3564 * %a4 = child_tidptr)
3565 */
3566 "li a7, %8\n"
3567 "scall\n"
3568
3569 /* if (%a0 != 0)
3570 * return %a0;
3571 */
3572 "bnez %0, 1f\n"
3573
3574 /* In the child, now. Call "fn(arg)".
3575 */
3576 "ld a1, 0(sp)\n"
3577 "ld a0, 8(sp)\n"
3578 "jalr a1\n"
3579
3580 /* Call _exit(%a0).
3581 */
3582 "li a7, %9\n"
3583 "scall\n"
3584 "1:\n"
3585 : "=r" (__res_a0)
3586 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
3587 "r"(__ptid), "r"(__tls), "r"(__ctid),
3588 "i"(__NR_clone), "i"(__NR_exit)
3589 : "cc", "memory");
3590 __res = __res_a0;
3591 }
3592 LSS_RETURN(int, __res);
3593 }
Konstantin Ivlev8007b272021-01-27 18:27:42 +03003594 #elif defined(__e2k__)
3595
3596 #undef _LSS_BODY
3597 #define _LSS_BODY(nr, type, name, ...) \
3598 register unsigned long long __res; \
3599 __asm__ __volatile__ \
3600 ( \
3601 "{\n\t" \
3602 " sdisp %%ctpr1, 0x3\n\t" \
3603 " addd, s 0x0, %[sys_num], %%b[0]\n\t" \
3604 LSS_BODY_ASM##nr \
3605 "}\n\t" \
3606 "{\n\t" \
3607 " call %%ctpr1, wbs = %#\n\t" \
3608 "}\n\t" \
3609 "{\n\t" \
3610 " addd, s 0x0, %%b[0], %[res]\n\t" \
3611 "}\n\t" \
3612 : [res] "=r" (__res) \
3613 : \
3614 LSS_BODY_ARG##nr(__VA_ARGS__) \
3615 [sys_num] "ri" (__NR_##name) \
3616 : "ctpr1", "ctpr2", "ctpr3", \
3617 "b[0]", "b[1]", "b[2]", "b[3]", \
3618 "b[4]", "b[5]", "b[6]", "b[7]" \
3619 ); \
3620 LSS_RETURN(type, __res);
3621
3622 #undef LSS_BODY
3623 #define LSS_BODY(nr, type, name, args...) \
3624 _LSS_BODY(nr, type, name, ## args)
3625
3626 #undef LSS_BODY_ASM0
3627 #undef LSS_BODY_ASM1
3628 #undef LSS_BODY_ASM2
3629 #undef LSS_BODY_ASM3
3630 #undef LSS_BODY_ASM4
3631 #undef LSS_BODY_ASM5
3632 #undef LSS_BODY_ASM6
3633
3634 #define LSS_BODY_ASM0
3635 #define LSS_BODY_ASM1 LSS_BODY_ASM0 \
3636 " addd, s 0x0, %[arg1], %%b[1]\n\t"
3637 #define LSS_BODY_ASM2 LSS_BODY_ASM1 \
3638 " addd, s 0x0, %[arg2], %%b[2]\n\t"
3639 #define LSS_BODY_ASM3 LSS_BODY_ASM2 \
3640 " addd, s 0x0, %[arg3], %%b[3]\n\t"
3641 #define LSS_BODY_ASM4 LSS_BODY_ASM3 \
3642 " addd, s 0x0, %[arg4], %%b[4]\n\t"
3643 #define LSS_BODY_ASM5 LSS_BODY_ASM4 \
3644 " addd, s 0x0, %[arg5], %%b[5]\n\t"
3645 #define LSS_BODY_ASM6 LSS_BODY_ASM5 \
3646 "}\n\t" \
3647 "{\n\t" \
3648 " addd, s 0x0, %[arg6], %%b[6]\n\t"
3649
3650 #undef LSS_SYSCALL_ARG
3651 #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a))
3652
3653 #undef LSS_BODY_ARG0
3654 #undef LSS_BODY_ARG1
3655 #undef LSS_BODY_ARG2
3656 #undef LSS_BODY_ARG3
3657 #undef LSS_BODY_ARG4
3658 #undef LSS_BODY_ARG5
3659 #undef LSS_BODY_ARG6
3660
3661 #define LSS_BODY_ARG0()
3662 #define LSS_BODY_ARG1(_arg1) \
3663 [arg1] "ri" LSS_SYSCALL_ARG(_arg1),
3664 #define LSS_BODY_ARG2(_arg1, _arg2) \
3665 LSS_BODY_ARG1(_arg1) \
3666 [arg2] "ri" LSS_SYSCALL_ARG(_arg2),
3667 #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3668 LSS_BODY_ARG2(_arg1, _arg2) \
3669 [arg3] "ri" LSS_SYSCALL_ARG(_arg3),
3670 #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3671 LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3672 [arg4] "ri" LSS_SYSCALL_ARG(_arg4),
3673 #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3674 LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3675 [arg5] "ri" LSS_SYSCALL_ARG(_arg5),
3676 #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \
3677 LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3678 [arg6] "ri" LSS_SYSCALL_ARG(_arg6),
3679
3680 #undef _syscall0
3681 #define _syscall0(type, name) \
3682 type LSS_NAME(name)(void) { \
3683 LSS_BODY(0, type, name); \
3684 }
3685
3686 #undef _syscall1
3687 #define _syscall1(type, name, type1, arg1) \
3688 type LSS_NAME(name)(type1 arg1) { \
3689 LSS_BODY(1, type, name, arg1) \
3690 }
3691
3692 #undef _syscall2
3693 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3694 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3695 LSS_BODY(2, type, name, arg1, arg2) \
3696 }
3697
3698 #undef _syscall3
3699 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3700 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3701 LSS_BODY(3, type, name, arg1, arg2, arg3) \
3702 }
3703
3704 #undef _syscall4
3705 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3706 type4, arg4) \
3707 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3708 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \
3709 }
3710
3711 #undef _syscall5
3712 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3713 type4, arg4, type5, arg5) \
3714 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3715 type5 arg5) { \
3716 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \
3717 }
3718
3719 #undef _syscall6
3720 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3721 type4, arg4, type5, arg5, type6, arg6) \
3722 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3723 type5 arg5, type6 arg6) { \
3724 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \
3725 }
3726
3727 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3728 int flags, void *arg, int *parent_tidptr,
3729 void *newtls, int *child_tidptr) {
3730 unsigned long long __res;
3731
3732 __asm__ __volatile__ (
3733 "{\n\t"
3734 " addd,s 0x0, %[nr_clone], %%b[0]\n\t"
3735 " addd,s 0x0, %[flags], %%db[1]\n\t"
3736 " addd,s 0x0, %[child_stack], %%db[2]\n\t"
3737 " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t"
3738 " addd,s 0x0, %[child_tidptr], %%db[4]\n\t"
3739 " addd,s 0x0, %[newtls], %%db[5]\n\t"
3740 "}\n\t"
3741 /* if (fn == NULL)
3742 * return -EINVAL;
3743 */
3744
3745 "{\n\t"
3746 " disp %%ctpr1, .L1\n\t"
3747 "}\n\t"
3748 "{\n\t"
3749 " cmpesb,s 0x0, %[fn], %%pred0\n\t"
3750 "}\n\t"
3751 "{\n\t"
3752 " ct %%ctpr1 ? %%pred0\n\t"
3753 "}\n\t"
3754
3755 /* if (child_stack == NULL)
3756 * return -EINVAL;
3757 */
3758 "{\n\t"
3759 " cmpesb,s 0x0, %%db[2], %%pred0\n\t"
3760 "}\n\t"
3761 "{\n\t"
3762 " ct %%ctpr1 ? %%pred0\n\t"
3763 "}\n\t"
3764
3765 /* b[0] = syscall(%b[0] = __NR_clone,
3766 * %db[1] = flags,
3767 * %db[2] = child_stack,
3768 * %db[3] = parent_tidptr,
3769 * %db[4] = child_tidptr,
3770 * %db[5] = newtls)
3771 */
3772 "{\n\t"
3773 " sdisp %%ctpr1, 0x3\n\t"
3774 "}\n\t"
3775 "{\n\t"
3776 " call %%ctpr1, wbs = %#\n\t"
3777 "}\n\t"
3778
3779 /* if (%[b0] != 0)
3780 * return %b[0];
3781 */
3782 "{\n\t"
3783 " disp %%ctpr1, .L2\n\t"
3784 " cmpesb,s 0x0, %%b[0], %%pred0\n\t"
3785 "}\n\t"
3786 "{\n\t"
3787 " ct %%ctpr1 ? ~%%pred0\n\t"
3788 "}\n\t"
3789 /* In the child, now. Call "fn(arg)".
3790 */
3791
3792 "{\n\t"
3793 " movtd,s %[fn], %%ctpr1\n\t"
3794 "}\n\t"
3795 "{\n\t"
3796 " addd,s 0x0, %[arg], %%db[0]\n\t"
3797 "}\n\t"
3798 "{\n\t"
3799 " call %%ctpr1, wbs = %#\n\t"
3800 "}\n\t"
3801 /* Call _exit(%b[0]).
3802 */
3803
3804 "{\n\t"
3805 " sdisp %%ctpr1, 0x3\n\t"
3806 " addd,s 0x0, %%b[0], %%b[1]\n\t"
3807 "}\n\t"
3808 "{\n\t"
3809 " addd,s 0x0, %[nr_exit], %%b[0]\n\t"
3810 "}\n\t"
3811 "{\n\t"
3812 " call %%ctpr1, wbs = %#\n\t"
3813 "}\n\t"
3814 "{\n\t"
3815 " disp %%ctpr1, .L2\n\t"
3816 " adds,s 0x0, 0x0, %%b[0]\n\t"
3817 "}\n\t"
3818 "{\n\t"
3819 " ct %%ctpr1\n\t"
3820 "}\n\t"
3821 ".L1:\n\t"
3822 "{\n\t"
3823 " addd,s 0x0, %[einval], %%b[0]\n\t"
3824 "}\n\t"
3825 ".L2:\n\t"
3826 "{\n\t"
3827 " addd,s 0x0, %%b[0], %[res]\n\t"
3828 "}\n\t"
3829 : [res] "=r" LSS_SYSCALL_ARG(__res)
3830 : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone)
3831 [arg] "ri" LSS_SYSCALL_ARG(arg)
3832 [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit)
3833 [flags] "ri" LSS_SYSCALL_ARG(flags)
3834 [child_stack] "ri" LSS_SYSCALL_ARG(child_stack)
3835 [parent_tidptr] "ri"
3836 LSS_SYSCALL_ARG(parent_tidptr)
3837 [newtls] "ri" LSS_SYSCALL_ARG(newtls)
3838 [child_tidptr] "ri"
3839 LSS_SYSCALL_ARG(child_tidptr)
3840 [fn] "ri" LSS_SYSCALL_ARG(fn)
3841 [einval] "ri" LSS_SYSCALL_ARG(-EINVAL)
3842 : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]",
3843 "b[4]", "b[5]", "pred0");
3844 LSS_RETURN(int, __res);
3845 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08003846 #elif defined(__loongarch_lp64)
3847 /* Most definitions of _syscallX() neglect to mark "memory" as being
3848 * clobbered. This causes problems with compilers, that do a better job
3849 * at optimizing across __asm__ calls.
3850 * So, we just have to redefine all of the _syscallX() macros.
3851 */
3852 #undef LSS_REG
3853 #define LSS_REG(ar,a) register int64_t __r##ar __asm__("a"#ar) = (int64_t)a
3854 /* syscall is like subroutine calls, all caller-saved registers may be
3855 * clobbered, we should add them to the |Clobbers| list.
3856 * a0 is not included because it's in the output list.
3857 */
3858 #define LSS_SYSCALL_CLOBBERS "t0", "t1", "t2", "t3", "t4", "t5", "t6", \
3859 "t7", "t8", "memory"
3860 #undef LSS_BODY
3861 #define LSS_BODY(type,name,args...) \
3862 register int64_t __res_a0 __asm__("a0"); \
3863 int64_t __res; \
3864 __asm__ __volatile__ ("li.d $a7, %1\n" \
3865 "syscall 0x0\n" \
3866 : "=r"(__res_a0) \
3867 : "i"(__NR_##name) , ## args \
3868 : LSS_SYSCALL_CLOBBERS); \
3869 __res = __res_a0; \
3870 LSS_RETURN(type, __res)
3871 #undef _syscall0
3872 #define _syscall0(type, name) \
3873 type LSS_NAME(name)(void) { \
3874 LSS_BODY(type, name); \
3875 }
3876 #undef _syscall1
3877 #define _syscall1(type, name, type1, arg1) \
3878 type LSS_NAME(name)(type1 arg1) { \
3879 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
3880 }
3881 #undef _syscall2
3882 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3883 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3884 LSS_REG(0, arg1); LSS_REG(1, arg2); \
3885 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
3886 }
3887 #undef _syscall3
3888 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3889 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3890 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3891 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
3892 }
3893 #undef _syscall4
3894 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3895 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3896 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3897 LSS_REG(3, arg4); \
3898 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
3899 }
3900 #undef _syscall5
3901 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3902 type5,arg5) \
3903 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3904 type5 arg5) { \
3905 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3906 LSS_REG(3, arg4); LSS_REG(4, arg5); \
3907 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3908 "r"(__r4)); \
3909 }
3910 #undef _syscall6
3911 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3912 type5,arg5,type6,arg6) \
3913 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3914 type5 arg5, type6 arg6) { \
3915 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3916 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
3917 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3918 "r"(__r4), "r"(__r5)); \
3919 }
3920
3921 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3922 int flags, void *arg, int *parent_tidptr,
3923 void *newtls, int *child_tidptr) {
3924 int64_t __res;
3925 {
3926 register int64_t __res_a0 __asm__("a0");
3927 register uint64_t __flags __asm__("a0") = flags;
3928 register void *__stack __asm__("a1") = child_stack;
3929 register void *__ptid __asm__("a2") = parent_tidptr;
3930 register void *__tls __asm__("a3") = newtls;
3931 register int *__ctid __asm__("a4") = child_tidptr;
3932 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
3933 * used by the child.
3934 */
3935 "addi.d %2, %2, -16\n"
3936 "st.d %1, %2, 8\n"
3937 "st.d %4, %2, 0\n"
3938
3939 /* %a0 = syscall(%a0 = flags,
3940 * %a1 = child_stack,
3941 * %a2 = parent_tidptr,
3942 * %a3 = newtls,
3943 * %a4 = child_tidptr)
3944 */
3945 "li.d $a7, %8\n"
3946 "syscall 0x0\n"
3947
3948 /* if (%a0 != 0)
3949 * return %a0;
3950 */
3951 "bnez $a0, 1f\n"
3952
3953 /* In the child, now. Call "fn(arg)".
3954 */
3955 "ld.d $a0, $sp, 0\n"
3956 "ld.d $a1, $sp, 8\n"
3957 "addi.d $sp, $sp, 16\n"
3958 "jirl $ra, $a1, 0\n"
3959
3960 /* Call _exit(%a0).
3961 */
3962 "li.d $a7, %9\n"
3963 "syscall 0x0\n"
3964 "1:\n"
3965 : "=r" (__res_a0)
3966 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
3967 "r"(__ptid), "r"(__tls), "r"(__ctid),
3968 "i"(__NR_clone), "i"(__NR_exit)
3969 : LSS_SYSCALL_CLOBBERS);
3970 __res = __res_a0;
3971 }
3972 LSS_RETURN(int, __res);
3973 }
Konstantin Ivlev8007b272021-01-27 18:27:42 +03003974
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003975 #endif
3976 #define __NR__exit __NR_exit
3977 #define __NR__gettid __NR_gettid
3978 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00003979 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003980 LSS_INLINE _syscall1(int, chdir, const char *,p)
3981 LSS_INLINE _syscall1(int, close, int, f)
3982 LSS_INLINE _syscall2(int, clock_getres, int, c,
3983 struct kernel_timespec*, t)
3984 LSS_INLINE _syscall2(int, clock_gettime, int, c,
3985 struct kernel_timespec*, t)
3986 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003987 #if defined(__NR_dup2)
3988 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003989 LSS_INLINE _syscall2(int, dup2, int, s,
3990 int, d)
3991 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003992 #if defined(__NR_dup3)
3993 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3994 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003995 LSS_INLINE _syscall3(int, execve, const char*, f,
3996 const char*const*,a,const char*const*, e)
3997 LSS_INLINE _syscall1(int, _exit, int, e)
3998 LSS_INLINE _syscall1(int, exit_group, int, e)
3999 LSS_INLINE _syscall3(int, fcntl, int, f,
4000 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004001 #if defined(__NR_fork)
4002 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004003 LSS_INLINE _syscall0(pid_t, fork)
4004 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004005 #if defined(__NR_fstat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004006 LSS_INLINE _syscall2(int, fstat, int, f,
4007 struct kernel_stat*, b)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004008 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004009 LSS_INLINE _syscall2(int, fstatfs, int, f,
4010 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004011 #if defined(__x86_64__)
4012 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
4013 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
4014 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
4015 }
4016 #else
4017 LSS_INLINE _syscall2(int, ftruncate, int, f,
4018 off_t, l)
4019 #endif
Mike Frysinger171a36a2019-01-26 23:05:43 -05004020 LSS_INLINE _syscall6(int, futex, int*, u,
4021 int, o, int, v,
4022 struct kernel_timespec*, t,
4023 int*, u2, int, v2)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004024 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004025 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004026 LSS_INLINE _syscall3(int, getdents64, int, f,
4027 struct kernel_dirent64*, d, int, c)
4028 LSS_INLINE _syscall0(gid_t, getegid)
4029 LSS_INLINE _syscall0(uid_t, geteuid)
Doug Kwan32a80cd2022-07-01 17:52:39 +00004030 LSS_INLINE _syscall2(int, getitimer, int, w,
4031 struct kernel_itimerval*, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004032 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004033 LSS_INLINE _syscall0(pid_t, getpgrp)
4034 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004035 LSS_INLINE _syscall0(pid_t, getpid)
4036 LSS_INLINE _syscall0(pid_t, getppid)
4037 LSS_INLINE _syscall2(int, getpriority, int, a,
4038 int, b)
4039 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
4040 gid_t *, e, gid_t *, s)
4041 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
4042 uid_t *, e, uid_t *, s)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004043 #if defined(__NR_getrlimit)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004044 LSS_INLINE _syscall2(int, getrlimit, int, r,
4045 struct kernel_rlimit*, l)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004046 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004047 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
4048 LSS_INLINE _syscall0(pid_t, _gettid)
4049 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
4050 void*, tz)
4051 LSS_INLINE _syscall5(int, setxattr, const char *,p,
4052 const char *, n, const void *,v,
4053 size_t, s, int, f)
4054 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
4055 const char *, n, const void *,v,
4056 size_t, s, int, f)
4057 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
4058 const char *, n, void *, v, size_t, s)
4059 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
4060 const char *, n, void *, v, size_t, s)
4061 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
4062 char *, l, size_t, s)
4063 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
4064 char *, l, size_t, s)
4065 LSS_INLINE _syscall3(int, ioctl, int, d,
4066 int, r, void *, a)
4067 LSS_INLINE _syscall2(int, ioprio_get, int, which,
4068 int, who)
4069 LSS_INLINE _syscall3(int, ioprio_set, int, which,
4070 int, who, int, ioprio)
4071 LSS_INLINE _syscall2(int, kill, pid_t, p,
4072 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004073 #if defined(__x86_64__)
4074 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
4075 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
4076 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4077 LSS_SYSCALL_ARG(w));
4078 }
4079 #else
4080 LSS_INLINE _syscall3(off_t, lseek, int, f,
4081 off_t, o, int, w)
4082 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004083 LSS_INLINE _syscall2(int, munmap, void*, s,
4084 size_t, l)
4085 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
4086 unsigned long, n, void **,g, int *, d,
4087 int *, s, int, f)
4088 LSS_INLINE _syscall3(int, mprotect, const void *,a,
4089 size_t, l, int, p)
4090 LSS_INLINE _syscall5(void*, _mremap, void*, o,
4091 size_t, os, size_t, ns,
4092 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004093 #if defined(__NR_open)
4094 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004095 LSS_INLINE _syscall3(int, open, const char*, p,
4096 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004097 #endif
4098 #if defined(__NR_poll)
4099 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004100 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
4101 unsigned int, n, int, t)
4102 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004103 #if defined(__NR_ppoll)
4104 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
4105 unsigned int, n, const struct kernel_timespec *, t,
4106 const struct kernel_sigset_t *, sigmask, size_t, s)
4107 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00004108 LSS_INLINE _syscall5(int, prctl, int, option,
4109 unsigned long, arg2,
4110 unsigned long, arg3,
4111 unsigned long, arg4,
4112 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004113 LSS_INLINE _syscall4(long, ptrace, int, r,
4114 pid_t, p, void *, a, void *, d)
4115 #if defined(__NR_quotactl)
4116 // Defined on x86_64 / i386 only
4117 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
4118 int, id, caddr_t, addr)
4119 #endif
4120 LSS_INLINE _syscall3(ssize_t, read, int, f,
4121 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004122 #if defined(__NR_readlink)
4123 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004124 LSS_INLINE _syscall3(int, readlink, const char*, p,
4125 char*, b, size_t, s)
4126 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004127 #if defined(__NR_readlinkat)
4128 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
4129 size_t, s)
4130 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004131 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
4132 const struct kernel_sigaction*, a,
4133 struct kernel_sigaction*, o, size_t, c)
4134 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
4135 size_t, c)
4136 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
4137 const struct kernel_sigset_t*, s,
4138 struct kernel_sigset_t*, o, size_t, c)
4139 LSS_INLINE _syscall2(int, rt_sigsuspend,
4140 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08004141 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
4142 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004143 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
4144 unsigned int, l, unsigned long *, m)
4145 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
4146 unsigned int, l, unsigned long *, m)
4147 LSS_INLINE _syscall0(int, sched_yield)
4148 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
4149 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
4150 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
4151 LSS_INLINE _syscall1(int, setuid, uid_t, u)
4152 LSS_INLINE _syscall1(int, setgid, gid_t, g)
Doug Kwan32a80cd2022-07-01 17:52:39 +00004153 LSS_INLINE _syscall3(int, setitimer, int, w,
4154 const struct kernel_itimerval*, n,
4155 struct kernel_itimerval*, o)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004156 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
4157 pid_t, g)
4158 LSS_INLINE _syscall3(int, setpriority, int, a,
4159 int, b, int, p)
4160 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
4161 gid_t, e, gid_t, s)
4162 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
4163 uid_t, e, uid_t, s)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004164 #if defined(__NR_setrlimit)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004165 LSS_INLINE _syscall2(int, setrlimit, int, r,
4166 const struct kernel_rlimit*, l)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004167 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004168 LSS_INLINE _syscall0(pid_t, setsid)
4169 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
4170 const stack_t*, o)
4171 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004172 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004173 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004174 #if defined(__NR_stat)
Matthew Denton92a65a82021-04-01 13:00:07 -07004175 // stat and lstat are polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004176 LSS_INLINE _syscall2(int, stat, const char*, f,
4177 struct kernel_stat*, b)
4178 #endif
Matthew Denton92a65a82021-04-01 13:00:07 -07004179 #if defined(__NR_lstat)
4180 LSS_INLINE _syscall2(int, lstat, const char*, f,
4181 struct kernel_stat*, b)
4182 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004183 LSS_INLINE _syscall2(int, statfs, const char*, f,
4184 struct kernel_statfs*, b)
4185 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
4186 pid_t, t, int, s)
4187 LSS_INLINE _syscall2(int, tkill, pid_t, p,
4188 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004189 #if defined(__NR_unlink)
4190 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004191 LSS_INLINE _syscall1(int, unlink, const char*, f)
4192 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004193 LSS_INLINE _syscall3(ssize_t, write, int, f,
4194 const void *, b, size_t, c)
4195 LSS_INLINE _syscall3(ssize_t, writev, int, f,
4196 const struct kernel_iovec*, v, size_t, c)
4197 #if defined(__NR_getcpu)
4198 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00004199 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004200 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004201 #if defined(__NR_fadvise64)
4202 #if defined(__x86_64__)
4203 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4204 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
4205 int advice) {
4206 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
4207 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
4208 }
4209 #else
4210 LSS_INLINE _syscall4(int, fadvise64,
4211 int, fd, loff_t, offset, loff_t, len, int, advice)
4212 #endif
4213 #elif defined(__i386__)
4214 #define __NR__fadvise64_64 __NR_fadvise64_64
4215 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
4216 unsigned, offset_lo, unsigned, offset_hi,
4217 unsigned, len_lo, unsigned, len_hi,
4218 int, advice)
4219
4220 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4221 loff_t len, int advice) {
4222 return LSS_NAME(_fadvise64_64)(fd,
4223 (unsigned)offset, (unsigned)(offset >>32),
4224 (unsigned)len, (unsigned)(len >> 32),
4225 advice);
4226 }
4227
4228 #elif defined(__s390__) && !defined(__s390x__)
4229 #define __NR__fadvise64_64 __NR_fadvise64_64
4230 struct kernel_fadvise64_64_args {
4231 int fd;
4232 long long offset;
4233 long long len;
4234 int advice;
4235 };
4236
4237 LSS_INLINE _syscall1(int, _fadvise64_64,
4238 struct kernel_fadvise64_64_args *args)
4239
4240 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4241 loff_t len, int advice) {
4242 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
4243 return LSS_NAME(_fadvise64_64)(&args);
4244 }
4245 #endif
4246 #if defined(__NR_fallocate)
4247 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004248 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4249 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
4250 loff_t len) {
4251 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
4252 (uint64_t)(offset), (uint64_t)(len));
4253 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08004254 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
4255 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
4256 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
4257 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04004258 #define __NR__fallocate __NR_fallocate
4259 LSS_INLINE _syscall6(int, _fallocate, int, fd,
4260 int, mode,
4261 unsigned, offset_lo, unsigned, offset_hi,
4262 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004263
Bryan Chan3f6478a2016-06-14 08:38:17 -04004264 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
4265 loff_t offset, loff_t len) {
4266 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
4267 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
4268 }
4269 #else
4270 LSS_INLINE _syscall4(int, fallocate,
4271 int, f, int, mode, loff_t, offset, loff_t, len)
4272 #endif
4273 #endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07004274 #if defined(__NR_getrandom)
4275 LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length,
4276 unsigned int, flags)
4277 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004278 #if defined(__NR_newfstatat)
4279 LSS_INLINE _syscall4(int, newfstatat, int, d,
4280 const char *, p,
4281 struct kernel_stat*, b, int, f)
4282 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004283 #if defined(__NR_statx)
4284 LSS_INLINE _syscall5(int, statx, int, d,
4285 const char *, p,
4286 int, f, int, m,
4287 struct kernel_statx*, b)
4288 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004289 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004290 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4291 gid_t *egid,
4292 gid_t *sgid) {
4293 return LSS_NAME(getresgid)(rgid, egid, sgid);
4294 }
4295
4296 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4297 uid_t *euid,
4298 uid_t *suid) {
4299 return LSS_NAME(getresuid)(ruid, euid, suid);
4300 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004301
4302 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4303 return LSS_NAME(setfsgid)(gid);
4304 }
4305
4306 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4307 return LSS_NAME(setfsuid)(uid);
4308 }
4309
4310 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4311 return LSS_NAME(setresgid)(rgid, egid, sgid);
4312 }
4313
4314 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4315 return LSS_NAME(setresuid)(ruid, euid, suid);
4316 }
4317
4318 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4319 const struct kernel_sigaction *act,
4320 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04004321 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004322 /* On x86_64, the kernel requires us to always set our own
4323 * SA_RESTORER in order to be able to return from a signal handler.
4324 * This function must have a "magic" signature that the "gdb"
4325 * (and maybe the kernel?) can recognize.
4326 */
4327 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
4328 struct kernel_sigaction a = *act;
4329 a.sa_flags |= SA_RESTORER;
4330 a.sa_restorer = LSS_NAME(restore_rt)();
4331 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
4332 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04004333 } else
4334 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004335 return LSS_NAME(rt_sigaction)(signum, act, oldact,
4336 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004337 }
4338
4339 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4340 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4341 }
4342
Joshua Peraza726d71e2019-11-13 12:21:13 -08004343 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4344 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4345 }
4346 #endif
4347 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004348 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
4349 const struct kernel_sigset_t *set,
4350 struct kernel_sigset_t *oldset) {
4351 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
4352 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08004353 #endif
4354 #if defined(__NR_rt_sigtimedwait)
4355 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
4356 siginfo_t *info,
4357 const struct timespec *timeout) {
4358 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004359 }
4360 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004361 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004362 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
4363 int*, s, int, o,
4364 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004365 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004366 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004367 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004368 #endif
4369 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004370 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
4371 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004372 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4373 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004374 #define __NR__getresgid32 __NR_getresgid32
4375 #define __NR__getresuid32 __NR_getresuid32
4376 #define __NR__setfsgid32 __NR_setfsgid32
4377 #define __NR__setfsuid32 __NR_setfsuid32
4378 #define __NR__setresgid32 __NR_setresgid32
4379 #define __NR__setresuid32 __NR_setresuid32
4380#if defined(__ARM_EABI__)
4381 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
4382 struct kernel_rlimit*, l)
4383#endif
4384 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
4385 gid_t *, e, gid_t *, s)
4386 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
4387 uid_t *, e, uid_t *, s)
4388 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
4389 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
4390 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
4391 gid_t, e, gid_t, s)
4392 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
4393 uid_t, e, uid_t, s)
4394
4395 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4396 gid_t *egid,
4397 gid_t *sgid) {
4398 int rc;
4399 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
4400 LSS_ERRNO == ENOSYS) {
4401 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
4402 return EFAULT;
4403 }
4404 // Clear the high bits first, since getresgid only sets 16 bits
4405 *rgid = *egid = *sgid = 0;
4406 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
4407 }
4408 return rc;
4409 }
4410
4411 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4412 uid_t *euid,
4413 uid_t *suid) {
4414 int rc;
4415 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
4416 LSS_ERRNO == ENOSYS) {
4417 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
4418 return EFAULT;
4419 }
4420 // Clear the high bits first, since getresuid only sets 16 bits
4421 *ruid = *euid = *suid = 0;
4422 rc = LSS_NAME(getresuid)(ruid, euid, suid);
4423 }
4424 return rc;
4425 }
4426
4427 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4428 int rc;
4429 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
4430 LSS_ERRNO == ENOSYS) {
4431 if ((unsigned int)gid & ~0xFFFFu) {
4432 rc = EINVAL;
4433 } else {
4434 rc = LSS_NAME(setfsgid)(gid);
4435 }
4436 }
4437 return rc;
4438 }
4439
4440 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4441 int rc;
4442 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
4443 LSS_ERRNO == ENOSYS) {
4444 if ((unsigned int)uid & ~0xFFFFu) {
4445 rc = EINVAL;
4446 } else {
4447 rc = LSS_NAME(setfsuid)(uid);
4448 }
4449 }
4450 return rc;
4451 }
4452
4453 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4454 int rc;
4455 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
4456 LSS_ERRNO == ENOSYS) {
4457 if ((unsigned int)rgid & ~0xFFFFu ||
4458 (unsigned int)egid & ~0xFFFFu ||
4459 (unsigned int)sgid & ~0xFFFFu) {
4460 rc = EINVAL;
4461 } else {
4462 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
4463 }
4464 }
4465 return rc;
4466 }
4467
4468 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4469 int rc;
4470 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
4471 LSS_ERRNO == ENOSYS) {
4472 if ((unsigned int)ruid & ~0xFFFFu ||
4473 (unsigned int)euid & ~0xFFFFu ||
4474 (unsigned int)suid & ~0xFFFFu) {
4475 rc = EINVAL;
4476 } else {
4477 rc = LSS_NAME(setresuid)(ruid, euid, suid);
4478 }
4479 }
4480 return rc;
4481 }
4482 #endif
4483 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
4484 memset(&set->sig, 0, sizeof(set->sig));
4485 return 0;
4486 }
4487
4488 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
4489 memset(&set->sig, -1, sizeof(set->sig));
4490 return 0;
4491 }
4492
4493 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
4494 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004495 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004496 LSS_ERRNO = EINVAL;
4497 return -1;
4498 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004499 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4500 |= 1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004501 return 0;
4502 }
4503 }
4504
4505 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
4506 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004507 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004508 LSS_ERRNO = EINVAL;
4509 return -1;
4510 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004511 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4512 &= ~(1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004513 return 0;
4514 }
4515 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004516
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004517 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
4518 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004519 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004520 LSS_ERRNO = EINVAL;
4521 return -1;
4522 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004523 return !!(set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] &
4524 (1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004525 }
4526 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04004527 #if defined(__i386__) || \
4528 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4529 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4530 defined(__PPC__) || \
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004531 (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004532 #define __NR__sigaction __NR_sigaction
4533 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004534 #define __NR__sigsuspend __NR_sigsuspend
4535 #define __NR__socketcall __NR_socketcall
4536 LSS_INLINE _syscall2(int, fstat64, int, f,
4537 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00004538 LSS_INLINE _syscall5(int, _llseek, uint, fd,
4539 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004540 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004541#if defined(__s390__) && !defined(__s390x__)
4542 /* On s390, mmap2() arguments are passed in memory. */
4543 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
4544 off_t o) {
4545 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4546 (unsigned long) p, (unsigned long) f,
4547 (unsigned long) d, (unsigned long) o };
4548 LSS_REG(2, buf);
4549 LSS_BODY(void*, mmap2, "0"(__r2));
4550 }
4551#else
4552 #define __NR__mmap2 __NR_mmap2
4553 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004554 size_t, l, int, p,
4555 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04004556 off_t, o)
4557#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004558 LSS_INLINE _syscall3(int, _sigaction, int, s,
4559 const struct kernel_old_sigaction*, a,
4560 struct kernel_old_sigaction*, o)
4561 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004562 #ifdef __PPC__
4563 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
4564 #else
4565 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
4566 int, b,
4567 unsigned long, s)
4568 #endif
4569 LSS_INLINE _syscall2(int, stat64, const char *, p,
4570 struct kernel_stat64 *, b)
4571
4572 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4573 const struct kernel_sigaction *act,
4574 struct kernel_sigaction *oldact) {
4575 int old_errno = LSS_ERRNO;
4576 int rc;
4577 struct kernel_sigaction a;
4578 if (act != NULL) {
4579 a = *act;
4580 #ifdef __i386__
4581 /* On i386, the kernel requires us to always set our own
4582 * SA_RESTORER when using realtime signals. Otherwise, it does not
4583 * know how to return from a signal handler. This function must have
4584 * a "magic" signature that the "gdb" (and maybe the kernel?) can
4585 * recognize.
4586 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
4587 * using non-realtime signals.
4588 *
4589 * TODO: Test whether ARM needs a restorer
4590 */
4591 if (!(a.sa_flags & SA_RESTORER)) {
4592 a.sa_flags |= SA_RESTORER;
4593 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
4594 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
4595 }
4596 #endif
4597 }
4598 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
4599 (KERNEL_NSIG+7)/8);
4600 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4601 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
4602 if (!act) {
4603 ptr_a = NULL;
4604 } else {
4605 oa.sa_handler_ = act->sa_handler_;
4606 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
4607 #ifndef __mips__
4608 oa.sa_restorer = act->sa_restorer;
4609 #endif
4610 oa.sa_flags = act->sa_flags;
4611 }
4612 if (!oldact) {
4613 ptr_oa = NULL;
4614 }
4615 LSS_ERRNO = old_errno;
4616 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
4617 if (rc == 0 && oldact) {
4618 if (act) {
4619 memcpy(oldact, act, sizeof(*act));
4620 } else {
4621 memset(oldact, 0, sizeof(*oldact));
4622 }
4623 oldact->sa_handler_ = ptr_oa->sa_handler_;
4624 oldact->sa_flags = ptr_oa->sa_flags;
4625 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4626 #ifndef __mips__
4627 oldact->sa_restorer = ptr_oa->sa_restorer;
4628 #endif
4629 }
4630 }
4631 return rc;
4632 }
4633
4634 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4635 int old_errno = LSS_ERRNO;
4636 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4637 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4638 LSS_ERRNO = old_errno;
4639 LSS_NAME(sigemptyset)(set);
4640 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4641 }
4642 return rc;
4643 }
4644
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004645 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4646 int olderrno = LSS_ERRNO;
4647 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4648 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4649 LSS_ERRNO = olderrno;
4650 rc = LSS_NAME(_sigsuspend)(
4651 #ifndef __PPC__
4652 set, 0,
4653 #endif
4654 set->sig[0]);
4655 }
4656 return rc;
4657 }
4658 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004659 #if defined(__i386__) || \
4660 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4661 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4662 defined(__PPC__) || \
4663 (defined(__s390__) && !defined(__s390x__))
4664 /* On these architectures, implement mmap() with mmap2(). */
4665 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4666 int64_t o) {
4667 if (o % 4096) {
4668 LSS_ERRNO = EINVAL;
4669 return (void *) -1;
4670 }
4671 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4672 }
4673 #elif defined(__s390x__)
4674 /* On s390x, mmap() arguments are passed in memory. */
4675 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4676 int64_t o) {
4677 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4678 (unsigned long) p, (unsigned long) f,
4679 (unsigned long) d, (unsigned long) o };
4680 LSS_REG(2, buf);
4681 LSS_BODY(void*, mmap, "0"(__r2));
4682 }
4683 #elif defined(__x86_64__)
4684 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4685 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4686 int64_t o) {
4687 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4688 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4689 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4690 }
4691 #else
4692 /* Remaining 64-bit architectures. */
4693 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4694 int, flags, int, fd, int64_t, offset)
4695 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004696 #if defined(__PPC__)
4697 #undef LSS_SC_LOADARGS_0
4698 #define LSS_SC_LOADARGS_0(dummy...)
4699 #undef LSS_SC_LOADARGS_1
4700 #define LSS_SC_LOADARGS_1(arg1) \
4701 __sc_4 = (unsigned long) (arg1)
4702 #undef LSS_SC_LOADARGS_2
4703 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4704 LSS_SC_LOADARGS_1(arg1); \
4705 __sc_5 = (unsigned long) (arg2)
4706 #undef LSS_SC_LOADARGS_3
4707 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4708 LSS_SC_LOADARGS_2(arg1, arg2); \
4709 __sc_6 = (unsigned long) (arg3)
4710 #undef LSS_SC_LOADARGS_4
4711 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4712 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4713 __sc_7 = (unsigned long) (arg4)
4714 #undef LSS_SC_LOADARGS_5
4715 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4716 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4717 __sc_8 = (unsigned long) (arg5)
4718 #undef LSS_SC_BODY
4719 #define LSS_SC_BODY(nr, type, opt, args...) \
4720 long __sc_ret, __sc_err; \
4721 { \
4722 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4723 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4724 register unsigned long __sc_4 __asm__ ("r4"); \
4725 register unsigned long __sc_5 __asm__ ("r5"); \
4726 register unsigned long __sc_6 __asm__ ("r6"); \
4727 register unsigned long __sc_7 __asm__ ("r7"); \
4728 register unsigned long __sc_8 __asm__ ("r8"); \
4729 LSS_SC_LOADARGS_##nr(args); \
4730 __asm__ __volatile__ \
4731 ("stwu 1, -48(1)\n\t" \
4732 "stw 4, 20(1)\n\t" \
4733 "stw 5, 24(1)\n\t" \
4734 "stw 6, 28(1)\n\t" \
4735 "stw 7, 32(1)\n\t" \
4736 "stw 8, 36(1)\n\t" \
4737 "addi 4, 1, 20\n\t" \
4738 "sc\n\t" \
4739 "mfcr %0" \
4740 : "=&r" (__sc_0), \
4741 "=&r" (__sc_3), "=&r" (__sc_4), \
4742 "=&r" (__sc_5), "=&r" (__sc_6), \
4743 "=&r" (__sc_7), "=&r" (__sc_8) \
4744 : LSS_ASMINPUT_##nr \
4745 : "cr0", "ctr", "memory"); \
4746 __sc_ret = __sc_3; \
4747 __sc_err = __sc_0; \
4748 } \
4749 LSS_RETURN(type, __sc_ret, __sc_err)
4750
4751 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4752 int flags){
4753 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4754 }
4755
4756 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4757 const struct kernel_msghdr *msg,
4758 int flags) {
4759 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4760 }
4761
4762 // TODO(csilvers): why is this ifdef'ed out?
4763#if 0
4764 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4765 int flags,
4766 const struct kernel_sockaddr *to,
4767 unsigned int tolen) {
4768 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4769 }
4770#endif
4771
4772 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4773 LSS_SC_BODY(2, int, 13, s, how);
4774 }
4775
4776 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4777 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4778 }
4779
4780 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4781 int sv[2]) {
4782 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4783 }
4784 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004785 #if defined(__NR_recvmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004786 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4787 int, flags)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004788 #endif
4789 #if defined(__NR_sendmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004790 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4791 msg, int, flags)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004792 #endif
4793 #if defined(__NR_sendto)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004794 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4795 int, flags, const struct kernel_sockaddr*, to,
4796 unsigned int, tolen)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004797 #endif
4798 #if defined(__NR_shutdown)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004799 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004800 #endif
4801 #if defined(__NR_socket)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004802 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004803 #endif
4804 #if defined(__NR_socketpair)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004805 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4806 int*, sv)
4807 #endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004808
4809 #if defined(__NR_socketcall)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004810 LSS_INLINE _syscall2(int, _socketcall, int, c,
4811 va_list, a)
4812 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4813 int rc;
4814 va_list ap;
4815 va_start(ap, op);
4816 rc = LSS_NAME(_socketcall)(op, ap);
4817 va_end(ap);
4818 return rc;
4819 }
4820
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004821 # if !defined(__NR_recvmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004822 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4823 int flags){
4824 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4825 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004826 # endif
4827 # if !defined(__NR_sendmsg)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004828 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4829 const struct kernel_msghdr *msg,
4830 int flags) {
4831 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4832 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004833 # endif
4834 # if !defined(__NR_sendto)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004835 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4836 int flags,
4837 const struct kernel_sockaddr *to,
4838 unsigned int tolen) {
4839 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4840 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004841 # endif
4842 # if !defined(__NR_shutdown)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004843 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4844 return LSS_NAME(socketcall)(13, s, how);
4845 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004846 # endif
4847 # if !defined(__NR_socket)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004848 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4849 return LSS_NAME(socketcall)(1, domain, type, protocol);
4850 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004851 # endif
4852 # if !defined(__NR_socketpair)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004853 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4854 int sv[2]) {
4855 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4856 }
mingtaoxt xtc0c96892022-08-11 16:53:21 +08004857 # endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004858 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004859 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004860 LSS_INLINE _syscall4(int, fstatat64, int, d,
4861 const char *, p,
4862 struct kernel_stat64 *, b, int, f)
4863 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004864 #if defined(__NR_waitpid)
4865 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004866 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4867 int*, s, int, o)
4868 #endif
4869 #if defined(__mips__)
4870 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4871 * both file handles through CPU registers.
4872 */
4873 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4874 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4875 register unsigned long __v1 __asm__("$3");
4876 register unsigned long __r7 __asm__("$7");
4877 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004878 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004879 : "0"(__v0)
4880 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004881 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004882 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004883 unsigned long __errnovalue = __v0;
4884 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004885 return -1;
4886 } else {
4887 p[0] = __v0;
4888 p[1] = __v1;
4889 return 0;
4890 }
4891 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004892 #elif defined(__NR_pipe)
4893 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004894 LSS_INLINE _syscall1(int, pipe, int *, p)
4895 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004896 #if defined(__NR_pipe2)
4897 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4898 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004899 /* TODO(csilvers): see if ppc can/should support this as well */
4900 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004901 defined(__ARM_EABI__) || \
4902 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4903 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004904 #define __NR__statfs64 __NR_statfs64
4905 #define __NR__fstatfs64 __NR_fstatfs64
4906 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4907 size_t, s,struct kernel_statfs64*, b)
4908 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4909 size_t, s,struct kernel_statfs64*, b)
4910 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
4911 struct kernel_statfs64 *b) {
4912 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
4913 }
4914 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
4915 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
4916 }
4917 #endif
4918
4919 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
4920 extern char **environ;
4921 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
4922 }
4923
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004924 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004925 pid_t tid = LSS_NAME(_gettid)();
4926 if (tid != -1) {
4927 return tid;
4928 }
4929 return LSS_NAME(getpid)();
4930 }
4931
4932 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
4933 size_t new_size, int flags, ...) {
4934 va_list ap;
4935 void *new_address, *rc;
4936 va_start(ap, flags);
4937 new_address = va_arg(ap, void *);
4938 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
Peter Kasting880985f2022-06-29 21:17:55 +00004939 (unsigned long)flags, new_address);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004940 va_end(ap);
4941 return rc;
4942 }
4943
Peter Kasting880985f2022-06-29 21:17:55 +00004944 LSS_INLINE long LSS_NAME(ptrace_detach)(pid_t pid) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004945 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
4946 * then sends job control signals to the real parent, rather than to
4947 * the tracer. We reduce the risk of this happening by starting a
4948 * whole new time slice, and then quickly sending a SIGCONT signal
4949 * right after detaching from the tracee.
4950 *
4951 * We use tkill to ensure that we only issue a wakeup for the thread being
4952 * detached. Large multi threaded apps can take a long time in the kernel
4953 * processing SIGCONT.
4954 */
Peter Kasting880985f2022-06-29 21:17:55 +00004955 long rc;
4956 int err;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004957 LSS_NAME(sched_yield)();
4958 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
4959 err = LSS_ERRNO;
4960 LSS_NAME(tkill)(pid, SIGCONT);
4961 /* Old systems don't have tkill */
4962 if (LSS_ERRNO == ENOSYS)
4963 LSS_NAME(kill)(pid, SIGCONT);
4964 LSS_ERRNO = err;
4965 return rc;
4966 }
4967
4968 LSS_INLINE int LSS_NAME(raise)(int sig) {
4969 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
4970 }
4971
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004972 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004973 return LSS_NAME(setpgid)(0, 0);
4974 }
4975
vapier@chromium.org2273e812013-04-01 17:52:44 +00004976 #if defined(__x86_64__)
4977 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4978 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
4979 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4980 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4981 }
4982
4983 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
4984 loff_t o) {
4985 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4986 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4987 }
4988
Peter Kasting3bb68592022-07-18 19:29:31 +00004989 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, size_t c) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00004990 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4991 LSS_SYSCALL_ARG(c));
4992 }
4993 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004994 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
4995 void *, b, size_t, c,
4996 loff_t, o)
4997 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
4998 const void *, b, size_t, c,
4999 loff_t, o)
5000 LSS_INLINE _syscall3(int, readahead, int, f,
5001 loff_t, o, unsigned, c)
5002 #else
5003 #define __NR__pread64 __NR_pread64
5004 #define __NR__pwrite64 __NR_pwrite64
5005 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00005006 #if defined(__ARM_EABI__) || defined(__mips__)
5007 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
5008 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005009 * fifth and sixth make such a pair (r4,r5).
5010 */
5011 #define LSS_LLARG_PAD 0,
5012 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
5013 void *, b, size_t, c,
5014 unsigned, skip, unsigned, o1, unsigned, o2)
5015 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
5016 const void *, b, size_t, c,
5017 unsigned, skip, unsigned, o1, unsigned, o2)
5018 LSS_INLINE _syscall5(int, _readahead, int, f,
5019 unsigned, skip,
5020 unsigned, o1, unsigned, o2, size_t, c)
5021 #else
5022 #define LSS_LLARG_PAD
5023 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
5024 void *, b, size_t, c, unsigned, o1,
5025 unsigned, o2)
5026 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
5027 const void *, b, size_t, c, unsigned, o1,
Samuel Attardacbdd592022-07-26 16:02:01 +00005028 unsigned, o2)
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005029 LSS_INLINE _syscall4(int, _readahead, int, f,
5030 unsigned, o1, unsigned, o2, size_t, c)
5031 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005032 /* We force 64bit-wide parameters onto the stack, then access each
5033 * 32-bit component individually. This guarantees that we build the
5034 * correct parameters independent of the native byte-order of the
5035 * underlying architecture.
5036 */
5037 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
5038 loff_t off) {
5039 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005040 return LSS_NAME(_pread64)(fd, buf, count,
5041 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005042 }
5043 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
5044 size_t count, loff_t off) {
5045 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00005046 return LSS_NAME(_pwrite64)(fd, buf, count,
5047 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005048 }
Peter Kasting3bb68592022-07-18 19:29:31 +00005049 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, size_t count) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005050 union { loff_t off; unsigned arg[2]; } o = { off };
Peter Kasting3bb68592022-07-18 19:29:31 +00005051 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], count);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005052 }
5053 #endif
5054#endif
5055
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005056/*
5057 * Polyfills for deprecated syscalls.
5058 */
5059
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005060#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005061 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
5062 return LSS_NAME(dup3)(s, d, 0);
5063 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005064#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005065
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005066#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005067 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
5068 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
5069 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005070#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005071
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005072#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005073 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
5074 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
5075 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005076#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005077
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005078#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005079 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
5080 size_t size) {
5081 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
5082 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005083#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005084
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005085#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05005086 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005087 return LSS_NAME(pipe2)(pipefd, 0);
5088 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005089#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005090
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005091#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005092 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
5093 int timeout) {
5094 struct kernel_timespec timeout_ts;
5095 struct kernel_timespec *timeout_ts_p = NULL;
5096
5097 if (timeout >= 0) {
5098 timeout_ts.tv_sec = timeout / 1000;
5099 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
5100 timeout_ts_p = &timeout_ts;
5101 }
5102 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
5103 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005104#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005105
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005106#if defined(__NR_statx)
5107 /* copy the contents of kernel_statx to the kernel_stat structure. */
5108 LSS_INLINE void LSS_NAME(cp_stat_statx)(struct kernel_stat *to,
5109 struct kernel_statx *from) {
5110 memset(to, 0, sizeof(struct kernel_stat));
5111 to->st_dev = ((from->stx_dev_minor & 0xff) |
5112 ((from->stx_dev_major & 0xfff) << 8) |
5113 ((from->stx_dev_minor & ~0xff) << 12));
5114 to->st_rdev = ((from->stx_rdev_minor & 0xff) |
5115 ((from->stx_rdev_major & 0xfff) << 8) |
5116 ((from->stx_rdev_minor & ~0xff) << 12));
5117 to->st_ino = from->stx_ino;
5118 to->st_mode = from->stx_mode;
5119 to->st_nlink = from->stx_nlink;
5120 to->st_uid = from->stx_uid;
5121 to->st_gid = from->stx_gid;
5122 to->st_atime_ = from->stx_atime.tv_sec;
5123 to->st_atime_nsec_ = from->stx_atime.tv_nsec;
5124 to->st_mtime_ = from->stx_mtime.tv_sec;
5125 to->st_mtime_nsec_ = from->stx_mtime.tv_nsec;
5126 to->st_ctime_ = from->stx_ctime.tv_sec;
5127 to->st_ctime_nsec_ = from->stx_ctime.tv_nsec;
5128 to->st_size = from->stx_size;
5129 to->st_blocks = from->stx_blocks;
5130 to->st_blksize = from->stx_blksize;
5131 }
5132#endif
5133
5134#if !defined(__NR_fstat)
5135 LSS_INLINE int LSS_NAME(fstat)(int fd,
5136 struct kernel_stat *buf) {
5137 #if defined(__NR_newfstatat)
5138 return LSS_NAME(newfstatat)(fd, "", buf, AT_EMPTY_PATH);
5139 #elif defined(__NR_statx)
5140 struct kernel_statx stx;
5141 int flags = AT_NO_AUTOMOUNT | AT_EMPTY_PATH;
5142 int mask = STATX_BASIC_STATS;
5143 int res = LSS_NAME(statx)(fd, "", flags, mask, &stx);
5144 LSS_NAME(cp_stat_statx)(buf, &stx);
5145 return res;
5146 #endif
5147 }
5148#endif
5149
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005150#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005151 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
5152 struct kernel_stat *buf) {
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005153 #if defined(__NR_newfstatat)
5154 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
5155 #elif defined(__NR_statx)
5156 struct kernel_statx stx;
5157 int flags = AT_NO_AUTOMOUNT | AT_STATX_SYNC_AS_STAT;
5158 int mask = STATX_BASIC_STATS;
5159 int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx);
5160 LSS_NAME(cp_stat_statx)(buf, &stx);
5161 return res;
5162 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005163 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005164#endif
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005165
Matthew Denton92a65a82021-04-01 13:00:07 -07005166#if !defined(__NR_lstat)
5167 LSS_INLINE int LSS_NAME(lstat)(const char *pathname,
5168 struct kernel_stat *buf) {
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005169 #if defined(__NR_newfstatat)
5170 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW);
5171 #elif defined(__NR_statx)
5172 struct kernel_statx stx;
5173 int flags = AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW;
5174 int mask = STATX_BASIC_STATS;
5175 int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx);
5176 LSS_NAME(cp_stat_statx)(buf, &stx);
5177 return res;
5178 #endif
Matthew Denton92a65a82021-04-01 13:00:07 -07005179 }
5180#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005181
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005182#if !defined(__NR_waitpid)
5183 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
5184 return LSS_NAME(wait4)(pid, status, options, 0);
5185 }
5186#endif
5187
5188#if !defined(__NR_fork)
5189// TODO: define this in an arch-independant way instead of inlining the clone
5190// syscall body.
5191
mingtaoxt xtc0c96892022-08-11 16:53:21 +08005192# if defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005193 LSS_INLINE pid_t LSS_NAME(fork)(void) {
5194 // No fork syscall on aarch64 - implement by means of the clone syscall.
5195 // Note that this does not reset glibc's cached view of the PID/TID, so
5196 // some glibc interfaces might go wrong in the forked subprocess.
5197 int flags = SIGCHLD;
5198 void *child_stack = NULL;
5199 void *parent_tidptr = NULL;
5200 void *newtls = NULL;
5201 void *child_tidptr = NULL;
5202
5203 LSS_REG(0, flags);
5204 LSS_REG(1, child_stack);
5205 LSS_REG(2, parent_tidptr);
5206 LSS_REG(3, newtls);
5207 LSS_REG(4, child_tidptr);
5208 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
5209 "r"(__r4));
5210 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04005211# elif defined(__x86_64__)
5212 LSS_INLINE pid_t LSS_NAME(fork)(void) {
5213 // Android disallows the fork syscall on x86_64 - implement by means of the
5214 // clone syscall as above for aarch64.
5215 int flags = SIGCHLD;
5216 void *child_stack = NULL;
5217 void *parent_tidptr = NULL;
5218 void *newtls = NULL;
5219 void *child_tidptr = NULL;
5220
5221 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
5222 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
5223 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
5224 }
5225# else
5226# error missing fork polyfill for this architecture
5227# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00005228#endif
5229
Michael Forneyf70e2f12020-01-22 19:19:38 -08005230/* These restore the original values of these macros saved by the
5231 * corresponding #pragma push_macro near the top of this file. */
5232#pragma pop_macro("stat64")
5233#pragma pop_macro("fstat64")
5234#pragma pop_macro("lstat64")
5235#pragma pop_macro("pread64")
5236#pragma pop_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -07005237#pragma pop_macro("getdents64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00005238
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00005239#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
5240}
5241#endif
5242
5243#endif
5244#endif