blob: 5ea1295f8e9bb5312469dbc1aadb67dd620d35d3 [file] [log] [blame]
mcgrathr@google.coma7999932011-11-21 22:26:20 +00001/* Copyright (c) 2005-2011, Google Inc.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * ---
31 * Author: Markus Gutschke
32 */
33
34/* This file includes Linux-specific support functions common to the
35 * coredumper and the thread lister; primarily, this is a collection
36 * of direct system calls, and a couple of symbols missing from
37 * standard header files.
38 * There are a few options that the including file can set to control
39 * the behavior of this file:
40 *
41 * SYS_CPLUSPLUS:
42 * The entire header file will normally be wrapped in 'extern "C" { }",
43 * making it suitable for compilation as both C and C++ source. If you
44 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
45 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
46 * system header files, too. It is the caller's responsibility to provide
47 * the necessary definitions.
48 *
49 * SYS_ERRNO:
50 * All system calls will update "errno" unless overriden by setting the
51 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
52 * an l-value.
53 *
54 * SYS_INLINE:
55 * New symbols will be defined "static inline", unless overridden by
56 * the SYS_INLINE macro.
57 *
58 * SYS_LINUX_SYSCALL_SUPPORT_H
59 * This macro is used to avoid multiple inclusions of this header file.
60 * If you need to include this file more than once, make sure to
61 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
62 *
63 * SYS_PREFIX:
64 * New system calls will have a prefix of "sys_" unless overridden by
65 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
66 * results in prefixes "sys[0..9]_". It is also possible to set this
67 * macro to -1, which avoids all prefixes.
68 *
69 * SYS_SYSCALL_ENTRYPOINT:
70 * Some applications (such as sandboxes that filter system calls), need
71 * to be able to run custom-code each time a system call is made. If this
72 * macro is defined, it expands to the name of a "common" symbol. If
73 * this symbol is assigned a non-NULL pointer value, it is used as the
74 * address of the system call entrypoint.
75 * A pointer to this symbol can be obtained by calling
76 * get_syscall_entrypoint()
77 *
78 * This file defines a few internal symbols that all start with "LSS_".
79 * Do not access these symbols from outside this file. They are not part
80 * of the supported API.
81 */
82#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
83#define SYS_LINUX_SYSCALL_SUPPORT_H
84
Bryan Chan3f6478a2016-06-14 08:38:17 -040085/* We currently only support x86-32, x86-64, ARM, MIPS, PPC, s390 and s390x
86 * on Linux.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000087 * Porting to other related platforms should not be difficult.
88 */
89#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
anton@chromium.org2f724fc2014-04-15 13:05:20 +000090 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \
Andreas Schwab1d387f42022-02-15 16:21:13 +010091 defined(__aarch64__) || defined(__s390__) || defined(__e2k__) || \
92 (defined(__riscv) && __riscv_xlen == 64)) \
zodiac@gmail.com4f470182010-10-13 03:47:54 +000093 && (defined(__linux) || defined(__ANDROID__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000094
95#ifndef SYS_CPLUSPLUS
96#ifdef __cplusplus
97/* Some system header files in older versions of gcc neglect to properly
98 * handle being included from C++. As it appears to be harmless to have
99 * multiple nested 'extern "C"' blocks, just add another one here.
100 */
101extern "C" {
102#endif
103
104#include <errno.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000105#include <fcntl.h>
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000106#include <sched.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000107#include <signal.h>
108#include <stdarg.h>
109#include <stddef.h>
vapier@chromium.org2273e812013-04-01 17:52:44 +0000110#include <stdint.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000111#include <string.h>
112#include <sys/ptrace.h>
113#include <sys/resource.h>
114#include <sys/time.h>
115#include <sys/types.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000116#include <sys/syscall.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000117#include <unistd.h>
118#include <linux/unistd.h>
119#include <endian.h>
120
121#ifdef __mips__
122/* Include definitions of the ABI currently in use. */
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000123#ifdef __ANDROID__
124/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h,
125 * which has the definitions we need.
126 */
127#include <asm/sgidefs.h>
128#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000129#include <sgidefs.h>
130#endif
131#endif
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000132#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000133
Michael Forneyf70e2f12020-01-22 19:19:38 -0800134/* Some libcs, for example Android NDK and musl, #define these
135 * macros as aliases to their non-64 counterparts. To avoid naming
136 * conflict, remove them.
137 *
138 * These are restored by the corresponding #pragma pop_macro near
139 * the end of this file.
140 */
141#pragma push_macro("stat64")
142#pragma push_macro("fstat64")
143#pragma push_macro("lstat64")
144#pragma push_macro("pread64")
145#pragma push_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700146#pragma push_macro("getdents64")
Michael Forneyf70e2f12020-01-22 19:19:38 -0800147#undef stat64
148#undef fstat64
149#undef lstat64
150#undef pread64
151#undef pwrite64
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700152#undef getdents64
mseaborn@chromium.orgca749372012-09-05 18:26:20 +0000153
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400154#if defined(__ANDROID__) && defined(__x86_64__)
155// A number of x86_64 syscalls are blocked by seccomp on recent Android;
156// undefine them so that modern alternatives will be used instead where
157// possible.
158// The alternative syscalls have been sanity checked against linux-3.4+;
159// older versions might not work.
160# undef __NR_getdents
161# undef __NR_dup2
162# undef __NR_fork
163# undef __NR_getpgrp
164# undef __NR_open
165# undef __NR_poll
166# undef __NR_readlink
167# undef __NR_stat
168# undef __NR_unlink
169# undef __NR_pipe
170#endif
171
172#if defined(__ANDROID__)
173// waitpid is blocked by seccomp on all architectures on recent Android.
174# undef __NR_waitpid
175#endif
176
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000177/* As glibc often provides subtly incompatible data structures (and implicit
178 * wrapper functions that convert them), we provide our own kernel data
179 * structures for use by the system calls.
180 * These structures have been developed by using Linux 2.6.23 headers for
181 * reference. Note though, we do not care about exact API compatibility
182 * with the kernel, and in fact the kernel often does not have a single
183 * API that works across architectures. Instead, we try to mimic the glibc
184 * API where reasonable, and only guarantee ABI compatibility with the
185 * kernel headers.
186 * Most notably, here are a few changes that were made to the structures
187 * defined by kernel headers:
188 *
189 * - we only define structures, but not symbolic names for kernel data
190 * types. For the latter, we directly use the native C datatype
191 * (i.e. "unsigned" instead of "mode_t").
192 * - in a few cases, it is possible to define identical structures for
193 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
194 * standardizing on the 64bit version of the data types. In particular,
195 * this means that we use "unsigned" where the 32bit headers say
196 * "unsigned long".
197 * - overall, we try to minimize the number of cases where we need to
198 * conditionally define different structures.
199 * - the "struct kernel_sigaction" class of structures have been
200 * modified to more closely mimic glibc's API by introducing an
201 * anonymous union for the function pointer.
202 * - a small number of field names had to have an underscore appended to
203 * them, because glibc defines a global macro by the same name.
204 */
205
206/* include/linux/dirent.h */
207struct kernel_dirent64 {
208 unsigned long long d_ino;
209 long long d_off;
210 unsigned short d_reclen;
211 unsigned char d_type;
212 char d_name[256];
213};
214
215/* include/linux/dirent.h */
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400216#if !defined(__NR_getdents)
217// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000218#define kernel_dirent kernel_dirent64
219#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000220struct kernel_dirent {
221 long d_ino;
222 long d_off;
223 unsigned short d_reclen;
224 char d_name[256];
225};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000226#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000227
228/* include/linux/uio.h */
229struct kernel_iovec {
230 void *iov_base;
231 unsigned long iov_len;
232};
233
234/* include/linux/socket.h */
235struct kernel_msghdr {
236 void *msg_name;
237 int msg_namelen;
238 struct kernel_iovec*msg_iov;
239 unsigned long msg_iovlen;
240 void *msg_control;
241 unsigned long msg_controllen;
242 unsigned msg_flags;
243};
244
245/* include/asm-generic/poll.h */
246struct kernel_pollfd {
247 int fd;
248 short events;
249 short revents;
250};
251
252/* include/linux/resource.h */
253struct kernel_rlimit {
254 unsigned long rlim_cur;
255 unsigned long rlim_max;
256};
257
258/* include/linux/time.h */
259struct kernel_timespec {
260 long tv_sec;
261 long tv_nsec;
262};
263
264/* include/linux/time.h */
265struct kernel_timeval {
266 long tv_sec;
267 long tv_usec;
268};
269
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
Andreas Schwab1d387f42022-02-15 16:21:13 +0100312#elif defined(__aarch64__) || defined(__riscv)
313 // No kernel_old_sigaction defined for arm64 or riscv.
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;
Andreas Schwab1d387f42022-02-15 16:21:13 +0100352#ifndef __riscv
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};
Andreas Schwab1d387f42022-02-15 16:21:13 +0100554#elif defined(__aarch64__) || defined(__riscv)
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
755
756/* Definitions missing from the standard header files */
757#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000758#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000759#define O_DIRECTORY 0040000
760#else
761#define O_DIRECTORY 0200000
762#endif
763#endif
764#ifndef NT_PRXFPREG
765#define NT_PRXFPREG 0x46e62b7f
766#endif
767#ifndef PTRACE_GETFPXREGS
768#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
769#endif
770#ifndef PR_GET_DUMPABLE
771#define PR_GET_DUMPABLE 3
772#endif
773#ifndef PR_SET_DUMPABLE
774#define PR_SET_DUMPABLE 4
775#endif
776#ifndef PR_GET_SECCOMP
777#define PR_GET_SECCOMP 21
778#endif
779#ifndef PR_SET_SECCOMP
780#define PR_SET_SECCOMP 22
781#endif
782#ifndef AT_FDCWD
783#define AT_FDCWD (-100)
784#endif
785#ifndef AT_SYMLINK_NOFOLLOW
786#define AT_SYMLINK_NOFOLLOW 0x100
787#endif
788#ifndef AT_REMOVEDIR
789#define AT_REMOVEDIR 0x200
790#endif
791#ifndef MREMAP_FIXED
792#define MREMAP_FIXED 2
793#endif
794#ifndef SA_RESTORER
795#define SA_RESTORER 0x04000000
796#endif
797#ifndef CPUCLOCK_PROF
798#define CPUCLOCK_PROF 0
799#endif
800#ifndef CPUCLOCK_VIRT
801#define CPUCLOCK_VIRT 1
802#endif
803#ifndef CPUCLOCK_SCHED
804#define CPUCLOCK_SCHED 2
805#endif
806#ifndef CPUCLOCK_PERTHREAD_MASK
807#define CPUCLOCK_PERTHREAD_MASK 4
808#endif
809#ifndef MAKE_PROCESS_CPUCLOCK
810#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400811 ((int)(~(unsigned)(pid) << 3) | (int)(clock))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000812#endif
813#ifndef MAKE_THREAD_CPUCLOCK
814#define MAKE_THREAD_CPUCLOCK(tid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400815 ((int)(~(unsigned)(tid) << 3) | \
816 (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000817#endif
818
819#ifndef FUTEX_WAIT
820#define FUTEX_WAIT 0
821#endif
822#ifndef FUTEX_WAKE
823#define FUTEX_WAKE 1
824#endif
825#ifndef FUTEX_FD
826#define FUTEX_FD 2
827#endif
828#ifndef FUTEX_REQUEUE
829#define FUTEX_REQUEUE 3
830#endif
831#ifndef FUTEX_CMP_REQUEUE
832#define FUTEX_CMP_REQUEUE 4
833#endif
834#ifndef FUTEX_WAKE_OP
835#define FUTEX_WAKE_OP 5
836#endif
837#ifndef FUTEX_LOCK_PI
838#define FUTEX_LOCK_PI 6
839#endif
840#ifndef FUTEX_UNLOCK_PI
841#define FUTEX_UNLOCK_PI 7
842#endif
843#ifndef FUTEX_TRYLOCK_PI
844#define FUTEX_TRYLOCK_PI 8
845#endif
846#ifndef FUTEX_PRIVATE_FLAG
847#define FUTEX_PRIVATE_FLAG 128
848#endif
849#ifndef FUTEX_CMD_MASK
850#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
851#endif
852#ifndef FUTEX_WAIT_PRIVATE
853#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
854#endif
855#ifndef FUTEX_WAKE_PRIVATE
856#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
857#endif
858#ifndef FUTEX_REQUEUE_PRIVATE
859#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
860#endif
861#ifndef FUTEX_CMP_REQUEUE_PRIVATE
862#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
863#endif
864#ifndef FUTEX_WAKE_OP_PRIVATE
865#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
866#endif
867#ifndef FUTEX_LOCK_PI_PRIVATE
868#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
869#endif
870#ifndef FUTEX_UNLOCK_PI_PRIVATE
871#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
872#endif
873#ifndef FUTEX_TRYLOCK_PI_PRIVATE
874#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
875#endif
876
877
878#if defined(__x86_64__)
879#ifndef ARCH_SET_GS
880#define ARCH_SET_GS 0x1001
881#endif
882#ifndef ARCH_GET_GS
883#define ARCH_GET_GS 0x1004
884#endif
885#endif
886
887#if defined(__i386__)
888#ifndef __NR_quotactl
889#define __NR_quotactl 131
890#endif
891#ifndef __NR_setresuid
892#define __NR_setresuid 164
893#define __NR_getresuid 165
894#define __NR_setresgid 170
895#define __NR_getresgid 171
896#endif
897#ifndef __NR_rt_sigaction
898#define __NR_rt_sigreturn 173
899#define __NR_rt_sigaction 174
900#define __NR_rt_sigprocmask 175
901#define __NR_rt_sigpending 176
902#define __NR_rt_sigsuspend 179
903#endif
904#ifndef __NR_pread64
905#define __NR_pread64 180
906#endif
907#ifndef __NR_pwrite64
908#define __NR_pwrite64 181
909#endif
910#ifndef __NR_ugetrlimit
911#define __NR_ugetrlimit 191
912#endif
913#ifndef __NR_stat64
914#define __NR_stat64 195
915#endif
916#ifndef __NR_fstat64
917#define __NR_fstat64 197
918#endif
919#ifndef __NR_setresuid32
920#define __NR_setresuid32 208
921#define __NR_getresuid32 209
922#define __NR_setresgid32 210
923#define __NR_getresgid32 211
924#endif
925#ifndef __NR_setfsuid32
926#define __NR_setfsuid32 215
927#define __NR_setfsgid32 216
928#endif
929#ifndef __NR_getdents64
930#define __NR_getdents64 220
931#endif
932#ifndef __NR_gettid
933#define __NR_gettid 224
934#endif
935#ifndef __NR_readahead
936#define __NR_readahead 225
937#endif
938#ifndef __NR_setxattr
939#define __NR_setxattr 226
940#endif
941#ifndef __NR_lsetxattr
942#define __NR_lsetxattr 227
943#endif
944#ifndef __NR_getxattr
945#define __NR_getxattr 229
946#endif
947#ifndef __NR_lgetxattr
948#define __NR_lgetxattr 230
949#endif
950#ifndef __NR_listxattr
951#define __NR_listxattr 232
952#endif
953#ifndef __NR_llistxattr
954#define __NR_llistxattr 233
955#endif
956#ifndef __NR_tkill
957#define __NR_tkill 238
958#endif
959#ifndef __NR_futex
960#define __NR_futex 240
961#endif
962#ifndef __NR_sched_setaffinity
963#define __NR_sched_setaffinity 241
964#define __NR_sched_getaffinity 242
965#endif
966#ifndef __NR_set_tid_address
967#define __NR_set_tid_address 258
968#endif
969#ifndef __NR_clock_gettime
970#define __NR_clock_gettime 265
971#endif
972#ifndef __NR_clock_getres
973#define __NR_clock_getres 266
974#endif
975#ifndef __NR_statfs64
976#define __NR_statfs64 268
977#endif
978#ifndef __NR_fstatfs64
979#define __NR_fstatfs64 269
980#endif
981#ifndef __NR_fadvise64_64
982#define __NR_fadvise64_64 272
983#endif
984#ifndef __NR_ioprio_set
985#define __NR_ioprio_set 289
986#endif
987#ifndef __NR_ioprio_get
988#define __NR_ioprio_get 290
989#endif
990#ifndef __NR_openat
991#define __NR_openat 295
992#endif
993#ifndef __NR_fstatat64
994#define __NR_fstatat64 300
995#endif
996#ifndef __NR_unlinkat
997#define __NR_unlinkat 301
998#endif
999#ifndef __NR_move_pages
1000#define __NR_move_pages 317
1001#endif
1002#ifndef __NR_getcpu
1003#define __NR_getcpu 318
1004#endif
1005#ifndef __NR_fallocate
1006#define __NR_fallocate 324
1007#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001008#ifndef __NR_getrandom
1009#define __NR_getrandom 355
1010#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001011/* End of i386 definitions */
1012#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
1013#ifndef __NR_setresuid
1014#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
1015#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
1016#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
1017#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
1018#endif
1019#ifndef __NR_rt_sigaction
1020#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
1021#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
1022#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
1023#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
1024#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
1025#endif
1026#ifndef __NR_pread64
1027#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
1028#endif
1029#ifndef __NR_pwrite64
1030#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
1031#endif
1032#ifndef __NR_ugetrlimit
1033#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
1034#endif
1035#ifndef __NR_stat64
1036#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
1037#endif
1038#ifndef __NR_fstat64
1039#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
1040#endif
1041#ifndef __NR_setresuid32
1042#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
1043#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
1044#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
1045#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
1046#endif
1047#ifndef __NR_setfsuid32
1048#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
1049#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
1050#endif
1051#ifndef __NR_getdents64
1052#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
1053#endif
1054#ifndef __NR_gettid
1055#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1056#endif
1057#ifndef __NR_readahead
1058#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1059#endif
1060#ifndef __NR_setxattr
1061#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1062#endif
1063#ifndef __NR_lsetxattr
1064#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1065#endif
1066#ifndef __NR_getxattr
1067#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1068#endif
1069#ifndef __NR_lgetxattr
1070#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1071#endif
1072#ifndef __NR_listxattr
1073#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1074#endif
1075#ifndef __NR_llistxattr
1076#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1077#endif
1078#ifndef __NR_tkill
1079#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1080#endif
1081#ifndef __NR_futex
1082#define __NR_futex (__NR_SYSCALL_BASE + 240)
1083#endif
1084#ifndef __NR_sched_setaffinity
1085#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1086#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1087#endif
1088#ifndef __NR_set_tid_address
1089#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1090#endif
1091#ifndef __NR_clock_gettime
1092#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1093#endif
1094#ifndef __NR_clock_getres
1095#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1096#endif
1097#ifndef __NR_statfs64
1098#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1099#endif
1100#ifndef __NR_fstatfs64
1101#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1102#endif
1103#ifndef __NR_ioprio_set
1104#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1105#endif
1106#ifndef __NR_ioprio_get
1107#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1108#endif
Matthew Denton92a65a82021-04-01 13:00:07 -07001109#ifndef __NR_fstatat64
1110#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
1111#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001112#ifndef __NR_move_pages
1113#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1114#endif
1115#ifndef __NR_getcpu
1116#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1117#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001118#ifndef __NR_getrandom
1119#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
1120#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001121/* End of ARM 3/EABI definitions */
Andreas Schwab1d387f42022-02-15 16:21:13 +01001122#elif defined(__aarch64__) || defined(__riscv)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001123#ifndef __NR_setxattr
1124#define __NR_setxattr 5
1125#endif
1126#ifndef __NR_lsetxattr
1127#define __NR_lsetxattr 6
1128#endif
1129#ifndef __NR_getxattr
1130#define __NR_getxattr 8
1131#endif
1132#ifndef __NR_lgetxattr
1133#define __NR_lgetxattr 9
1134#endif
1135#ifndef __NR_listxattr
1136#define __NR_listxattr 11
1137#endif
1138#ifndef __NR_llistxattr
1139#define __NR_llistxattr 12
1140#endif
1141#ifndef __NR_ioprio_set
1142#define __NR_ioprio_set 30
1143#endif
1144#ifndef __NR_ioprio_get
1145#define __NR_ioprio_get 31
1146#endif
1147#ifndef __NR_unlinkat
1148#define __NR_unlinkat 35
1149#endif
1150#ifndef __NR_fallocate
1151#define __NR_fallocate 47
1152#endif
1153#ifndef __NR_openat
1154#define __NR_openat 56
1155#endif
1156#ifndef __NR_quotactl
1157#define __NR_quotactl 60
1158#endif
1159#ifndef __NR_getdents64
1160#define __NR_getdents64 61
1161#endif
1162#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001163// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001164#define __NR_getdents __NR_getdents64
1165#endif
1166#ifndef __NR_pread64
1167#define __NR_pread64 67
1168#endif
1169#ifndef __NR_pwrite64
1170#define __NR_pwrite64 68
1171#endif
1172#ifndef __NR_ppoll
1173#define __NR_ppoll 73
1174#endif
1175#ifndef __NR_readlinkat
1176#define __NR_readlinkat 78
1177#endif
1178#ifndef __NR_newfstatat
1179#define __NR_newfstatat 79
1180#endif
1181#ifndef __NR_set_tid_address
1182#define __NR_set_tid_address 96
1183#endif
1184#ifndef __NR_futex
1185#define __NR_futex 98
1186#endif
1187#ifndef __NR_clock_gettime
1188#define __NR_clock_gettime 113
1189#endif
1190#ifndef __NR_clock_getres
1191#define __NR_clock_getres 114
1192#endif
1193#ifndef __NR_sched_setaffinity
1194#define __NR_sched_setaffinity 122
1195#define __NR_sched_getaffinity 123
1196#endif
1197#ifndef __NR_tkill
1198#define __NR_tkill 130
1199#endif
1200#ifndef __NR_setresuid
1201#define __NR_setresuid 147
1202#define __NR_getresuid 148
1203#define __NR_setresgid 149
1204#define __NR_getresgid 150
1205#endif
1206#ifndef __NR_gettid
1207#define __NR_gettid 178
1208#endif
1209#ifndef __NR_readahead
1210#define __NR_readahead 213
1211#endif
1212#ifndef __NR_fadvise64
1213#define __NR_fadvise64 223
1214#endif
1215#ifndef __NR_move_pages
1216#define __NR_move_pages 239
1217#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001218#ifndef __NR_getrandom
1219#define __NR_getrandom 278
1220#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001221/* End of aarch64 definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001222#elif defined(__x86_64__)
1223#ifndef __NR_pread64
1224#define __NR_pread64 17
1225#endif
1226#ifndef __NR_pwrite64
1227#define __NR_pwrite64 18
1228#endif
1229#ifndef __NR_setresuid
1230#define __NR_setresuid 117
1231#define __NR_getresuid 118
1232#define __NR_setresgid 119
1233#define __NR_getresgid 120
1234#endif
1235#ifndef __NR_quotactl
1236#define __NR_quotactl 179
1237#endif
1238#ifndef __NR_gettid
1239#define __NR_gettid 186
1240#endif
1241#ifndef __NR_readahead
1242#define __NR_readahead 187
1243#endif
1244#ifndef __NR_setxattr
1245#define __NR_setxattr 188
1246#endif
1247#ifndef __NR_lsetxattr
1248#define __NR_lsetxattr 189
1249#endif
1250#ifndef __NR_getxattr
1251#define __NR_getxattr 191
1252#endif
1253#ifndef __NR_lgetxattr
1254#define __NR_lgetxattr 192
1255#endif
1256#ifndef __NR_listxattr
1257#define __NR_listxattr 194
1258#endif
1259#ifndef __NR_llistxattr
1260#define __NR_llistxattr 195
1261#endif
1262#ifndef __NR_tkill
1263#define __NR_tkill 200
1264#endif
1265#ifndef __NR_futex
1266#define __NR_futex 202
1267#endif
1268#ifndef __NR_sched_setaffinity
1269#define __NR_sched_setaffinity 203
1270#define __NR_sched_getaffinity 204
1271#endif
1272#ifndef __NR_getdents64
1273#define __NR_getdents64 217
1274#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001275#ifndef __NR_getdents
1276// when getdents is not available, getdents64 is used for both.
1277#define __NR_getdents __NR_getdents64
1278#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001279#ifndef __NR_set_tid_address
1280#define __NR_set_tid_address 218
1281#endif
1282#ifndef __NR_fadvise64
1283#define __NR_fadvise64 221
1284#endif
1285#ifndef __NR_clock_gettime
1286#define __NR_clock_gettime 228
1287#endif
1288#ifndef __NR_clock_getres
1289#define __NR_clock_getres 229
1290#endif
1291#ifndef __NR_ioprio_set
1292#define __NR_ioprio_set 251
1293#endif
1294#ifndef __NR_ioprio_get
1295#define __NR_ioprio_get 252
1296#endif
1297#ifndef __NR_openat
1298#define __NR_openat 257
1299#endif
1300#ifndef __NR_newfstatat
1301#define __NR_newfstatat 262
1302#endif
1303#ifndef __NR_unlinkat
1304#define __NR_unlinkat 263
1305#endif
1306#ifndef __NR_move_pages
1307#define __NR_move_pages 279
1308#endif
1309#ifndef __NR_fallocate
1310#define __NR_fallocate 285
1311#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001312#ifndef __NR_getrandom
1313#define __NR_getrandom 318
1314#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001315/* End of x86-64 definitions */
1316#elif defined(__mips__)
1317#if _MIPS_SIM == _MIPS_SIM_ABI32
1318#ifndef __NR_setresuid
1319#define __NR_setresuid (__NR_Linux + 185)
1320#define __NR_getresuid (__NR_Linux + 186)
1321#define __NR_setresgid (__NR_Linux + 190)
1322#define __NR_getresgid (__NR_Linux + 191)
1323#endif
1324#ifndef __NR_rt_sigaction
1325#define __NR_rt_sigreturn (__NR_Linux + 193)
1326#define __NR_rt_sigaction (__NR_Linux + 194)
1327#define __NR_rt_sigprocmask (__NR_Linux + 195)
1328#define __NR_rt_sigpending (__NR_Linux + 196)
1329#define __NR_rt_sigsuspend (__NR_Linux + 199)
1330#endif
1331#ifndef __NR_pread64
1332#define __NR_pread64 (__NR_Linux + 200)
1333#endif
1334#ifndef __NR_pwrite64
1335#define __NR_pwrite64 (__NR_Linux + 201)
1336#endif
1337#ifndef __NR_stat64
1338#define __NR_stat64 (__NR_Linux + 213)
1339#endif
1340#ifndef __NR_fstat64
1341#define __NR_fstat64 (__NR_Linux + 215)
1342#endif
1343#ifndef __NR_getdents64
1344#define __NR_getdents64 (__NR_Linux + 219)
1345#endif
1346#ifndef __NR_gettid
1347#define __NR_gettid (__NR_Linux + 222)
1348#endif
1349#ifndef __NR_readahead
1350#define __NR_readahead (__NR_Linux + 223)
1351#endif
1352#ifndef __NR_setxattr
1353#define __NR_setxattr (__NR_Linux + 224)
1354#endif
1355#ifndef __NR_lsetxattr
1356#define __NR_lsetxattr (__NR_Linux + 225)
1357#endif
1358#ifndef __NR_getxattr
1359#define __NR_getxattr (__NR_Linux + 227)
1360#endif
1361#ifndef __NR_lgetxattr
1362#define __NR_lgetxattr (__NR_Linux + 228)
1363#endif
1364#ifndef __NR_listxattr
1365#define __NR_listxattr (__NR_Linux + 230)
1366#endif
1367#ifndef __NR_llistxattr
1368#define __NR_llistxattr (__NR_Linux + 231)
1369#endif
1370#ifndef __NR_tkill
1371#define __NR_tkill (__NR_Linux + 236)
1372#endif
1373#ifndef __NR_futex
1374#define __NR_futex (__NR_Linux + 238)
1375#endif
1376#ifndef __NR_sched_setaffinity
1377#define __NR_sched_setaffinity (__NR_Linux + 239)
1378#define __NR_sched_getaffinity (__NR_Linux + 240)
1379#endif
1380#ifndef __NR_set_tid_address
1381#define __NR_set_tid_address (__NR_Linux + 252)
1382#endif
1383#ifndef __NR_statfs64
1384#define __NR_statfs64 (__NR_Linux + 255)
1385#endif
1386#ifndef __NR_fstatfs64
1387#define __NR_fstatfs64 (__NR_Linux + 256)
1388#endif
1389#ifndef __NR_clock_gettime
1390#define __NR_clock_gettime (__NR_Linux + 263)
1391#endif
1392#ifndef __NR_clock_getres
1393#define __NR_clock_getres (__NR_Linux + 264)
1394#endif
1395#ifndef __NR_openat
1396#define __NR_openat (__NR_Linux + 288)
1397#endif
1398#ifndef __NR_fstatat
1399#define __NR_fstatat (__NR_Linux + 293)
1400#endif
1401#ifndef __NR_unlinkat
1402#define __NR_unlinkat (__NR_Linux + 294)
1403#endif
1404#ifndef __NR_move_pages
1405#define __NR_move_pages (__NR_Linux + 308)
1406#endif
1407#ifndef __NR_getcpu
1408#define __NR_getcpu (__NR_Linux + 312)
1409#endif
1410#ifndef __NR_ioprio_set
1411#define __NR_ioprio_set (__NR_Linux + 314)
1412#endif
1413#ifndef __NR_ioprio_get
1414#define __NR_ioprio_get (__NR_Linux + 315)
1415#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001416#ifndef __NR_getrandom
1417#define __NR_getrandom (__NR_Linux + 353)
1418#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001419/* End of MIPS (old 32bit API) definitions */
1420#elif _MIPS_SIM == _MIPS_SIM_ABI64
1421#ifndef __NR_pread64
1422#define __NR_pread64 (__NR_Linux + 16)
1423#endif
1424#ifndef __NR_pwrite64
1425#define __NR_pwrite64 (__NR_Linux + 17)
1426#endif
1427#ifndef __NR_setresuid
1428#define __NR_setresuid (__NR_Linux + 115)
1429#define __NR_getresuid (__NR_Linux + 116)
1430#define __NR_setresgid (__NR_Linux + 117)
1431#define __NR_getresgid (__NR_Linux + 118)
1432#endif
1433#ifndef __NR_gettid
1434#define __NR_gettid (__NR_Linux + 178)
1435#endif
1436#ifndef __NR_readahead
1437#define __NR_readahead (__NR_Linux + 179)
1438#endif
1439#ifndef __NR_setxattr
1440#define __NR_setxattr (__NR_Linux + 180)
1441#endif
1442#ifndef __NR_lsetxattr
1443#define __NR_lsetxattr (__NR_Linux + 181)
1444#endif
1445#ifndef __NR_getxattr
1446#define __NR_getxattr (__NR_Linux + 183)
1447#endif
1448#ifndef __NR_lgetxattr
1449#define __NR_lgetxattr (__NR_Linux + 184)
1450#endif
1451#ifndef __NR_listxattr
1452#define __NR_listxattr (__NR_Linux + 186)
1453#endif
1454#ifndef __NR_llistxattr
1455#define __NR_llistxattr (__NR_Linux + 187)
1456#endif
1457#ifndef __NR_tkill
1458#define __NR_tkill (__NR_Linux + 192)
1459#endif
1460#ifndef __NR_futex
1461#define __NR_futex (__NR_Linux + 194)
1462#endif
1463#ifndef __NR_sched_setaffinity
1464#define __NR_sched_setaffinity (__NR_Linux + 195)
1465#define __NR_sched_getaffinity (__NR_Linux + 196)
1466#endif
1467#ifndef __NR_set_tid_address
1468#define __NR_set_tid_address (__NR_Linux + 212)
1469#endif
1470#ifndef __NR_clock_gettime
1471#define __NR_clock_gettime (__NR_Linux + 222)
1472#endif
1473#ifndef __NR_clock_getres
1474#define __NR_clock_getres (__NR_Linux + 223)
1475#endif
1476#ifndef __NR_openat
1477#define __NR_openat (__NR_Linux + 247)
1478#endif
1479#ifndef __NR_fstatat
1480#define __NR_fstatat (__NR_Linux + 252)
1481#endif
1482#ifndef __NR_unlinkat
1483#define __NR_unlinkat (__NR_Linux + 253)
1484#endif
1485#ifndef __NR_move_pages
1486#define __NR_move_pages (__NR_Linux + 267)
1487#endif
1488#ifndef __NR_getcpu
1489#define __NR_getcpu (__NR_Linux + 271)
1490#endif
1491#ifndef __NR_ioprio_set
1492#define __NR_ioprio_set (__NR_Linux + 273)
1493#endif
1494#ifndef __NR_ioprio_get
1495#define __NR_ioprio_get (__NR_Linux + 274)
1496#endif
Yu Yind9ad2962020-11-24 16:49:22 +08001497#ifndef __NR_getrandom
1498#define __NR_getrandom (__NR_Linux + 313)
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001499#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001500/* End of MIPS (64bit API) definitions */
1501#else
1502#ifndef __NR_setresuid
1503#define __NR_setresuid (__NR_Linux + 115)
1504#define __NR_getresuid (__NR_Linux + 116)
1505#define __NR_setresgid (__NR_Linux + 117)
1506#define __NR_getresgid (__NR_Linux + 118)
1507#endif
1508#ifndef __NR_gettid
1509#define __NR_gettid (__NR_Linux + 178)
1510#endif
1511#ifndef __NR_readahead
1512#define __NR_readahead (__NR_Linux + 179)
1513#endif
1514#ifndef __NR_setxattr
1515#define __NR_setxattr (__NR_Linux + 180)
1516#endif
1517#ifndef __NR_lsetxattr
1518#define __NR_lsetxattr (__NR_Linux + 181)
1519#endif
1520#ifndef __NR_getxattr
1521#define __NR_getxattr (__NR_Linux + 183)
1522#endif
1523#ifndef __NR_lgetxattr
1524#define __NR_lgetxattr (__NR_Linux + 184)
1525#endif
1526#ifndef __NR_listxattr
1527#define __NR_listxattr (__NR_Linux + 186)
1528#endif
1529#ifndef __NR_llistxattr
1530#define __NR_llistxattr (__NR_Linux + 187)
1531#endif
1532#ifndef __NR_tkill
1533#define __NR_tkill (__NR_Linux + 192)
1534#endif
1535#ifndef __NR_futex
1536#define __NR_futex (__NR_Linux + 194)
1537#endif
1538#ifndef __NR_sched_setaffinity
1539#define __NR_sched_setaffinity (__NR_Linux + 195)
1540#define __NR_sched_getaffinity (__NR_Linux + 196)
1541#endif
1542#ifndef __NR_set_tid_address
1543#define __NR_set_tid_address (__NR_Linux + 213)
1544#endif
1545#ifndef __NR_statfs64
1546#define __NR_statfs64 (__NR_Linux + 217)
1547#endif
1548#ifndef __NR_fstatfs64
1549#define __NR_fstatfs64 (__NR_Linux + 218)
1550#endif
1551#ifndef __NR_clock_gettime
1552#define __NR_clock_gettime (__NR_Linux + 226)
1553#endif
1554#ifndef __NR_clock_getres
1555#define __NR_clock_getres (__NR_Linux + 227)
1556#endif
1557#ifndef __NR_openat
1558#define __NR_openat (__NR_Linux + 251)
1559#endif
1560#ifndef __NR_fstatat
1561#define __NR_fstatat (__NR_Linux + 256)
1562#endif
1563#ifndef __NR_unlinkat
1564#define __NR_unlinkat (__NR_Linux + 257)
1565#endif
1566#ifndef __NR_move_pages
1567#define __NR_move_pages (__NR_Linux + 271)
1568#endif
1569#ifndef __NR_getcpu
1570#define __NR_getcpu (__NR_Linux + 275)
1571#endif
1572#ifndef __NR_ioprio_set
1573#define __NR_ioprio_set (__NR_Linux + 277)
1574#endif
1575#ifndef __NR_ioprio_get
1576#define __NR_ioprio_get (__NR_Linux + 278)
1577#endif
1578/* End of MIPS (new 32bit API) definitions */
1579#endif
1580/* End of MIPS definitions */
1581#elif defined(__PPC__)
1582#ifndef __NR_setfsuid
1583#define __NR_setfsuid 138
1584#define __NR_setfsgid 139
1585#endif
1586#ifndef __NR_setresuid
1587#define __NR_setresuid 164
1588#define __NR_getresuid 165
1589#define __NR_setresgid 169
1590#define __NR_getresgid 170
1591#endif
1592#ifndef __NR_rt_sigaction
1593#define __NR_rt_sigreturn 172
1594#define __NR_rt_sigaction 173
1595#define __NR_rt_sigprocmask 174
1596#define __NR_rt_sigpending 175
1597#define __NR_rt_sigsuspend 178
1598#endif
1599#ifndef __NR_pread64
1600#define __NR_pread64 179
1601#endif
1602#ifndef __NR_pwrite64
1603#define __NR_pwrite64 180
1604#endif
1605#ifndef __NR_ugetrlimit
1606#define __NR_ugetrlimit 190
1607#endif
1608#ifndef __NR_readahead
1609#define __NR_readahead 191
1610#endif
1611#ifndef __NR_stat64
1612#define __NR_stat64 195
1613#endif
1614#ifndef __NR_fstat64
1615#define __NR_fstat64 197
1616#endif
1617#ifndef __NR_getdents64
1618#define __NR_getdents64 202
1619#endif
1620#ifndef __NR_gettid
1621#define __NR_gettid 207
1622#endif
1623#ifndef __NR_tkill
1624#define __NR_tkill 208
1625#endif
1626#ifndef __NR_setxattr
1627#define __NR_setxattr 209
1628#endif
1629#ifndef __NR_lsetxattr
1630#define __NR_lsetxattr 210
1631#endif
1632#ifndef __NR_getxattr
1633#define __NR_getxattr 212
1634#endif
1635#ifndef __NR_lgetxattr
1636#define __NR_lgetxattr 213
1637#endif
1638#ifndef __NR_listxattr
1639#define __NR_listxattr 215
1640#endif
1641#ifndef __NR_llistxattr
1642#define __NR_llistxattr 216
1643#endif
1644#ifndef __NR_futex
1645#define __NR_futex 221
1646#endif
1647#ifndef __NR_sched_setaffinity
1648#define __NR_sched_setaffinity 222
1649#define __NR_sched_getaffinity 223
1650#endif
1651#ifndef __NR_set_tid_address
1652#define __NR_set_tid_address 232
1653#endif
1654#ifndef __NR_clock_gettime
1655#define __NR_clock_gettime 246
1656#endif
1657#ifndef __NR_clock_getres
1658#define __NR_clock_getres 247
1659#endif
1660#ifndef __NR_statfs64
1661#define __NR_statfs64 252
1662#endif
1663#ifndef __NR_fstatfs64
1664#define __NR_fstatfs64 253
1665#endif
1666#ifndef __NR_fadvise64_64
1667#define __NR_fadvise64_64 254
1668#endif
1669#ifndef __NR_ioprio_set
1670#define __NR_ioprio_set 273
1671#endif
1672#ifndef __NR_ioprio_get
1673#define __NR_ioprio_get 274
1674#endif
1675#ifndef __NR_openat
1676#define __NR_openat 286
1677#endif
1678#ifndef __NR_fstatat64
1679#define __NR_fstatat64 291
1680#endif
1681#ifndef __NR_unlinkat
1682#define __NR_unlinkat 292
1683#endif
1684#ifndef __NR_move_pages
1685#define __NR_move_pages 301
1686#endif
1687#ifndef __NR_getcpu
1688#define __NR_getcpu 302
1689#endif
1690/* End of powerpc defininitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001691#elif defined(__s390__)
1692#ifndef __NR_quotactl
1693#define __NR_quotactl 131
1694#endif
1695#ifndef __NR_rt_sigreturn
1696#define __NR_rt_sigreturn 173
1697#endif
1698#ifndef __NR_rt_sigaction
1699#define __NR_rt_sigaction 174
1700#endif
1701#ifndef __NR_rt_sigprocmask
1702#define __NR_rt_sigprocmask 175
1703#endif
1704#ifndef __NR_rt_sigpending
1705#define __NR_rt_sigpending 176
1706#endif
1707#ifndef __NR_rt_sigsuspend
1708#define __NR_rt_sigsuspend 179
1709#endif
1710#ifndef __NR_pread64
1711#define __NR_pread64 180
1712#endif
1713#ifndef __NR_pwrite64
1714#define __NR_pwrite64 181
1715#endif
1716#ifndef __NR_getdents64
1717#define __NR_getdents64 220
1718#endif
1719#ifndef __NR_readahead
1720#define __NR_readahead 222
1721#endif
1722#ifndef __NR_setxattr
1723#define __NR_setxattr 224
1724#endif
1725#ifndef __NR_lsetxattr
1726#define __NR_lsetxattr 225
1727#endif
1728#ifndef __NR_getxattr
1729#define __NR_getxattr 227
1730#endif
1731#ifndef __NR_lgetxattr
1732#define __NR_lgetxattr 228
1733#endif
1734#ifndef __NR_listxattr
1735#define __NR_listxattr 230
1736#endif
1737#ifndef __NR_llistxattr
1738#define __NR_llistxattr 231
1739#endif
1740#ifndef __NR_gettid
1741#define __NR_gettid 236
1742#endif
1743#ifndef __NR_tkill
1744#define __NR_tkill 237
1745#endif
1746#ifndef __NR_futex
1747#define __NR_futex 238
1748#endif
1749#ifndef __NR_sched_setaffinity
1750#define __NR_sched_setaffinity 239
1751#endif
1752#ifndef __NR_sched_getaffinity
1753#define __NR_sched_getaffinity 240
1754#endif
1755#ifndef __NR_set_tid_address
1756#define __NR_set_tid_address 252
1757#endif
1758#ifndef __NR_clock_gettime
1759#define __NR_clock_gettime 260
1760#endif
1761#ifndef __NR_clock_getres
1762#define __NR_clock_getres 261
1763#endif
1764#ifndef __NR_statfs64
1765#define __NR_statfs64 265
1766#endif
1767#ifndef __NR_fstatfs64
1768#define __NR_fstatfs64 266
1769#endif
1770#ifndef __NR_ioprio_set
1771#define __NR_ioprio_set 282
1772#endif
1773#ifndef __NR_ioprio_get
1774#define __NR_ioprio_get 283
1775#endif
1776#ifndef __NR_openat
1777#define __NR_openat 288
1778#endif
1779#ifndef __NR_unlinkat
1780#define __NR_unlinkat 294
1781#endif
1782#ifndef __NR_move_pages
1783#define __NR_move_pages 310
1784#endif
1785#ifndef __NR_getcpu
1786#define __NR_getcpu 311
1787#endif
1788#ifndef __NR_fallocate
1789#define __NR_fallocate 314
1790#endif
1791/* Some syscalls are named/numbered differently between s390 and s390x. */
1792#ifdef __s390x__
1793# ifndef __NR_getrlimit
1794# define __NR_getrlimit 191
1795# endif
1796# ifndef __NR_setresuid
1797# define __NR_setresuid 208
1798# endif
1799# ifndef __NR_getresuid
1800# define __NR_getresuid 209
1801# endif
1802# ifndef __NR_setresgid
1803# define __NR_setresgid 210
1804# endif
1805# ifndef __NR_getresgid
1806# define __NR_getresgid 211
1807# endif
1808# ifndef __NR_setfsuid
1809# define __NR_setfsuid 215
1810# endif
1811# ifndef __NR_setfsgid
1812# define __NR_setfsgid 216
1813# endif
1814# ifndef __NR_fadvise64
1815# define __NR_fadvise64 253
1816# endif
1817# ifndef __NR_newfstatat
1818# define __NR_newfstatat 293
1819# endif
1820#else /* __s390x__ */
1821# ifndef __NR_getrlimit
1822# define __NR_getrlimit 76
1823# endif
1824# ifndef __NR_setfsuid
1825# define __NR_setfsuid 138
1826# endif
1827# ifndef __NR_setfsgid
1828# define __NR_setfsgid 139
1829# endif
1830# ifndef __NR_setresuid
1831# define __NR_setresuid 164
1832# endif
1833# ifndef __NR_getresuid
1834# define __NR_getresuid 165
1835# endif
1836# ifndef __NR_setresgid
1837# define __NR_setresgid 170
1838# endif
1839# ifndef __NR_getresgid
1840# define __NR_getresgid 171
1841# endif
1842# ifndef __NR_ugetrlimit
1843# define __NR_ugetrlimit 191
1844# endif
1845# ifndef __NR_mmap2
1846# define __NR_mmap2 192
1847# endif
1848# ifndef __NR_setresuid32
1849# define __NR_setresuid32 208
1850# endif
1851# ifndef __NR_getresuid32
1852# define __NR_getresuid32 209
1853# endif
1854# ifndef __NR_setresgid32
1855# define __NR_setresgid32 210
1856# endif
1857# ifndef __NR_getresgid32
1858# define __NR_getresgid32 211
1859# endif
1860# ifndef __NR_setfsuid32
1861# define __NR_setfsuid32 215
1862# endif
1863# ifndef __NR_setfsgid32
1864# define __NR_setfsgid32 216
1865# endif
1866# ifndef __NR_fadvise64_64
1867# define __NR_fadvise64_64 264
1868# endif
1869# ifndef __NR_fstatat64
1870# define __NR_fstatat64 293
1871# endif
1872#endif /* __s390__ */
1873/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001874#endif
1875
1876
1877/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001878#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001879 #error "Need to port invocations of syscalls for bounded ptrs"
1880#else
1881 /* The core dumper and the thread lister get executed after threads
1882 * have been suspended. As a consequence, we cannot call any functions
1883 * that acquire locks. Unfortunately, libc wraps most system calls
1884 * (e.g. in order to implement pthread_atfork, and to make calls
1885 * cancellable), which means we cannot call these functions. Instead,
1886 * we have to call syscall() directly.
1887 */
1888 #undef LSS_ERRNO
1889 #ifdef SYS_ERRNO
1890 /* Allow the including file to override the location of errno. This can
1891 * be useful when using clone() with the CLONE_VM option.
1892 */
1893 #define LSS_ERRNO SYS_ERRNO
1894 #else
1895 #define LSS_ERRNO errno
1896 #endif
1897
1898 #undef LSS_INLINE
1899 #ifdef SYS_INLINE
1900 #define LSS_INLINE SYS_INLINE
1901 #else
1902 #define LSS_INLINE static inline
1903 #endif
1904
1905 /* Allow the including file to override the prefix used for all new
1906 * system calls. By default, it will be set to "sys_".
1907 */
1908 #undef LSS_NAME
1909 #ifndef SYS_PREFIX
1910 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001911 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001912 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001913 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001914 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001915 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001916 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001917 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001918 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001919 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001920 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001921 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001922 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001923 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001924 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001925 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001926 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001927 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001928 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001929 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001930 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001931 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001932 #define LSS_NAME(name) sys9_##name
1933 #endif
1934
1935 #undef LSS_RETURN
Askar Safine1e7b0a2021-04-12 14:03:02 +03001936 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
1937 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \
Andreas Schwab1d387f42022-02-15 16:21:13 +01001938 || defined(__e2k__) || defined(__riscv)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001939 /* Failing system calls return a negative result in the range of
1940 * -1..-4095. These are "errno" values with the sign inverted.
1941 */
1942 #define LSS_RETURN(type, res) \
1943 do { \
1944 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
Peter Kasting0d6435b2022-07-20 20:21:35 +00001945 LSS_ERRNO = (int)(-(res)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001946 res = -1; \
1947 } \
1948 return (type) (res); \
1949 } while (0)
1950 #elif defined(__mips__)
1951 /* On MIPS, failing system calls return -1, and set errno in a
1952 * separate CPU register.
1953 */
1954 #define LSS_RETURN(type, res, err) \
1955 do { \
1956 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00001957 unsigned long __errnovalue = (res); \
1958 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001959 res = -1; \
1960 } \
1961 return (type) (res); \
1962 } while (0)
1963 #elif defined(__PPC__)
1964 /* On PPC, failing system calls return -1, and set errno in a
1965 * separate CPU register. See linux/unistd.h.
1966 */
1967 #define LSS_RETURN(type, res, err) \
1968 do { \
1969 if (err & 0x10000000 ) { \
1970 LSS_ERRNO = (res); \
1971 res = -1; \
1972 } \
1973 return (type) (res); \
1974 } while (0)
1975 #endif
1976 #if defined(__i386__)
1977 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1978 * reserves ebx. Unfortunately, most distribution ship with implementations
1979 * of _syscallX() which clobber ebx.
1980 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1981 * clobbered. This causes problems with compilers, that do a better job
1982 * at optimizing across __asm__ calls.
1983 * So, we just have to redefine all of the _syscallX() macros.
1984 */
1985 #undef LSS_ENTRYPOINT
1986 #ifdef SYS_SYSCALL_ENTRYPOINT
1987 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1988 void (**entrypoint)(void);
1989 asm volatile(".bss\n"
1990 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001991 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1992 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001993 ".previous\n"
1994 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
1995 "call 0f\n"
1996 "0:pop %0\n"
1997 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001998 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001999 : "=r"(entrypoint));
2000 return entrypoint;
2001 }
2002
2003 #define LSS_ENTRYPOINT ".bss\n" \
2004 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002005 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2006 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002007 ".previous\n" \
2008 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
2009 "push %%eax\n" \
2010 "call 10000f\n" \
2011 "10000:pop %%eax\n" \
2012 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002013 "mov " SYS_SYSCALL_ENTRYPOINT \
2014 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002015 "mov 0(%%eax), %%eax\n" \
2016 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002017 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002018 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002019 "call 10001f\n" \
2020 "10001:pop %%eax\n" \
2021 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002022 "xchg 4(%%esp), %%eax\n" \
2023 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002024 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002025 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00002026 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002027 #else
2028 #define LSS_ENTRYPOINT "int $0x80\n"
2029 #endif
2030 #undef LSS_BODY
2031 #define LSS_BODY(type,args...) \
2032 long __res; \
2033 __asm__ __volatile__("push %%ebx\n" \
2034 "movl %2,%%ebx\n" \
2035 LSS_ENTRYPOINT \
2036 "pop %%ebx" \
2037 args \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002038 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002039 LSS_RETURN(type,__res)
2040 #undef _syscall0
2041 #define _syscall0(type,name) \
2042 type LSS_NAME(name)(void) { \
2043 long __res; \
2044 __asm__ volatile(LSS_ENTRYPOINT \
2045 : "=a" (__res) \
2046 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08002047 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002048 LSS_RETURN(type,__res); \
2049 }
2050 #undef _syscall1
2051 #define _syscall1(type,name,type1,arg1) \
2052 type LSS_NAME(name)(type1 arg1) { \
2053 LSS_BODY(type, \
2054 : "=a" (__res) \
2055 : "0" (__NR_##name), "ri" ((long)(arg1))); \
2056 }
2057 #undef _syscall2
2058 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2059 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
2060 LSS_BODY(type, \
2061 : "=a" (__res) \
2062 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
2063 }
2064 #undef _syscall3
2065 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2066 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
2067 LSS_BODY(type, \
2068 : "=a" (__res) \
2069 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2070 "d" ((long)(arg3))); \
2071 }
2072 #undef _syscall4
2073 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2074 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2075 LSS_BODY(type, \
2076 : "=a" (__res) \
2077 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2078 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2079 }
2080 #undef _syscall5
2081 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2082 type5,arg5) \
2083 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2084 type5 arg5) { \
2085 long __res; \
2086 __asm__ __volatile__("push %%ebx\n" \
2087 "movl %2,%%ebx\n" \
2088 "movl %1,%%eax\n" \
2089 LSS_ENTRYPOINT \
2090 "pop %%ebx" \
2091 : "=a" (__res) \
2092 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2093 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2094 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002095 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002096 LSS_RETURN(type,__res); \
2097 }
2098 #undef _syscall6
2099 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2100 type5,arg5,type6,arg6) \
2101 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2102 type5 arg5, type6 arg6) { \
2103 long __res; \
2104 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2105 __asm__ __volatile__("push %%ebp\n" \
2106 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002107 "movl 4(%2),%%ebp\n" \
2108 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002109 "movl %1,%%eax\n" \
2110 LSS_ENTRYPOINT \
2111 "pop %%ebx\n" \
2112 "pop %%ebp" \
2113 : "=a" (__res) \
2114 : "i" (__NR_##name), "0" ((long)(&__s)), \
2115 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2116 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002117 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002118 LSS_RETURN(type,__res); \
2119 }
2120 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2121 int flags, void *arg, int *parent_tidptr,
2122 void *newtls, int *child_tidptr) {
2123 long __res;
2124 __asm__ __volatile__(/* if (fn == NULL)
2125 * return -EINVAL;
2126 */
2127 "movl %3,%%ecx\n"
2128 "jecxz 1f\n"
2129
2130 /* if (child_stack == NULL)
2131 * return -EINVAL;
2132 */
2133 "movl %4,%%ecx\n"
2134 "jecxz 1f\n"
2135
2136 /* Set up alignment of the child stack:
2137 * child_stack = (child_stack & ~0xF) - 20;
2138 */
2139 "andl $-16,%%ecx\n"
2140 "subl $20,%%ecx\n"
2141
2142 /* Push "arg" and "fn" onto the stack that will be
2143 * used by the child.
2144 */
2145 "movl %6,%%eax\n"
2146 "movl %%eax,4(%%ecx)\n"
2147 "movl %3,%%eax\n"
2148 "movl %%eax,(%%ecx)\n"
2149
2150 /* %eax = syscall(%eax = __NR_clone,
2151 * %ebx = flags,
2152 * %ecx = child_stack,
2153 * %edx = parent_tidptr,
2154 * %esi = newtls,
2155 * %edi = child_tidptr)
2156 * Also, make sure that %ebx gets preserved as it is
2157 * used in PIC mode.
2158 */
2159 "movl %8,%%esi\n"
2160 "movl %7,%%edx\n"
2161 "movl %5,%%eax\n"
2162 "movl %9,%%edi\n"
2163 "pushl %%ebx\n"
2164 "movl %%eax,%%ebx\n"
2165 "movl %2,%%eax\n"
2166 LSS_ENTRYPOINT
2167
2168 /* In the parent: restore %ebx
2169 * In the child: move "fn" into %ebx
2170 */
2171 "popl %%ebx\n"
2172
2173 /* if (%eax != 0)
2174 * return %eax;
2175 */
2176 "test %%eax,%%eax\n"
2177 "jnz 1f\n"
2178
2179 /* In the child, now. Terminate frame pointer chain.
2180 */
2181 "movl $0,%%ebp\n"
2182
2183 /* Call "fn". "arg" is already on the stack.
2184 */
2185 "call *%%ebx\n"
2186
2187 /* Call _exit(%ebx). Unfortunately older versions
2188 * of gcc restrict the number of arguments that can
2189 * be passed to asm(). So, we need to hard-code the
2190 * system call number.
2191 */
2192 "movl %%eax,%%ebx\n"
2193 "movl $1,%%eax\n"
2194 LSS_ENTRYPOINT
2195
2196 /* Return to parent.
2197 */
2198 "1:\n"
2199 : "=a" (__res)
2200 : "0"(-EINVAL), "i"(__NR_clone),
2201 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2202 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002203 : "memory", "ecx", "edx", "esi", "edi");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002204 LSS_RETURN(int, __res);
2205 }
2206
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002207 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2208 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2209
2210 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2211 /* On i386, the kernel does not know how to return from a signal
2212 * handler. Instead, it relies on user space to provide a
2213 * restorer function that calls the {rt_,}sigreturn() system call.
2214 * Unfortunately, we cannot just reference the glibc version of this
2215 * function, as glibc goes out of its way to make it inaccessible.
2216 */
2217 void (*res)(void);
2218 __asm__ __volatile__("call 2f\n"
2219 "0:.align 16\n"
2220 "1:movl %1,%%eax\n"
2221 LSS_ENTRYPOINT
2222 "2:popl %0\n"
2223 "addl $(1b-0b),%0\n"
2224 : "=a" (res)
2225 : "i" (__NR_rt_sigreturn));
2226 return res;
2227 }
2228 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
2229 /* On i386, the kernel does not know how to return from a signal
2230 * handler. Instead, it relies on user space to provide a
2231 * restorer function that calls the {rt_,}sigreturn() system call.
2232 * Unfortunately, we cannot just reference the glibc version of this
2233 * function, as glibc goes out of its way to make it inaccessible.
2234 */
2235 void (*res)(void);
2236 __asm__ __volatile__("call 2f\n"
2237 "0:.align 16\n"
2238 "1:pop %%eax\n"
2239 "movl %1,%%eax\n"
2240 LSS_ENTRYPOINT
2241 "2:popl %0\n"
2242 "addl $(1b-0b),%0\n"
2243 : "=a" (res)
2244 : "i" (__NR_sigreturn));
2245 return res;
2246 }
2247 #elif defined(__x86_64__)
2248 /* There are no known problems with any of the _syscallX() macros
2249 * currently shipping for x86_64, but we still need to be able to define
2250 * our own version so that we can override the location of the errno
2251 * location (e.g. when using the clone() system call with the CLONE_VM
2252 * option).
2253 */
2254 #undef LSS_ENTRYPOINT
2255 #ifdef SYS_SYSCALL_ENTRYPOINT
2256 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2257 void (**entrypoint)(void);
2258 asm volatile(".bss\n"
2259 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002260 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2261 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002262 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002263 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002264 : "=r"(entrypoint));
2265 return entrypoint;
2266 }
2267
2268 #define LSS_ENTRYPOINT \
2269 ".bss\n" \
2270 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002271 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2272 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002273 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002274 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002275 "mov 0(%%rcx), %%rcx\n" \
2276 "test %%rcx, %%rcx\n" \
2277 "jz 10001f\n" \
2278 "call *%%rcx\n" \
2279 "jmp 10002f\n" \
2280 "10001:syscall\n" \
2281 "10002:\n"
2282
2283 #else
2284 #define LSS_ENTRYPOINT "syscall\n"
2285 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002286
2287 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2288 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2289 * sign extension. We can't cast pointers directly because those are
2290 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2291 * to an integer of a different size.
2292 */
2293 #undef LSS_SYSCALL_ARG
2294 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2295 #undef _LSS_RETURN
2296 #define _LSS_RETURN(type, res, cast) \
2297 do { \
2298 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
Peter Kasting880985f2022-06-29 21:17:55 +00002299 LSS_ERRNO = (int)(-(res)); \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002300 res = -1; \
2301 } \
2302 return (type)(cast)(res); \
2303 } while (0)
2304 #undef LSS_RETURN
2305 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2306
2307 #undef _LSS_BODY
2308 #define _LSS_BODY(nr, type, name, cast, ...) \
2309 long long __res; \
2310 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2311 : "=a" (__res) \
2312 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2313 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2314 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002315 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002316 #define LSS_BODY(nr, type, name, args...) \
2317 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2318
2319 #undef LSS_BODY_ASM0
2320 #undef LSS_BODY_ASM1
2321 #undef LSS_BODY_ASM2
2322 #undef LSS_BODY_ASM3
2323 #undef LSS_BODY_ASM4
2324 #undef LSS_BODY_ASM5
2325 #undef LSS_BODY_ASM6
2326 #define LSS_BODY_ASM0
2327 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2328 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2329 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2330 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2331 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2332 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2333
2334 #undef LSS_BODY_CLOBBER0
2335 #undef LSS_BODY_CLOBBER1
2336 #undef LSS_BODY_CLOBBER2
2337 #undef LSS_BODY_CLOBBER3
2338 #undef LSS_BODY_CLOBBER4
2339 #undef LSS_BODY_CLOBBER5
2340 #undef LSS_BODY_CLOBBER6
2341 #define LSS_BODY_CLOBBER0
2342 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2343 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2344 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2345 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2346 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2347 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2348
2349 #undef LSS_BODY_ARG0
2350 #undef LSS_BODY_ARG1
2351 #undef LSS_BODY_ARG2
2352 #undef LSS_BODY_ARG3
2353 #undef LSS_BODY_ARG4
2354 #undef LSS_BODY_ARG5
2355 #undef LSS_BODY_ARG6
2356 #define LSS_BODY_ARG0()
2357 #define LSS_BODY_ARG1(arg1) \
2358 LSS_BODY_ARG0(), "D" (arg1)
2359 #define LSS_BODY_ARG2(arg1, arg2) \
2360 LSS_BODY_ARG1(arg1), "S" (arg2)
2361 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2362 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2363 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2364 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2365 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2366 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2367 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2368 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2369
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002370 #undef _syscall0
2371 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002372 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002373 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002374 }
2375 #undef _syscall1
2376 #define _syscall1(type,name,type1,arg1) \
2377 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002378 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002379 }
2380 #undef _syscall2
2381 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2382 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002383 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002384 }
2385 #undef _syscall3
2386 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2387 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002388 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2389 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002390 }
2391 #undef _syscall4
2392 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2393 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002394 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2395 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002396 }
2397 #undef _syscall5
2398 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2399 type5,arg5) \
2400 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2401 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002402 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2403 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2404 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002405 }
2406 #undef _syscall6
2407 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2408 type5,arg5,type6,arg6) \
2409 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2410 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002411 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2412 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2413 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002414 }
2415 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2416 int flags, void *arg, int *parent_tidptr,
2417 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002418 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002419 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002420 __asm__ __volatile__(/* if (fn == NULL)
2421 * return -EINVAL;
2422 */
2423 "testq %4,%4\n"
2424 "jz 1f\n"
2425
2426 /* if (child_stack == NULL)
2427 * return -EINVAL;
2428 */
2429 "testq %5,%5\n"
2430 "jz 1f\n"
2431
2432 /* childstack -= 2*sizeof(void *);
2433 */
2434 "subq $16,%5\n"
2435
2436 /* Push "arg" and "fn" onto the stack that will be
2437 * used by the child.
2438 */
2439 "movq %7,8(%5)\n"
2440 "movq %4,0(%5)\n"
2441
2442 /* %rax = syscall(%rax = __NR_clone,
2443 * %rdi = flags,
2444 * %rsi = child_stack,
2445 * %rdx = parent_tidptr,
2446 * %r8 = new_tls,
2447 * %r10 = child_tidptr)
2448 */
2449 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002450 "movq %9,%%r8\n"
2451 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002452 LSS_ENTRYPOINT
2453
2454 /* if (%rax != 0)
2455 * return;
2456 */
2457 "testq %%rax,%%rax\n"
2458 "jnz 1f\n"
2459
2460 /* In the child. Terminate frame pointer chain.
2461 */
2462 "xorq %%rbp,%%rbp\n"
2463
2464 /* Call "fn(arg)".
2465 */
2466 "popq %%rax\n"
2467 "popq %%rdi\n"
2468 "call *%%rax\n"
2469
2470 /* Call _exit(%ebx).
2471 */
2472 "movq %%rax,%%rdi\n"
2473 "movq %3,%%rax\n"
2474 LSS_ENTRYPOINT
2475
2476 /* Return to parent.
2477 */
2478 "1:\n"
2479 : "=a" (__res)
2480 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002481 "r"(LSS_SYSCALL_ARG(fn)),
2482 "S"(LSS_SYSCALL_ARG(child_stack)),
2483 "D"(LSS_SYSCALL_ARG(flags)),
2484 "r"(LSS_SYSCALL_ARG(arg)),
2485 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2486 "r"(LSS_SYSCALL_ARG(newtls)),
2487 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002488 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002489 }
2490 LSS_RETURN(int, __res);
2491 }
2492 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002493
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002494 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2495 /* On x86-64, the kernel does not know how to return from
2496 * a signal handler. Instead, it relies on user space to provide a
2497 * restorer function that calls the rt_sigreturn() system call.
2498 * Unfortunately, we cannot just reference the glibc version of this
2499 * function, as glibc goes out of its way to make it inaccessible.
2500 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002501 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002502 __asm__ __volatile__("jmp 2f\n"
2503 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002504 "1:movq %1,%%rax\n"
2505 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002506 "2:leaq 1b(%%rip),%0\n"
2507 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002508 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002509 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002510 }
2511 #elif defined(__ARM_ARCH_3__)
2512 /* Most definitions of _syscallX() neglect to mark "memory" as being
2513 * clobbered. This causes problems with compilers, that do a better job
2514 * at optimizing across __asm__ calls.
2515 * So, we just have to redefine all of the _syscallX() macros.
2516 */
2517 #undef LSS_REG
2518 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2519 #undef LSS_BODY
2520 #define LSS_BODY(type,name,args...) \
2521 register long __res_r0 __asm__("r0"); \
2522 long __res; \
2523 __asm__ __volatile__ (__syscall(name) \
2524 : "=r"(__res_r0) : args : "lr", "memory"); \
2525 __res = __res_r0; \
2526 LSS_RETURN(type, __res)
2527 #undef _syscall0
2528 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002529 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002530 LSS_BODY(type, name); \
2531 }
2532 #undef _syscall1
2533 #define _syscall1(type, name, type1, arg1) \
2534 type LSS_NAME(name)(type1 arg1) { \
2535 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2536 }
2537 #undef _syscall2
2538 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2539 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2540 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2541 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2542 }
2543 #undef _syscall3
2544 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2545 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2546 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2547 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2548 }
2549 #undef _syscall4
2550 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2551 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2552 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2553 LSS_REG(3, arg4); \
2554 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2555 }
2556 #undef _syscall5
2557 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2558 type5,arg5) \
2559 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2560 type5 arg5) { \
2561 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2562 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2563 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2564 "r"(__r4)); \
2565 }
2566 #undef _syscall6
2567 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2568 type5,arg5,type6,arg6) \
2569 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2570 type5 arg5, type6 arg6) { \
2571 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2572 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2573 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2574 "r"(__r4), "r"(__r5)); \
2575 }
2576 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2577 int flags, void *arg, int *parent_tidptr,
2578 void *newtls, int *child_tidptr) {
2579 long __res;
2580 {
2581 register int __flags __asm__("r0") = flags;
2582 register void *__stack __asm__("r1") = child_stack;
2583 register void *__ptid __asm__("r2") = parent_tidptr;
2584 register void *__tls __asm__("r3") = newtls;
2585 register int *__ctid __asm__("r4") = child_tidptr;
2586 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2587 * return -EINVAL;
2588 */
2589 "cmp %2,#0\n"
2590 "cmpne %3,#0\n"
2591 "moveq %0,%1\n"
2592 "beq 1f\n"
2593
2594 /* Push "arg" and "fn" onto the stack that will be
2595 * used by the child.
2596 */
2597 "str %5,[%3,#-4]!\n"
2598 "str %2,[%3,#-4]!\n"
2599
2600 /* %r0 = syscall(%r0 = flags,
2601 * %r1 = child_stack,
2602 * %r2 = parent_tidptr,
2603 * %r3 = newtls,
2604 * %r4 = child_tidptr)
2605 */
2606 __syscall(clone)"\n"
2607
2608 /* if (%r0 != 0)
2609 * return %r0;
2610 */
2611 "movs %0,r0\n"
2612 "bne 1f\n"
2613
2614 /* In the child, now. Call "fn(arg)".
2615 */
2616 "ldr r0,[sp, #4]\n"
2617 "mov lr,pc\n"
2618 "ldr pc,[sp]\n"
2619
2620 /* Call _exit(%r0).
2621 */
2622 __syscall(exit)"\n"
2623 "1:\n"
2624 : "=r" (__res)
2625 : "i"(-EINVAL),
2626 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2627 "r"(__ptid), "r"(__tls), "r"(__ctid)
2628 : "cc", "lr", "memory");
2629 }
2630 LSS_RETURN(int, __res);
2631 }
2632 #elif defined(__ARM_EABI__)
2633 /* Most definitions of _syscallX() neglect to mark "memory" as being
2634 * clobbered. This causes problems with compilers, that do a better job
2635 * at optimizing across __asm__ calls.
2636 * So, we just have to redefine all fo the _syscallX() macros.
2637 */
2638 #undef LSS_REG
2639 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2640 #undef LSS_BODY
2641 #define LSS_BODY(type,name,args...) \
2642 register long __res_r0 __asm__("r0"); \
2643 long __res; \
2644 __asm__ __volatile__ ("push {r7}\n" \
2645 "mov r7, %1\n" \
2646 "swi 0x0\n" \
2647 "pop {r7}\n" \
2648 : "=r"(__res_r0) \
2649 : "i"(__NR_##name) , ## args \
2650 : "lr", "memory"); \
2651 __res = __res_r0; \
2652 LSS_RETURN(type, __res)
2653 #undef _syscall0
2654 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002655 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002656 LSS_BODY(type, name); \
2657 }
2658 #undef _syscall1
2659 #define _syscall1(type, name, type1, arg1) \
2660 type LSS_NAME(name)(type1 arg1) { \
2661 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2662 }
2663 #undef _syscall2
2664 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2665 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2666 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2667 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2668 }
2669 #undef _syscall3
2670 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2671 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2672 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2673 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2674 }
2675 #undef _syscall4
2676 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2677 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2678 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2679 LSS_REG(3, arg4); \
2680 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2681 }
2682 #undef _syscall5
2683 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2684 type5,arg5) \
2685 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2686 type5 arg5) { \
2687 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2688 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2689 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2690 "r"(__r4)); \
2691 }
2692 #undef _syscall6
2693 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2694 type5,arg5,type6,arg6) \
2695 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2696 type5 arg5, type6 arg6) { \
2697 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2698 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2699 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2700 "r"(__r4), "r"(__r5)); \
2701 }
2702 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2703 int flags, void *arg, int *parent_tidptr,
2704 void *newtls, int *child_tidptr) {
2705 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002706 if (fn == NULL || child_stack == NULL) {
2707 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002708 LSS_RETURN(int, __res);
2709 }
2710
2711 /* Push "arg" and "fn" onto the stack that will be
2712 * used by the child.
2713 */
2714 {
2715 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2716 cstack[0] = (uintptr_t)fn;
2717 cstack[1] = (uintptr_t)arg;
2718 child_stack = cstack;
2719 }
2720 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002721 register int __flags __asm__("r0") = flags;
2722 register void *__stack __asm__("r1") = child_stack;
2723 register void *__ptid __asm__("r2") = parent_tidptr;
2724 register void *__tls __asm__("r3") = newtls;
2725 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002726 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002727#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002728 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002729#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002730 /* %r0 = syscall(%r0 = flags,
2731 * %r1 = child_stack,
2732 * %r2 = parent_tidptr,
2733 * %r3 = newtls,
2734 * %r4 = child_tidptr)
2735 */
2736 "mov r7, %6\n"
2737 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002738
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002739 /* if (%r0 != 0)
2740 * return %r0;
2741 */
2742 "cmp r0, #0\n"
2743 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002744
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002745 /* In the child, now. Call "fn(arg)".
2746 */
2747 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002748
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002749 "ldr lr,[sp]\n"
2750 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002751
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002752 /* Call _exit(%r0).
2753 */
2754 "mov r7, %7\n"
2755 "swi 0x0\n"
2756 /* Unreachable */
2757 "bkpt #0\n"
2758 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002759#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002760 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002761#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002762 "movs %0,r0\n"
2763 : "=r"(__res)
2764 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2765 "i"(__NR_clone), "i"(__NR_exit)
2766 : "cc", "lr", "memory"
2767#ifndef __thumb2__
2768 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002769#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002770 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002771 }
2772 LSS_RETURN(int, __res);
2773 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002774 #elif defined(__aarch64__)
2775 /* Most definitions of _syscallX() neglect to mark "memory" as being
2776 * clobbered. This causes problems with compilers, that do a better job
2777 * at optimizing across __asm__ calls.
2778 * So, we just have to redefine all of the _syscallX() macros.
2779 */
2780 #undef LSS_REG
2781 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2782 #undef LSS_BODY
2783 #define LSS_BODY(type,name,args...) \
2784 register int64_t __res_x0 __asm__("x0"); \
2785 int64_t __res; \
2786 __asm__ __volatile__ ("mov x8, %1\n" \
2787 "svc 0x0\n" \
2788 : "=r"(__res_x0) \
2789 : "i"(__NR_##name) , ## args \
2790 : "x8", "memory"); \
2791 __res = __res_x0; \
2792 LSS_RETURN(type, __res)
2793 #undef _syscall0
2794 #define _syscall0(type, name) \
2795 type LSS_NAME(name)(void) { \
2796 LSS_BODY(type, name); \
2797 }
2798 #undef _syscall1
2799 #define _syscall1(type, name, type1, arg1) \
2800 type LSS_NAME(name)(type1 arg1) { \
2801 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2802 }
2803 #undef _syscall2
2804 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2805 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2806 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2807 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2808 }
2809 #undef _syscall3
2810 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2811 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2812 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2813 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2814 }
2815 #undef _syscall4
2816 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2817 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2818 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2819 LSS_REG(3, arg4); \
2820 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2821 }
2822 #undef _syscall5
2823 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2824 type5,arg5) \
2825 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2826 type5 arg5) { \
2827 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2828 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2829 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2830 "r"(__r4)); \
2831 }
2832 #undef _syscall6
2833 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2834 type5,arg5,type6,arg6) \
2835 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2836 type5 arg5, type6 arg6) { \
2837 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2838 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2839 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2840 "r"(__r4), "r"(__r5)); \
2841 }
2842
2843 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2844 int flags, void *arg, int *parent_tidptr,
2845 void *newtls, int *child_tidptr) {
2846 int64_t __res;
2847 {
Peter Kasting0d6435b2022-07-20 20:21:35 +00002848 register uint64_t __flags __asm__("x0") = (uint64_t)flags;
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002849 register void *__stack __asm__("x1") = child_stack;
2850 register void *__ptid __asm__("x2") = parent_tidptr;
2851 register void *__tls __asm__("x3") = newtls;
2852 register int *__ctid __asm__("x4") = child_tidptr;
2853 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2854 * used by the child.
2855 */
2856 "stp %1, %4, [%2, #-16]!\n"
2857
2858 /* %x0 = syscall(%x0 = flags,
2859 * %x1 = child_stack,
2860 * %x2 = parent_tidptr,
2861 * %x3 = newtls,
2862 * %x4 = child_tidptr)
2863 */
2864 "mov x8, %8\n"
2865 "svc 0x0\n"
2866
2867 /* if (%r0 != 0)
2868 * return %r0;
2869 */
2870 "mov %0, x0\n"
2871 "cbnz x0, 1f\n"
2872
2873 /* In the child, now. Call "fn(arg)".
2874 */
2875 "ldp x1, x0, [sp], #16\n"
2876 "blr x1\n"
2877
2878 /* Call _exit(%r0).
2879 */
2880 "mov x8, %9\n"
2881 "svc 0x0\n"
2882 "1:\n"
2883 : "=r" (__res)
2884 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2885 "r"(__ptid), "r"(__tls), "r"(__ctid),
2886 "i"(__NR_clone), "i"(__NR_exit)
2887 : "cc", "x8", "memory");
2888 }
2889 LSS_RETURN(int, __res);
2890 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002891 #elif defined(__mips__)
2892 #undef LSS_REG
2893 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2894 (unsigned long)(a)
2895 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002896 #undef LSS_SYSCALL_CLOBBERS
2897 #if _MIPS_SIM == _MIPS_SIM_ABI32
2898 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2899 "$11", "$12", "$13", "$14", "$15", \
2900 "$24", "$25", "hi", "lo", "memory"
2901 #else
2902 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2903 "$13", "$14", "$15", "$24", "$25", \
2904 "hi", "lo", "memory"
2905 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002906 #define LSS_BODY(type,name,r7,...) \
2907 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2908 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002909 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002910 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002911 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002912 LSS_RETURN(type, __v0, __r7)
2913 #undef _syscall0
2914 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002915 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002916 register unsigned long __r7 __asm__("$7"); \
2917 LSS_BODY(type, name, "=r"); \
2918 }
2919 #undef _syscall1
2920 #define _syscall1(type, name, type1, arg1) \
2921 type LSS_NAME(name)(type1 arg1) { \
2922 register unsigned long __r7 __asm__("$7"); \
2923 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2924 }
2925 #undef _syscall2
2926 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2927 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2928 register unsigned long __r7 __asm__("$7"); \
2929 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2930 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2931 }
2932 #undef _syscall3
2933 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2934 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2935 register unsigned long __r7 __asm__("$7"); \
2936 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2937 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2938 }
2939 #undef _syscall4
2940 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2941 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2942 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2943 LSS_REG(7, arg4); \
2944 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2945 }
2946 #undef _syscall5
2947 #if _MIPS_SIM == _MIPS_SIM_ABI32
2948 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2949 * on the stack, whereas the new APIs use registers "r8" and "r9".
2950 */
2951 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2952 type5,arg5) \
2953 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2954 type5 arg5) { \
2955 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2956 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002957 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002958 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002959 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002960 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002961 "syscall\n" \
2962 "addiu $29, 32\n" \
2963 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002964 : "+r"(__v0), "+r" (__r7) \
2965 : "r"(__r4), "r"(__r5), \
2966 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002967 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002968 "$13", "$14", "$15", "$24", "$25", \
2969 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002970 LSS_RETURN(type, __v0, __r7); \
2971 }
2972 #else
2973 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2974 type5,arg5) \
2975 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2976 type5 arg5) { \
2977 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2978 LSS_REG(7, arg4); LSS_REG(8, arg5); \
2979 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2980 "r"(__r8)); \
2981 }
2982 #endif
2983 #undef _syscall6
2984 #if _MIPS_SIM == _MIPS_SIM_ABI32
2985 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2986 * on the stack, whereas the new APIs use registers "r8" and "r9".
2987 */
2988 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2989 type5,arg5,type6,arg6) \
2990 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2991 type5 arg5, type6 arg6) { \
2992 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2993 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002994 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002995 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002996 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002997 "sw %5, 16($29)\n" \
2998 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002999 "syscall\n" \
3000 "addiu $29, 32\n" \
3001 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003002 : "+r"(__v0), "+r" (__r7) \
3003 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003004 "r"(__r6), "r" ((unsigned long)arg5), \
3005 "r" ((unsigned long)arg6) \
3006 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003007 "$13", "$14", "$15", "$24", "$25", \
3008 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003009 LSS_RETURN(type, __v0, __r7); \
3010 }
3011 #else
3012 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3013 type5,arg5,type6,arg6) \
3014 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3015 type5 arg5,type6 arg6) { \
3016 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
3017 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
3018 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
3019 "r"(__r8), "r"(__r9)); \
3020 }
3021 #endif
3022 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3023 int flags, void *arg, int *parent_tidptr,
3024 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00003025 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003026 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
3027 {
3028 register int __flags __asm__("$4") = flags;
3029 register void *__stack __asm__("$5") = child_stack;
3030 register void *__ptid __asm__("$6") = parent_tidptr;
3031 register int *__ctid __asm__("$8") = child_tidptr;
3032 __asm__ __volatile__(
3033 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3034 "subu $29,24\n"
3035 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3036 "sub $29,16\n"
3037 #else
3038 "dsubu $29,16\n"
3039 #endif
3040
3041 /* if (fn == NULL || child_stack == NULL)
3042 * return -EINVAL;
3043 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003044 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003045 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003046
3047 /* Push "arg" and "fn" onto the stack that will be
3048 * used by the child.
3049 */
3050 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003051 "subu %5,32\n"
3052 "sw %4,0(%5)\n"
3053 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003054 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003055 "sub %5,32\n"
3056 "sw %4,0(%5)\n"
3057 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003058 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00003059 "dsubu %5,32\n"
3060 "sd %4,0(%5)\n"
3061 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003062 #endif
3063
3064 /* $7 = syscall($4 = flags,
3065 * $5 = child_stack,
3066 * $6 = parent_tidptr,
3067 * $7 = newtls,
3068 * $8 = child_tidptr)
3069 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003070 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003071 "syscall\n"
3072
3073 /* if ($7 != 0)
3074 * return $2;
3075 */
3076 "bnez $7,1f\n"
3077 "bnez $2,1f\n"
3078
3079 /* In the child, now. Call "fn(arg)".
3080 */
3081 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3082 "lw $25,0($29)\n"
3083 "lw $4,4($29)\n"
3084 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3085 "lw $25,0($29)\n"
3086 "lw $4,8($29)\n"
3087 #else
3088 "ld $25,0($29)\n"
3089 "ld $4,8($29)\n"
3090 #endif
3091 "jalr $25\n"
3092
3093 /* Call _exit($2)
3094 */
3095 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003096 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003097 "syscall\n"
3098
3099 "1:\n"
3100 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3101 "addu $29, 24\n"
3102 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3103 "add $29, 16\n"
3104 #else
3105 "daddu $29,16\n"
3106 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003107 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003108 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3109 "r"(__stack), "r"(__flags), "r"(arg),
3110 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003111 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003112 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003113 }
3114 LSS_RETURN(int, __v0, __r7);
3115 }
3116 #elif defined (__PPC__)
3117 #undef LSS_LOADARGS_0
3118 #define LSS_LOADARGS_0(name, dummy...) \
3119 __sc_0 = __NR_##name
3120 #undef LSS_LOADARGS_1
3121 #define LSS_LOADARGS_1(name, arg1) \
3122 LSS_LOADARGS_0(name); \
3123 __sc_3 = (unsigned long) (arg1)
3124 #undef LSS_LOADARGS_2
3125 #define LSS_LOADARGS_2(name, arg1, arg2) \
3126 LSS_LOADARGS_1(name, arg1); \
3127 __sc_4 = (unsigned long) (arg2)
3128 #undef LSS_LOADARGS_3
3129 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3130 LSS_LOADARGS_2(name, arg1, arg2); \
3131 __sc_5 = (unsigned long) (arg3)
3132 #undef LSS_LOADARGS_4
3133 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3134 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3135 __sc_6 = (unsigned long) (arg4)
3136 #undef LSS_LOADARGS_5
3137 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3138 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3139 __sc_7 = (unsigned long) (arg5)
3140 #undef LSS_LOADARGS_6
3141 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3142 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3143 __sc_8 = (unsigned long) (arg6)
3144 #undef LSS_ASMINPUT_0
3145 #define LSS_ASMINPUT_0 "0" (__sc_0)
3146 #undef LSS_ASMINPUT_1
3147 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3148 #undef LSS_ASMINPUT_2
3149 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3150 #undef LSS_ASMINPUT_3
3151 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3152 #undef LSS_ASMINPUT_4
3153 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3154 #undef LSS_ASMINPUT_5
3155 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3156 #undef LSS_ASMINPUT_6
3157 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3158 #undef LSS_BODY
3159 #define LSS_BODY(nr, type, name, args...) \
3160 long __sc_ret, __sc_err; \
3161 { \
3162 register unsigned long __sc_0 __asm__ ("r0"); \
3163 register unsigned long __sc_3 __asm__ ("r3"); \
3164 register unsigned long __sc_4 __asm__ ("r4"); \
3165 register unsigned long __sc_5 __asm__ ("r5"); \
3166 register unsigned long __sc_6 __asm__ ("r6"); \
3167 register unsigned long __sc_7 __asm__ ("r7"); \
3168 register unsigned long __sc_8 __asm__ ("r8"); \
3169 \
3170 LSS_LOADARGS_##nr(name, args); \
3171 __asm__ __volatile__ \
3172 ("sc\n\t" \
3173 "mfcr %0" \
3174 : "=&r" (__sc_0), \
3175 "=&r" (__sc_3), "=&r" (__sc_4), \
3176 "=&r" (__sc_5), "=&r" (__sc_6), \
3177 "=&r" (__sc_7), "=&r" (__sc_8) \
3178 : LSS_ASMINPUT_##nr \
3179 : "cr0", "ctr", "memory", \
3180 "r9", "r10", "r11", "r12"); \
3181 __sc_ret = __sc_3; \
3182 __sc_err = __sc_0; \
3183 } \
3184 LSS_RETURN(type, __sc_ret, __sc_err)
3185 #undef _syscall0
3186 #define _syscall0(type, name) \
3187 type LSS_NAME(name)(void) { \
3188 LSS_BODY(0, type, name); \
3189 }
3190 #undef _syscall1
3191 #define _syscall1(type, name, type1, arg1) \
3192 type LSS_NAME(name)(type1 arg1) { \
3193 LSS_BODY(1, type, name, arg1); \
3194 }
3195 #undef _syscall2
3196 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3197 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3198 LSS_BODY(2, type, name, arg1, arg2); \
3199 }
3200 #undef _syscall3
3201 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3202 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3203 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3204 }
3205 #undef _syscall4
3206 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3207 type4, arg4) \
3208 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3209 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3210 }
3211 #undef _syscall5
3212 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3213 type4, arg4, type5, arg5) \
3214 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3215 type5 arg5) { \
3216 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3217 }
3218 #undef _syscall6
3219 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3220 type4, arg4, type5, arg5, type6, arg6) \
3221 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3222 type5 arg5, type6 arg6) { \
3223 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3224 }
3225 /* clone function adapted from glibc 2.3.6 clone.S */
3226 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3227 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3228 */
3229 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3230 int flags, void *arg, int *parent_tidptr,
3231 void *newtls, int *child_tidptr) {
3232 long __ret, __err;
3233 {
3234 register int (*__fn)(void *) __asm__ ("r8") = fn;
3235 register void *__cstack __asm__ ("r4") = child_stack;
3236 register int __flags __asm__ ("r3") = flags;
3237 register void * __arg __asm__ ("r9") = arg;
3238 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3239 register void * __newtls __asm__ ("r6") = newtls;
3240 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3241 __asm__ __volatile__(
3242 /* check for fn == NULL
3243 * and child_stack == NULL
3244 */
3245 "cmpwi cr0, %6, 0\n\t"
3246 "cmpwi cr1, %7, 0\n\t"
3247 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3248 "beq- cr0, 1f\n\t"
3249
3250 /* set up stack frame for child */
3251 "clrrwi %7, %7, 4\n\t"
3252 "li 0, 0\n\t"
3253 "stwu 0, -16(%7)\n\t"
3254
3255 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3256 "mr 28, %6\n\t"
3257 "mr 29, %7\n\t"
3258 "mr 27, %9\n\t"
3259
3260 /* syscall */
3261 "li 0, %4\n\t"
3262 /* flags already in r3
3263 * child_stack already in r4
3264 * ptidptr already in r5
3265 * newtls already in r6
3266 * ctidptr already in r7
3267 */
3268 "sc\n\t"
3269
3270 /* Test if syscall was successful */
3271 "cmpwi cr1, 3, 0\n\t"
3272 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3273 "bne- cr1, 1f\n\t"
3274
3275 /* Do the function call */
3276 "mtctr 28\n\t"
3277 "mr 3, 27\n\t"
3278 "bctrl\n\t"
3279
3280 /* Call _exit(r3) */
3281 "li 0, %5\n\t"
3282 "sc\n\t"
3283
3284 /* Return to parent */
3285 "1:\n"
3286 "mfcr %1\n\t"
3287 "mr %0, 3\n\t"
3288 : "=r" (__ret), "=r" (__err)
3289 : "0" (-1), "1" (EINVAL),
3290 "i" (__NR_clone), "i" (__NR_exit),
3291 "r" (__fn), "r" (__cstack), "r" (__flags),
3292 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3293 "r" (__ctidptr)
3294 : "cr0", "cr1", "memory", "ctr",
3295 "r0", "r29", "r27", "r28");
3296 }
3297 LSS_RETURN(int, __ret, __err);
3298 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003299 #elif defined(__s390__)
3300 #undef LSS_REG
3301 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3302 #undef LSS_BODY
3303 #define LSS_BODY(type, name, args...) \
3304 register unsigned long __nr __asm__("r1") \
3305 = (unsigned long)(__NR_##name); \
3306 register long __res_r2 __asm__("r2"); \
3307 long __res; \
3308 __asm__ __volatile__ \
3309 ("svc 0\n\t" \
3310 : "=d"(__res_r2) \
3311 : "d"(__nr), ## args \
3312 : "memory"); \
3313 __res = __res_r2; \
3314 LSS_RETURN(type, __res)
3315 #undef _syscall0
3316 #define _syscall0(type, name) \
3317 type LSS_NAME(name)(void) { \
3318 LSS_BODY(type, name); \
3319 }
3320 #undef _syscall1
3321 #define _syscall1(type, name, type1, arg1) \
3322 type LSS_NAME(name)(type1 arg1) { \
3323 LSS_REG(2, arg1); \
3324 LSS_BODY(type, name, "0"(__r2)); \
3325 }
3326 #undef _syscall2
3327 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3328 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3329 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3330 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3331 }
3332 #undef _syscall3
3333 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3334 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3335 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3336 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3337 }
3338 #undef _syscall4
3339 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3340 type4, arg4) \
3341 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3342 type4 arg4) { \
3343 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3344 LSS_REG(5, arg4); \
3345 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3346 "d"(__r5)); \
3347 }
3348 #undef _syscall5
3349 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3350 type4, arg4, type5, arg5) \
3351 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3352 type4 arg4, type5 arg5) { \
3353 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3354 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3355 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3356 "d"(__r5), "d"(__r6)); \
3357 }
3358 #undef _syscall6
3359 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3360 type4, arg4, type5, arg5, type6, arg6) \
3361 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3362 type4 arg4, type5 arg5, type6 arg6) { \
3363 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3364 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3365 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3366 "d"(__r5), "d"(__r6), "d"(__r7)); \
3367 }
3368 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3369 int flags, void *arg, int *parent_tidptr,
3370 void *newtls, int *child_tidptr) {
3371 long __ret;
3372 {
3373 register int (*__fn)(void *) __asm__ ("r1") = fn;
3374 register void *__cstack __asm__ ("r2") = child_stack;
3375 register int __flags __asm__ ("r3") = flags;
3376 register void *__arg __asm__ ("r0") = arg;
3377 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3378 register void *__newtls __asm__ ("r6") = newtls;
3379 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3380 __asm__ __volatile__ (
3381 #ifndef __s390x__
3382 /* arg already in r0 */
3383 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3384 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3385 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3386 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3387 /* flags already in r3 */
3388 /* parent_tidptr already in r4 */
3389 /* child_tidptr already in r5 */
3390 /* newtls already in r6 */
3391 "svc %2\n\t" /* invoke clone syscall */
3392 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3393 "jnz 1f\n\t" /* return to parent if non-zero */
3394 /* start child thread */
3395 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3396 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3397 "xc 0(4,%%r15), 0(%%r15)\n\t"
3398 "basr %%r14, %4\n\t" /* jump to fn */
3399 "svc %3\n" /* invoke exit syscall */
3400 "1:\n"
3401 #else
3402 /* arg already in r0 */
3403 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3404 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3405 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3406 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3407 /* flags already in r3 */
3408 /* parent_tidptr already in r4 */
3409 /* child_tidptr already in r5 */
3410 /* newtls already in r6 */
3411 "svc %2\n\t" /* invoke clone syscall */
3412 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3413 "jnz 1f\n\t" /* return to parent if non-zero */
3414 /* start child thread */
3415 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3416 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3417 "xc 0(8,%%r15), 0(%%r15)\n\t"
3418 "basr %%r14, %4\n\t" /* jump to fn */
3419 "svc %3\n" /* invoke exit syscall */
3420 "1:\n"
3421 #endif
3422 : "=r" (__ret)
3423 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3424 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3425 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3426 : "cc", "r14", "memory"
3427 );
3428 }
3429 LSS_RETURN(int, __ret);
3430 }
Andreas Schwab1d387f42022-02-15 16:21:13 +01003431 #elif defined(__riscv) && __riscv_xlen == 64
3432 #undef LSS_REG
3433 #define LSS_REG(r,a) register int64_t __r##r __asm__("a"#r) = (int64_t)a
3434 #undef LSS_BODY
3435 #define LSS_BODY(type,name,args...) \
3436 register int64_t __res_a0 __asm__("a0"); \
3437 register int64_t __a7 __asm__("a7") = __NR_##name; \
3438 int64_t __res; \
3439 __asm__ __volatile__ ("scall\n" \
3440 : "=r"(__res_a0) \
3441 : "r"(__a7) , ## args \
3442 : "memory"); \
3443 __res = __res_a0; \
3444 LSS_RETURN(type, __res)
3445 #undef _syscall0
3446 #define _syscall0(type, name) \
3447 type LSS_NAME(name)(void) { \
3448 LSS_BODY(type, name); \
3449 }
3450 #undef _syscall1
3451 #define _syscall1(type, name, type1, arg1) \
3452 type LSS_NAME(name)(type1 arg1) { \
3453 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
3454 }
3455 #undef _syscall2
3456 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3457 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3458 LSS_REG(0, arg1); LSS_REG(1, arg2); \
3459 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
3460 }
3461 #undef _syscall3
3462 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3463 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3464 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3465 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
3466 }
3467 #undef _syscall4
3468 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
3469 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3470 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3471 LSS_REG(3, arg4); \
3472 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
3473 }
3474 #undef _syscall5
3475 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3476 type5,arg5) \
3477 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3478 type5 arg5) { \
3479 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3480 LSS_REG(3, arg4); LSS_REG(4, arg5); \
3481 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3482 "r"(__r4)); \
3483 }
3484 #undef _syscall6
3485 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
3486 type5,arg5,type6,arg6) \
3487 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3488 type5 arg5, type6 arg6) { \
3489 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
3490 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
3491 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
3492 "r"(__r4), "r"(__r5)); \
3493 }
3494
3495 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3496 int flags, void *arg, int *parent_tidptr,
3497 void *newtls, int *child_tidptr) {
3498 int64_t __res;
3499 {
3500 register int64_t __res_a0 __asm__("a0");
3501 register uint64_t __flags __asm__("a0") = flags;
3502 register void *__stack __asm__("a1") = child_stack;
3503 register void *__ptid __asm__("a2") = parent_tidptr;
3504 register void *__tls __asm__("a3") = newtls;
3505 register int *__ctid __asm__("a4") = child_tidptr;
3506 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
3507 * used by the child.
3508 */
3509 "addi %2,%2,-16\n"
3510 "sd %1, 0(%2)\n"
3511 "sd %4, 8(%2)\n"
3512
3513 /* %a0 = syscall(%a0 = flags,
3514 * %a1 = child_stack,
3515 * %a2 = parent_tidptr,
3516 * %a3 = newtls,
3517 * %a4 = child_tidptr)
3518 */
3519 "li a7, %8\n"
3520 "scall\n"
3521
3522 /* if (%a0 != 0)
3523 * return %a0;
3524 */
3525 "bnez %0, 1f\n"
3526
3527 /* In the child, now. Call "fn(arg)".
3528 */
3529 "ld a1, 0(sp)\n"
3530 "ld a0, 8(sp)\n"
3531 "jalr a1\n"
3532
3533 /* Call _exit(%a0).
3534 */
3535 "li a7, %9\n"
3536 "scall\n"
3537 "1:\n"
3538 : "=r" (__res_a0)
3539 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
3540 "r"(__ptid), "r"(__tls), "r"(__ctid),
3541 "i"(__NR_clone), "i"(__NR_exit)
3542 : "cc", "memory");
3543 __res = __res_a0;
3544 }
3545 LSS_RETURN(int, __res);
3546 }
Konstantin Ivlev8007b272021-01-27 18:27:42 +03003547 #elif defined(__e2k__)
3548
3549 #undef _LSS_BODY
3550 #define _LSS_BODY(nr, type, name, ...) \
3551 register unsigned long long __res; \
3552 __asm__ __volatile__ \
3553 ( \
3554 "{\n\t" \
3555 " sdisp %%ctpr1, 0x3\n\t" \
3556 " addd, s 0x0, %[sys_num], %%b[0]\n\t" \
3557 LSS_BODY_ASM##nr \
3558 "}\n\t" \
3559 "{\n\t" \
3560 " call %%ctpr1, wbs = %#\n\t" \
3561 "}\n\t" \
3562 "{\n\t" \
3563 " addd, s 0x0, %%b[0], %[res]\n\t" \
3564 "}\n\t" \
3565 : [res] "=r" (__res) \
3566 : \
3567 LSS_BODY_ARG##nr(__VA_ARGS__) \
3568 [sys_num] "ri" (__NR_##name) \
3569 : "ctpr1", "ctpr2", "ctpr3", \
3570 "b[0]", "b[1]", "b[2]", "b[3]", \
3571 "b[4]", "b[5]", "b[6]", "b[7]" \
3572 ); \
3573 LSS_RETURN(type, __res);
3574
3575 #undef LSS_BODY
3576 #define LSS_BODY(nr, type, name, args...) \
3577 _LSS_BODY(nr, type, name, ## args)
3578
3579 #undef LSS_BODY_ASM0
3580 #undef LSS_BODY_ASM1
3581 #undef LSS_BODY_ASM2
3582 #undef LSS_BODY_ASM3
3583 #undef LSS_BODY_ASM4
3584 #undef LSS_BODY_ASM5
3585 #undef LSS_BODY_ASM6
3586
3587 #define LSS_BODY_ASM0
3588 #define LSS_BODY_ASM1 LSS_BODY_ASM0 \
3589 " addd, s 0x0, %[arg1], %%b[1]\n\t"
3590 #define LSS_BODY_ASM2 LSS_BODY_ASM1 \
3591 " addd, s 0x0, %[arg2], %%b[2]\n\t"
3592 #define LSS_BODY_ASM3 LSS_BODY_ASM2 \
3593 " addd, s 0x0, %[arg3], %%b[3]\n\t"
3594 #define LSS_BODY_ASM4 LSS_BODY_ASM3 \
3595 " addd, s 0x0, %[arg4], %%b[4]\n\t"
3596 #define LSS_BODY_ASM5 LSS_BODY_ASM4 \
3597 " addd, s 0x0, %[arg5], %%b[5]\n\t"
3598 #define LSS_BODY_ASM6 LSS_BODY_ASM5 \
3599 "}\n\t" \
3600 "{\n\t" \
3601 " addd, s 0x0, %[arg6], %%b[6]\n\t"
3602
3603 #undef LSS_SYSCALL_ARG
3604 #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a))
3605
3606 #undef LSS_BODY_ARG0
3607 #undef LSS_BODY_ARG1
3608 #undef LSS_BODY_ARG2
3609 #undef LSS_BODY_ARG3
3610 #undef LSS_BODY_ARG4
3611 #undef LSS_BODY_ARG5
3612 #undef LSS_BODY_ARG6
3613
3614 #define LSS_BODY_ARG0()
3615 #define LSS_BODY_ARG1(_arg1) \
3616 [arg1] "ri" LSS_SYSCALL_ARG(_arg1),
3617 #define LSS_BODY_ARG2(_arg1, _arg2) \
3618 LSS_BODY_ARG1(_arg1) \
3619 [arg2] "ri" LSS_SYSCALL_ARG(_arg2),
3620 #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3621 LSS_BODY_ARG2(_arg1, _arg2) \
3622 [arg3] "ri" LSS_SYSCALL_ARG(_arg3),
3623 #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3624 LSS_BODY_ARG3(_arg1, _arg2, _arg3) \
3625 [arg4] "ri" LSS_SYSCALL_ARG(_arg4),
3626 #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3627 LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \
3628 [arg5] "ri" LSS_SYSCALL_ARG(_arg5),
3629 #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \
3630 LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \
3631 [arg6] "ri" LSS_SYSCALL_ARG(_arg6),
3632
3633 #undef _syscall0
3634 #define _syscall0(type, name) \
3635 type LSS_NAME(name)(void) { \
3636 LSS_BODY(0, type, name); \
3637 }
3638
3639 #undef _syscall1
3640 #define _syscall1(type, name, type1, arg1) \
3641 type LSS_NAME(name)(type1 arg1) { \
3642 LSS_BODY(1, type, name, arg1) \
3643 }
3644
3645 #undef _syscall2
3646 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3647 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3648 LSS_BODY(2, type, name, arg1, arg2) \
3649 }
3650
3651 #undef _syscall3
3652 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3653 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3654 LSS_BODY(3, type, name, arg1, arg2, arg3) \
3655 }
3656
3657 #undef _syscall4
3658 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3659 type4, arg4) \
3660 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3661 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \
3662 }
3663
3664 #undef _syscall5
3665 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3666 type4, arg4, type5, arg5) \
3667 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3668 type5 arg5) { \
3669 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \
3670 }
3671
3672 #undef _syscall6
3673 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3674 type4, arg4, type5, arg5, type6, arg6) \
3675 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3676 type5 arg5, type6 arg6) { \
3677 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \
3678 }
3679
3680 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3681 int flags, void *arg, int *parent_tidptr,
3682 void *newtls, int *child_tidptr) {
3683 unsigned long long __res;
3684
3685 __asm__ __volatile__ (
3686 "{\n\t"
3687 " addd,s 0x0, %[nr_clone], %%b[0]\n\t"
3688 " addd,s 0x0, %[flags], %%db[1]\n\t"
3689 " addd,s 0x0, %[child_stack], %%db[2]\n\t"
3690 " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t"
3691 " addd,s 0x0, %[child_tidptr], %%db[4]\n\t"
3692 " addd,s 0x0, %[newtls], %%db[5]\n\t"
3693 "}\n\t"
3694 /* if (fn == NULL)
3695 * return -EINVAL;
3696 */
3697
3698 "{\n\t"
3699 " disp %%ctpr1, .L1\n\t"
3700 "}\n\t"
3701 "{\n\t"
3702 " cmpesb,s 0x0, %[fn], %%pred0\n\t"
3703 "}\n\t"
3704 "{\n\t"
3705 " ct %%ctpr1 ? %%pred0\n\t"
3706 "}\n\t"
3707
3708 /* if (child_stack == NULL)
3709 * return -EINVAL;
3710 */
3711 "{\n\t"
3712 " cmpesb,s 0x0, %%db[2], %%pred0\n\t"
3713 "}\n\t"
3714 "{\n\t"
3715 " ct %%ctpr1 ? %%pred0\n\t"
3716 "}\n\t"
3717
3718 /* b[0] = syscall(%b[0] = __NR_clone,
3719 * %db[1] = flags,
3720 * %db[2] = child_stack,
3721 * %db[3] = parent_tidptr,
3722 * %db[4] = child_tidptr,
3723 * %db[5] = newtls)
3724 */
3725 "{\n\t"
3726 " sdisp %%ctpr1, 0x3\n\t"
3727 "}\n\t"
3728 "{\n\t"
3729 " call %%ctpr1, wbs = %#\n\t"
3730 "}\n\t"
3731
3732 /* if (%[b0] != 0)
3733 * return %b[0];
3734 */
3735 "{\n\t"
3736 " disp %%ctpr1, .L2\n\t"
3737 " cmpesb,s 0x0, %%b[0], %%pred0\n\t"
3738 "}\n\t"
3739 "{\n\t"
3740 " ct %%ctpr1 ? ~%%pred0\n\t"
3741 "}\n\t"
3742 /* In the child, now. Call "fn(arg)".
3743 */
3744
3745 "{\n\t"
3746 " movtd,s %[fn], %%ctpr1\n\t"
3747 "}\n\t"
3748 "{\n\t"
3749 " addd,s 0x0, %[arg], %%db[0]\n\t"
3750 "}\n\t"
3751 "{\n\t"
3752 " call %%ctpr1, wbs = %#\n\t"
3753 "}\n\t"
3754 /* Call _exit(%b[0]).
3755 */
3756
3757 "{\n\t"
3758 " sdisp %%ctpr1, 0x3\n\t"
3759 " addd,s 0x0, %%b[0], %%b[1]\n\t"
3760 "}\n\t"
3761 "{\n\t"
3762 " addd,s 0x0, %[nr_exit], %%b[0]\n\t"
3763 "}\n\t"
3764 "{\n\t"
3765 " call %%ctpr1, wbs = %#\n\t"
3766 "}\n\t"
3767 "{\n\t"
3768 " disp %%ctpr1, .L2\n\t"
3769 " adds,s 0x0, 0x0, %%b[0]\n\t"
3770 "}\n\t"
3771 "{\n\t"
3772 " ct %%ctpr1\n\t"
3773 "}\n\t"
3774 ".L1:\n\t"
3775 "{\n\t"
3776 " addd,s 0x0, %[einval], %%b[0]\n\t"
3777 "}\n\t"
3778 ".L2:\n\t"
3779 "{\n\t"
3780 " addd,s 0x0, %%b[0], %[res]\n\t"
3781 "}\n\t"
3782 : [res] "=r" LSS_SYSCALL_ARG(__res)
3783 : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone)
3784 [arg] "ri" LSS_SYSCALL_ARG(arg)
3785 [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit)
3786 [flags] "ri" LSS_SYSCALL_ARG(flags)
3787 [child_stack] "ri" LSS_SYSCALL_ARG(child_stack)
3788 [parent_tidptr] "ri"
3789 LSS_SYSCALL_ARG(parent_tidptr)
3790 [newtls] "ri" LSS_SYSCALL_ARG(newtls)
3791 [child_tidptr] "ri"
3792 LSS_SYSCALL_ARG(child_tidptr)
3793 [fn] "ri" LSS_SYSCALL_ARG(fn)
3794 [einval] "ri" LSS_SYSCALL_ARG(-EINVAL)
3795 : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]",
3796 "b[4]", "b[5]", "pred0");
3797 LSS_RETURN(int, __res);
3798 }
3799
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003800 #endif
3801 #define __NR__exit __NR_exit
3802 #define __NR__gettid __NR_gettid
3803 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00003804 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003805 LSS_INLINE _syscall1(int, chdir, const char *,p)
3806 LSS_INLINE _syscall1(int, close, int, f)
3807 LSS_INLINE _syscall2(int, clock_getres, int, c,
3808 struct kernel_timespec*, t)
3809 LSS_INLINE _syscall2(int, clock_gettime, int, c,
3810 struct kernel_timespec*, t)
3811 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003812 #if defined(__NR_dup2)
3813 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003814 LSS_INLINE _syscall2(int, dup2, int, s,
3815 int, d)
3816 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003817 #if defined(__NR_dup3)
3818 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3819 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003820 LSS_INLINE _syscall3(int, execve, const char*, f,
3821 const char*const*,a,const char*const*, e)
3822 LSS_INLINE _syscall1(int, _exit, int, e)
3823 LSS_INLINE _syscall1(int, exit_group, int, e)
3824 LSS_INLINE _syscall3(int, fcntl, int, f,
3825 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003826 #if defined(__NR_fork)
3827 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003828 LSS_INLINE _syscall0(pid_t, fork)
3829 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003830 LSS_INLINE _syscall2(int, fstat, int, f,
3831 struct kernel_stat*, b)
3832 LSS_INLINE _syscall2(int, fstatfs, int, f,
3833 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003834 #if defined(__x86_64__)
3835 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3836 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
3837 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
3838 }
3839 #else
3840 LSS_INLINE _syscall2(int, ftruncate, int, f,
3841 off_t, l)
3842 #endif
Mike Frysinger171a36a2019-01-26 23:05:43 -05003843 LSS_INLINE _syscall6(int, futex, int*, u,
3844 int, o, int, v,
3845 struct kernel_timespec*, t,
3846 int*, u2, int, v2)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003847 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003848 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003849 LSS_INLINE _syscall3(int, getdents64, int, f,
3850 struct kernel_dirent64*, d, int, c)
3851 LSS_INLINE _syscall0(gid_t, getegid)
3852 LSS_INLINE _syscall0(uid_t, geteuid)
Doug Kwan32a80cd2022-07-01 17:52:39 +00003853 LSS_INLINE _syscall2(int, getitimer, int, w,
3854 struct kernel_itimerval*, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003855 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003856 LSS_INLINE _syscall0(pid_t, getpgrp)
3857 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003858 LSS_INLINE _syscall0(pid_t, getpid)
3859 LSS_INLINE _syscall0(pid_t, getppid)
3860 LSS_INLINE _syscall2(int, getpriority, int, a,
3861 int, b)
3862 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
3863 gid_t *, e, gid_t *, s)
3864 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
3865 uid_t *, e, uid_t *, s)
3866#if !defined(__ARM_EABI__)
3867 LSS_INLINE _syscall2(int, getrlimit, int, r,
3868 struct kernel_rlimit*, l)
3869#endif
3870 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
3871 LSS_INLINE _syscall0(pid_t, _gettid)
3872 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
3873 void*, tz)
3874 LSS_INLINE _syscall5(int, setxattr, const char *,p,
3875 const char *, n, const void *,v,
3876 size_t, s, int, f)
3877 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
3878 const char *, n, const void *,v,
3879 size_t, s, int, f)
3880 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
3881 const char *, n, void *, v, size_t, s)
3882 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
3883 const char *, n, void *, v, size_t, s)
3884 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
3885 char *, l, size_t, s)
3886 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
3887 char *, l, size_t, s)
3888 LSS_INLINE _syscall3(int, ioctl, int, d,
3889 int, r, void *, a)
3890 LSS_INLINE _syscall2(int, ioprio_get, int, which,
3891 int, who)
3892 LSS_INLINE _syscall3(int, ioprio_set, int, which,
3893 int, who, int, ioprio)
3894 LSS_INLINE _syscall2(int, kill, pid_t, p,
3895 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003896 #if defined(__x86_64__)
3897 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3898 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
3899 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3900 LSS_SYSCALL_ARG(w));
3901 }
3902 #else
3903 LSS_INLINE _syscall3(off_t, lseek, int, f,
3904 off_t, o, int, w)
3905 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003906 LSS_INLINE _syscall2(int, munmap, void*, s,
3907 size_t, l)
3908 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
3909 unsigned long, n, void **,g, int *, d,
3910 int *, s, int, f)
3911 LSS_INLINE _syscall3(int, mprotect, const void *,a,
3912 size_t, l, int, p)
3913 LSS_INLINE _syscall5(void*, _mremap, void*, o,
3914 size_t, os, size_t, ns,
3915 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003916 #if defined(__NR_open)
3917 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003918 LSS_INLINE _syscall3(int, open, const char*, p,
3919 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003920 #endif
3921 #if defined(__NR_poll)
3922 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003923 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
3924 unsigned int, n, int, t)
3925 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003926 #if defined(__NR_ppoll)
3927 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
3928 unsigned int, n, const struct kernel_timespec *, t,
3929 const struct kernel_sigset_t *, sigmask, size_t, s)
3930 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00003931 LSS_INLINE _syscall5(int, prctl, int, option,
3932 unsigned long, arg2,
3933 unsigned long, arg3,
3934 unsigned long, arg4,
3935 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003936 LSS_INLINE _syscall4(long, ptrace, int, r,
3937 pid_t, p, void *, a, void *, d)
3938 #if defined(__NR_quotactl)
3939 // Defined on x86_64 / i386 only
3940 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
3941 int, id, caddr_t, addr)
3942 #endif
3943 LSS_INLINE _syscall3(ssize_t, read, int, f,
3944 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003945 #if defined(__NR_readlink)
3946 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003947 LSS_INLINE _syscall3(int, readlink, const char*, p,
3948 char*, b, size_t, s)
3949 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003950 #if defined(__NR_readlinkat)
3951 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
3952 size_t, s)
3953 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003954 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
3955 const struct kernel_sigaction*, a,
3956 struct kernel_sigaction*, o, size_t, c)
3957 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
3958 size_t, c)
3959 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
3960 const struct kernel_sigset_t*, s,
3961 struct kernel_sigset_t*, o, size_t, c)
3962 LSS_INLINE _syscall2(int, rt_sigsuspend,
3963 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08003964 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
3965 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003966 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
3967 unsigned int, l, unsigned long *, m)
3968 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
3969 unsigned int, l, unsigned long *, m)
3970 LSS_INLINE _syscall0(int, sched_yield)
3971 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
3972 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
3973 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
3974 LSS_INLINE _syscall1(int, setuid, uid_t, u)
3975 LSS_INLINE _syscall1(int, setgid, gid_t, g)
Doug Kwan32a80cd2022-07-01 17:52:39 +00003976 LSS_INLINE _syscall3(int, setitimer, int, w,
3977 const struct kernel_itimerval*, n,
3978 struct kernel_itimerval*, o)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003979 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
3980 pid_t, g)
3981 LSS_INLINE _syscall3(int, setpriority, int, a,
3982 int, b, int, p)
3983 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
3984 gid_t, e, gid_t, s)
3985 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
3986 uid_t, e, uid_t, s)
3987 LSS_INLINE _syscall2(int, setrlimit, int, r,
3988 const struct kernel_rlimit*, l)
3989 LSS_INLINE _syscall0(pid_t, setsid)
3990 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
3991 const stack_t*, o)
3992 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003993 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003994 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003995 #if defined(__NR_stat)
Matthew Denton92a65a82021-04-01 13:00:07 -07003996 // stat and lstat are polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003997 LSS_INLINE _syscall2(int, stat, const char*, f,
3998 struct kernel_stat*, b)
3999 #endif
Matthew Denton92a65a82021-04-01 13:00:07 -07004000 #if defined(__NR_lstat)
4001 LSS_INLINE _syscall2(int, lstat, const char*, f,
4002 struct kernel_stat*, b)
4003 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004004 LSS_INLINE _syscall2(int, statfs, const char*, f,
4005 struct kernel_statfs*, b)
4006 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
4007 pid_t, t, int, s)
4008 LSS_INLINE _syscall2(int, tkill, pid_t, p,
4009 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004010 #if defined(__NR_unlink)
4011 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004012 LSS_INLINE _syscall1(int, unlink, const char*, f)
4013 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004014 LSS_INLINE _syscall3(ssize_t, write, int, f,
4015 const void *, b, size_t, c)
4016 LSS_INLINE _syscall3(ssize_t, writev, int, f,
4017 const struct kernel_iovec*, v, size_t, c)
4018 #if defined(__NR_getcpu)
4019 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00004020 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004021 #endif
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004022 #if defined(__x86_64__) || defined(__e2k__) || \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004023 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
4024 LSS_INLINE _syscall3(int, recvmsg, int, s,
4025 struct kernel_msghdr*, m, int, f)
4026 LSS_INLINE _syscall3(int, sendmsg, int, s,
4027 const struct kernel_msghdr*, m, int, f)
4028 LSS_INLINE _syscall6(int, sendto, int, s,
4029 const void*, m, size_t, l,
4030 int, f,
4031 const struct kernel_sockaddr*, a, int, t)
4032 LSS_INLINE _syscall2(int, shutdown, int, s,
4033 int, h)
4034 LSS_INLINE _syscall3(int, socket, int, d,
4035 int, t, int, p)
4036 LSS_INLINE _syscall4(int, socketpair, int, d,
4037 int, t, int, p, int*, s)
4038 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004039 #if defined(__NR_fadvise64)
4040 #if defined(__x86_64__)
4041 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4042 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
4043 int advice) {
4044 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
4045 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
4046 }
4047 #else
4048 LSS_INLINE _syscall4(int, fadvise64,
4049 int, fd, loff_t, offset, loff_t, len, int, advice)
4050 #endif
4051 #elif defined(__i386__)
4052 #define __NR__fadvise64_64 __NR_fadvise64_64
4053 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
4054 unsigned, offset_lo, unsigned, offset_hi,
4055 unsigned, len_lo, unsigned, len_hi,
4056 int, advice)
4057
4058 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4059 loff_t len, int advice) {
4060 return LSS_NAME(_fadvise64_64)(fd,
4061 (unsigned)offset, (unsigned)(offset >>32),
4062 (unsigned)len, (unsigned)(len >> 32),
4063 advice);
4064 }
4065
4066 #elif defined(__s390__) && !defined(__s390x__)
4067 #define __NR__fadvise64_64 __NR_fadvise64_64
4068 struct kernel_fadvise64_64_args {
4069 int fd;
4070 long long offset;
4071 long long len;
4072 int advice;
4073 };
4074
4075 LSS_INLINE _syscall1(int, _fadvise64_64,
4076 struct kernel_fadvise64_64_args *args)
4077
4078 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
4079 loff_t len, int advice) {
4080 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
4081 return LSS_NAME(_fadvise64_64)(&args);
4082 }
4083 #endif
4084 #if defined(__NR_fallocate)
4085 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00004086 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4087 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
4088 loff_t len) {
4089 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
4090 (uint64_t)(offset), (uint64_t)(len));
4091 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08004092 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
4093 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
4094 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
4095 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04004096 #define __NR__fallocate __NR_fallocate
4097 LSS_INLINE _syscall6(int, _fallocate, int, fd,
4098 int, mode,
4099 unsigned, offset_lo, unsigned, offset_hi,
4100 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004101
Bryan Chan3f6478a2016-06-14 08:38:17 -04004102 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
4103 loff_t offset, loff_t len) {
4104 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
4105 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
4106 }
4107 #else
4108 LSS_INLINE _syscall4(int, fallocate,
4109 int, f, int, mode, loff_t, offset, loff_t, len)
4110 #endif
4111 #endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07004112 #if defined(__NR_getrandom)
4113 LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length,
4114 unsigned int, flags)
4115 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004116 #if defined(__NR_newfstatat)
4117 LSS_INLINE _syscall4(int, newfstatat, int, d,
4118 const char *, p,
4119 struct kernel_stat*, b, int, f)
4120 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004121 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004122 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4123 gid_t *egid,
4124 gid_t *sgid) {
4125 return LSS_NAME(getresgid)(rgid, egid, sgid);
4126 }
4127
4128 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4129 uid_t *euid,
4130 uid_t *suid) {
4131 return LSS_NAME(getresuid)(ruid, euid, suid);
4132 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004133
4134 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4135 return LSS_NAME(setfsgid)(gid);
4136 }
4137
4138 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4139 return LSS_NAME(setfsuid)(uid);
4140 }
4141
4142 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4143 return LSS_NAME(setresgid)(rgid, egid, sgid);
4144 }
4145
4146 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4147 return LSS_NAME(setresuid)(ruid, euid, suid);
4148 }
4149
4150 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4151 const struct kernel_sigaction *act,
4152 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04004153 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004154 /* On x86_64, the kernel requires us to always set our own
4155 * SA_RESTORER in order to be able to return from a signal handler.
4156 * This function must have a "magic" signature that the "gdb"
4157 * (and maybe the kernel?) can recognize.
4158 */
4159 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
4160 struct kernel_sigaction a = *act;
4161 a.sa_flags |= SA_RESTORER;
4162 a.sa_restorer = LSS_NAME(restore_rt)();
4163 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
4164 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04004165 } else
4166 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004167 return LSS_NAME(rt_sigaction)(signum, act, oldact,
4168 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004169 }
4170
4171 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4172 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4173 }
4174
Joshua Peraza726d71e2019-11-13 12:21:13 -08004175 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4176 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4177 }
4178 #endif
4179 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004180 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
4181 const struct kernel_sigset_t *set,
4182 struct kernel_sigset_t *oldset) {
4183 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
4184 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08004185 #endif
4186 #if defined(__NR_rt_sigtimedwait)
4187 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
4188 siginfo_t *info,
4189 const struct timespec *timeout) {
4190 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004191 }
4192 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004193 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004194 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
4195 int*, s, int, o,
4196 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004197 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004198 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004199 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004200 #endif
4201 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004202 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
4203 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004204 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4205 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004206 #define __NR__getresgid32 __NR_getresgid32
4207 #define __NR__getresuid32 __NR_getresuid32
4208 #define __NR__setfsgid32 __NR_setfsgid32
4209 #define __NR__setfsuid32 __NR_setfsuid32
4210 #define __NR__setresgid32 __NR_setresgid32
4211 #define __NR__setresuid32 __NR_setresuid32
4212#if defined(__ARM_EABI__)
4213 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
4214 struct kernel_rlimit*, l)
4215#endif
4216 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
4217 gid_t *, e, gid_t *, s)
4218 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
4219 uid_t *, e, uid_t *, s)
4220 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
4221 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
4222 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
4223 gid_t, e, gid_t, s)
4224 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
4225 uid_t, e, uid_t, s)
4226
4227 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
4228 gid_t *egid,
4229 gid_t *sgid) {
4230 int rc;
4231 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
4232 LSS_ERRNO == ENOSYS) {
4233 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
4234 return EFAULT;
4235 }
4236 // Clear the high bits first, since getresgid only sets 16 bits
4237 *rgid = *egid = *sgid = 0;
4238 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
4239 }
4240 return rc;
4241 }
4242
4243 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
4244 uid_t *euid,
4245 uid_t *suid) {
4246 int rc;
4247 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
4248 LSS_ERRNO == ENOSYS) {
4249 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
4250 return EFAULT;
4251 }
4252 // Clear the high bits first, since getresuid only sets 16 bits
4253 *ruid = *euid = *suid = 0;
4254 rc = LSS_NAME(getresuid)(ruid, euid, suid);
4255 }
4256 return rc;
4257 }
4258
4259 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
4260 int rc;
4261 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
4262 LSS_ERRNO == ENOSYS) {
4263 if ((unsigned int)gid & ~0xFFFFu) {
4264 rc = EINVAL;
4265 } else {
4266 rc = LSS_NAME(setfsgid)(gid);
4267 }
4268 }
4269 return rc;
4270 }
4271
4272 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
4273 int rc;
4274 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
4275 LSS_ERRNO == ENOSYS) {
4276 if ((unsigned int)uid & ~0xFFFFu) {
4277 rc = EINVAL;
4278 } else {
4279 rc = LSS_NAME(setfsuid)(uid);
4280 }
4281 }
4282 return rc;
4283 }
4284
4285 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
4286 int rc;
4287 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
4288 LSS_ERRNO == ENOSYS) {
4289 if ((unsigned int)rgid & ~0xFFFFu ||
4290 (unsigned int)egid & ~0xFFFFu ||
4291 (unsigned int)sgid & ~0xFFFFu) {
4292 rc = EINVAL;
4293 } else {
4294 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
4295 }
4296 }
4297 return rc;
4298 }
4299
4300 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
4301 int rc;
4302 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
4303 LSS_ERRNO == ENOSYS) {
4304 if ((unsigned int)ruid & ~0xFFFFu ||
4305 (unsigned int)euid & ~0xFFFFu ||
4306 (unsigned int)suid & ~0xFFFFu) {
4307 rc = EINVAL;
4308 } else {
4309 rc = LSS_NAME(setresuid)(ruid, euid, suid);
4310 }
4311 }
4312 return rc;
4313 }
4314 #endif
4315 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
4316 memset(&set->sig, 0, sizeof(set->sig));
4317 return 0;
4318 }
4319
4320 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
4321 memset(&set->sig, -1, sizeof(set->sig));
4322 return 0;
4323 }
4324
4325 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
4326 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004327 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004328 LSS_ERRNO = EINVAL;
4329 return -1;
4330 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004331 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4332 |= 1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004333 return 0;
4334 }
4335 }
4336
4337 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
4338 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004339 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004340 LSS_ERRNO = EINVAL;
4341 return -1;
4342 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004343 set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))]
4344 &= ~(1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004345 return 0;
4346 }
4347 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004348
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004349 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
4350 int signum) {
Peter Kasting880985f2022-06-29 21:17:55 +00004351 if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004352 LSS_ERRNO = EINVAL;
4353 return -1;
4354 } else {
Peter Kasting880985f2022-06-29 21:17:55 +00004355 return !!(set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] &
4356 (1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])))));
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004357 }
4358 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04004359 #if defined(__i386__) || \
4360 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4361 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4362 defined(__PPC__) || \
Konstantin Ivlev8007b272021-01-27 18:27:42 +03004363 (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004364 #define __NR__sigaction __NR_sigaction
4365 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004366 #define __NR__sigsuspend __NR_sigsuspend
4367 #define __NR__socketcall __NR_socketcall
4368 LSS_INLINE _syscall2(int, fstat64, int, f,
4369 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00004370 LSS_INLINE _syscall5(int, _llseek, uint, fd,
4371 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004372 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04004373#if defined(__s390__) && !defined(__s390x__)
4374 /* On s390, mmap2() arguments are passed in memory. */
4375 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
4376 off_t o) {
4377 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4378 (unsigned long) p, (unsigned long) f,
4379 (unsigned long) d, (unsigned long) o };
4380 LSS_REG(2, buf);
4381 LSS_BODY(void*, mmap2, "0"(__r2));
4382 }
4383#else
4384 #define __NR__mmap2 __NR_mmap2
4385 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004386 size_t, l, int, p,
4387 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04004388 off_t, o)
4389#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004390 LSS_INLINE _syscall3(int, _sigaction, int, s,
4391 const struct kernel_old_sigaction*, a,
4392 struct kernel_old_sigaction*, o)
4393 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004394 #ifdef __PPC__
4395 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
4396 #else
4397 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
4398 int, b,
4399 unsigned long, s)
4400 #endif
4401 LSS_INLINE _syscall2(int, stat64, const char *, p,
4402 struct kernel_stat64 *, b)
4403
4404 LSS_INLINE int LSS_NAME(sigaction)(int signum,
4405 const struct kernel_sigaction *act,
4406 struct kernel_sigaction *oldact) {
4407 int old_errno = LSS_ERRNO;
4408 int rc;
4409 struct kernel_sigaction a;
4410 if (act != NULL) {
4411 a = *act;
4412 #ifdef __i386__
4413 /* On i386, the kernel requires us to always set our own
4414 * SA_RESTORER when using realtime signals. Otherwise, it does not
4415 * know how to return from a signal handler. This function must have
4416 * a "magic" signature that the "gdb" (and maybe the kernel?) can
4417 * recognize.
4418 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
4419 * using non-realtime signals.
4420 *
4421 * TODO: Test whether ARM needs a restorer
4422 */
4423 if (!(a.sa_flags & SA_RESTORER)) {
4424 a.sa_flags |= SA_RESTORER;
4425 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
4426 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
4427 }
4428 #endif
4429 }
4430 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
4431 (KERNEL_NSIG+7)/8);
4432 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4433 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
4434 if (!act) {
4435 ptr_a = NULL;
4436 } else {
4437 oa.sa_handler_ = act->sa_handler_;
4438 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
4439 #ifndef __mips__
4440 oa.sa_restorer = act->sa_restorer;
4441 #endif
4442 oa.sa_flags = act->sa_flags;
4443 }
4444 if (!oldact) {
4445 ptr_oa = NULL;
4446 }
4447 LSS_ERRNO = old_errno;
4448 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
4449 if (rc == 0 && oldact) {
4450 if (act) {
4451 memcpy(oldact, act, sizeof(*act));
4452 } else {
4453 memset(oldact, 0, sizeof(*oldact));
4454 }
4455 oldact->sa_handler_ = ptr_oa->sa_handler_;
4456 oldact->sa_flags = ptr_oa->sa_flags;
4457 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4458 #ifndef __mips__
4459 oldact->sa_restorer = ptr_oa->sa_restorer;
4460 #endif
4461 }
4462 }
4463 return rc;
4464 }
4465
4466 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4467 int old_errno = LSS_ERRNO;
4468 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4469 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4470 LSS_ERRNO = old_errno;
4471 LSS_NAME(sigemptyset)(set);
4472 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4473 }
4474 return rc;
4475 }
4476
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004477 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4478 int olderrno = LSS_ERRNO;
4479 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4480 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4481 LSS_ERRNO = olderrno;
4482 rc = LSS_NAME(_sigsuspend)(
4483 #ifndef __PPC__
4484 set, 0,
4485 #endif
4486 set->sig[0]);
4487 }
4488 return rc;
4489 }
4490 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004491 #if defined(__i386__) || \
4492 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4493 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4494 defined(__PPC__) || \
4495 (defined(__s390__) && !defined(__s390x__))
4496 /* On these architectures, implement mmap() with mmap2(). */
4497 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4498 int64_t o) {
4499 if (o % 4096) {
4500 LSS_ERRNO = EINVAL;
4501 return (void *) -1;
4502 }
4503 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4504 }
4505 #elif defined(__s390x__)
4506 /* On s390x, mmap() arguments are passed in memory. */
4507 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4508 int64_t o) {
4509 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4510 (unsigned long) p, (unsigned long) f,
4511 (unsigned long) d, (unsigned long) o };
4512 LSS_REG(2, buf);
4513 LSS_BODY(void*, mmap, "0"(__r2));
4514 }
4515 #elif defined(__x86_64__)
4516 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4517 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4518 int64_t o) {
4519 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4520 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4521 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4522 }
4523 #else
4524 /* Remaining 64-bit architectures. */
4525 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4526 int, flags, int, fd, int64_t, offset)
4527 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004528 #if defined(__PPC__)
4529 #undef LSS_SC_LOADARGS_0
4530 #define LSS_SC_LOADARGS_0(dummy...)
4531 #undef LSS_SC_LOADARGS_1
4532 #define LSS_SC_LOADARGS_1(arg1) \
4533 __sc_4 = (unsigned long) (arg1)
4534 #undef LSS_SC_LOADARGS_2
4535 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4536 LSS_SC_LOADARGS_1(arg1); \
4537 __sc_5 = (unsigned long) (arg2)
4538 #undef LSS_SC_LOADARGS_3
4539 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4540 LSS_SC_LOADARGS_2(arg1, arg2); \
4541 __sc_6 = (unsigned long) (arg3)
4542 #undef LSS_SC_LOADARGS_4
4543 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4544 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4545 __sc_7 = (unsigned long) (arg4)
4546 #undef LSS_SC_LOADARGS_5
4547 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4548 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4549 __sc_8 = (unsigned long) (arg5)
4550 #undef LSS_SC_BODY
4551 #define LSS_SC_BODY(nr, type, opt, args...) \
4552 long __sc_ret, __sc_err; \
4553 { \
4554 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4555 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4556 register unsigned long __sc_4 __asm__ ("r4"); \
4557 register unsigned long __sc_5 __asm__ ("r5"); \
4558 register unsigned long __sc_6 __asm__ ("r6"); \
4559 register unsigned long __sc_7 __asm__ ("r7"); \
4560 register unsigned long __sc_8 __asm__ ("r8"); \
4561 LSS_SC_LOADARGS_##nr(args); \
4562 __asm__ __volatile__ \
4563 ("stwu 1, -48(1)\n\t" \
4564 "stw 4, 20(1)\n\t" \
4565 "stw 5, 24(1)\n\t" \
4566 "stw 6, 28(1)\n\t" \
4567 "stw 7, 32(1)\n\t" \
4568 "stw 8, 36(1)\n\t" \
4569 "addi 4, 1, 20\n\t" \
4570 "sc\n\t" \
4571 "mfcr %0" \
4572 : "=&r" (__sc_0), \
4573 "=&r" (__sc_3), "=&r" (__sc_4), \
4574 "=&r" (__sc_5), "=&r" (__sc_6), \
4575 "=&r" (__sc_7), "=&r" (__sc_8) \
4576 : LSS_ASMINPUT_##nr \
4577 : "cr0", "ctr", "memory"); \
4578 __sc_ret = __sc_3; \
4579 __sc_err = __sc_0; \
4580 } \
4581 LSS_RETURN(type, __sc_ret, __sc_err)
4582
4583 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4584 int flags){
4585 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4586 }
4587
4588 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4589 const struct kernel_msghdr *msg,
4590 int flags) {
4591 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4592 }
4593
4594 // TODO(csilvers): why is this ifdef'ed out?
4595#if 0
4596 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4597 int flags,
4598 const struct kernel_sockaddr *to,
4599 unsigned int tolen) {
4600 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4601 }
4602#endif
4603
4604 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4605 LSS_SC_BODY(2, int, 13, s, how);
4606 }
4607
4608 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4609 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4610 }
4611
4612 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4613 int sv[2]) {
4614 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4615 }
4616 #endif
Andreas Schwab1d387f42022-02-15 16:21:13 +01004617 #if defined(__ARM_EABI__) || defined (__aarch64__) || defined(__riscv)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004618 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4619 int, flags)
4620 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4621 msg, int, flags)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004622 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4623 int, flags, const struct kernel_sockaddr*, to,
4624 unsigned int, tolen)
4625 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
4626 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
4627 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4628 int*, sv)
4629 #endif
4630 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004631 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4632 defined(__s390__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004633 #define __NR__socketcall __NR_socketcall
4634 LSS_INLINE _syscall2(int, _socketcall, int, c,
4635 va_list, a)
4636 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4637 int rc;
4638 va_list ap;
4639 va_start(ap, op);
4640 rc = LSS_NAME(_socketcall)(op, ap);
4641 va_end(ap);
4642 return rc;
4643 }
4644
4645 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4646 int flags){
4647 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4648 }
4649
4650 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4651 const struct kernel_msghdr *msg,
4652 int flags) {
4653 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4654 }
4655
4656 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4657 int flags,
4658 const struct kernel_sockaddr *to,
4659 unsigned int tolen) {
4660 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4661 }
4662
4663 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4664 return LSS_NAME(socketcall)(13, s, how);
4665 }
4666
4667 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4668 return LSS_NAME(socketcall)(1, domain, type, protocol);
4669 }
4670
4671 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4672 int sv[2]) {
4673 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4674 }
4675 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004676 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004677 LSS_INLINE _syscall4(int, fstatat64, int, d,
4678 const char *, p,
4679 struct kernel_stat64 *, b, int, f)
4680 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004681 #if defined(__NR_waitpid)
4682 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004683 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4684 int*, s, int, o)
4685 #endif
4686 #if defined(__mips__)
4687 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4688 * both file handles through CPU registers.
4689 */
4690 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4691 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4692 register unsigned long __v1 __asm__("$3");
4693 register unsigned long __r7 __asm__("$7");
4694 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004695 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004696 : "0"(__v0)
4697 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004698 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004699 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004700 unsigned long __errnovalue = __v0;
4701 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004702 return -1;
4703 } else {
4704 p[0] = __v0;
4705 p[1] = __v1;
4706 return 0;
4707 }
4708 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004709 #elif defined(__NR_pipe)
4710 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004711 LSS_INLINE _syscall1(int, pipe, int *, p)
4712 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004713 #if defined(__NR_pipe2)
4714 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4715 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004716 /* TODO(csilvers): see if ppc can/should support this as well */
4717 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004718 defined(__ARM_EABI__) || \
4719 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4720 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004721 #define __NR__statfs64 __NR_statfs64
4722 #define __NR__fstatfs64 __NR_fstatfs64
4723 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4724 size_t, s,struct kernel_statfs64*, b)
4725 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4726 size_t, s,struct kernel_statfs64*, b)
4727 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
4728 struct kernel_statfs64 *b) {
4729 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
4730 }
4731 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
4732 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
4733 }
4734 #endif
4735
4736 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
4737 extern char **environ;
4738 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
4739 }
4740
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004741 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004742 pid_t tid = LSS_NAME(_gettid)();
4743 if (tid != -1) {
4744 return tid;
4745 }
4746 return LSS_NAME(getpid)();
4747 }
4748
4749 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
4750 size_t new_size, int flags, ...) {
4751 va_list ap;
4752 void *new_address, *rc;
4753 va_start(ap, flags);
4754 new_address = va_arg(ap, void *);
4755 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
Peter Kasting880985f2022-06-29 21:17:55 +00004756 (unsigned long)flags, new_address);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004757 va_end(ap);
4758 return rc;
4759 }
4760
Peter Kasting880985f2022-06-29 21:17:55 +00004761 LSS_INLINE long LSS_NAME(ptrace_detach)(pid_t pid) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004762 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
4763 * then sends job control signals to the real parent, rather than to
4764 * the tracer. We reduce the risk of this happening by starting a
4765 * whole new time slice, and then quickly sending a SIGCONT signal
4766 * right after detaching from the tracee.
4767 *
4768 * We use tkill to ensure that we only issue a wakeup for the thread being
4769 * detached. Large multi threaded apps can take a long time in the kernel
4770 * processing SIGCONT.
4771 */
Peter Kasting880985f2022-06-29 21:17:55 +00004772 long rc;
4773 int err;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004774 LSS_NAME(sched_yield)();
4775 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
4776 err = LSS_ERRNO;
4777 LSS_NAME(tkill)(pid, SIGCONT);
4778 /* Old systems don't have tkill */
4779 if (LSS_ERRNO == ENOSYS)
4780 LSS_NAME(kill)(pid, SIGCONT);
4781 LSS_ERRNO = err;
4782 return rc;
4783 }
4784
4785 LSS_INLINE int LSS_NAME(raise)(int sig) {
4786 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
4787 }
4788
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004789 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004790 return LSS_NAME(setpgid)(0, 0);
4791 }
4792
vapier@chromium.org2273e812013-04-01 17:52:44 +00004793 #if defined(__x86_64__)
4794 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4795 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
4796 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4797 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4798 }
4799
4800 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
4801 loff_t o) {
4802 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4803 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4804 }
4805
Peter Kasting3bb68592022-07-18 19:29:31 +00004806 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, size_t c) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00004807 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4808 LSS_SYSCALL_ARG(c));
4809 }
4810 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004811 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
4812 void *, b, size_t, c,
4813 loff_t, o)
4814 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
4815 const void *, b, size_t, c,
4816 loff_t, o)
4817 LSS_INLINE _syscall3(int, readahead, int, f,
4818 loff_t, o, unsigned, c)
4819 #else
4820 #define __NR__pread64 __NR_pread64
4821 #define __NR__pwrite64 __NR_pwrite64
4822 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00004823 #if defined(__ARM_EABI__) || defined(__mips__)
4824 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
4825 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004826 * fifth and sixth make such a pair (r4,r5).
4827 */
4828 #define LSS_LLARG_PAD 0,
4829 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
4830 void *, b, size_t, c,
4831 unsigned, skip, unsigned, o1, unsigned, o2)
4832 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
4833 const void *, b, size_t, c,
4834 unsigned, skip, unsigned, o1, unsigned, o2)
4835 LSS_INLINE _syscall5(int, _readahead, int, f,
4836 unsigned, skip,
4837 unsigned, o1, unsigned, o2, size_t, c)
4838 #else
4839 #define LSS_LLARG_PAD
4840 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
4841 void *, b, size_t, c, unsigned, o1,
4842 unsigned, o2)
4843 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
4844 const void *, b, size_t, c, unsigned, o1,
Samuel Attardacbdd592022-07-26 16:02:01 +00004845 unsigned, o2)
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004846 LSS_INLINE _syscall4(int, _readahead, int, f,
4847 unsigned, o1, unsigned, o2, size_t, c)
4848 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004849 /* We force 64bit-wide parameters onto the stack, then access each
4850 * 32-bit component individually. This guarantees that we build the
4851 * correct parameters independent of the native byte-order of the
4852 * underlying architecture.
4853 */
4854 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
4855 loff_t off) {
4856 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004857 return LSS_NAME(_pread64)(fd, buf, count,
4858 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004859 }
4860 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
4861 size_t count, loff_t off) {
4862 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004863 return LSS_NAME(_pwrite64)(fd, buf, count,
4864 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004865 }
Peter Kasting3bb68592022-07-18 19:29:31 +00004866 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, size_t count) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004867 union { loff_t off; unsigned arg[2]; } o = { off };
Peter Kasting3bb68592022-07-18 19:29:31 +00004868 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], count);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004869 }
4870 #endif
4871#endif
4872
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004873/*
4874 * Polyfills for deprecated syscalls.
4875 */
4876
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004877#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004878 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
4879 return LSS_NAME(dup3)(s, d, 0);
4880 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004881#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004882
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004883#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004884 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
4885 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
4886 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004887#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004888
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004889#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004890 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
4891 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
4892 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004893#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004894
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004895#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004896 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
4897 size_t size) {
4898 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
4899 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004900#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004901
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004902#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05004903 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004904 return LSS_NAME(pipe2)(pipefd, 0);
4905 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004906#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004907
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004908#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004909 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
4910 int timeout) {
4911 struct kernel_timespec timeout_ts;
4912 struct kernel_timespec *timeout_ts_p = NULL;
4913
4914 if (timeout >= 0) {
4915 timeout_ts.tv_sec = timeout / 1000;
4916 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
4917 timeout_ts_p = &timeout_ts;
4918 }
4919 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
4920 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004921#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004922
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004923#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004924 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
4925 struct kernel_stat *buf) {
4926 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
4927 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004928#endif
Matthew Denton92a65a82021-04-01 13:00:07 -07004929#if !defined(__NR_lstat)
4930 LSS_INLINE int LSS_NAME(lstat)(const char *pathname,
4931 struct kernel_stat *buf) {
4932 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW);
4933 }
4934#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004935
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004936#if !defined(__NR_waitpid)
4937 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
4938 return LSS_NAME(wait4)(pid, status, options, 0);
4939 }
4940#endif
4941
4942#if !defined(__NR_fork)
4943// TODO: define this in an arch-independant way instead of inlining the clone
4944// syscall body.
4945
Andreas Schwab1d387f42022-02-15 16:21:13 +01004946# if defined(__aarch64__) || defined(__riscv)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004947 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4948 // No fork syscall on aarch64 - implement by means of the clone syscall.
4949 // Note that this does not reset glibc's cached view of the PID/TID, so
4950 // some glibc interfaces might go wrong in the forked subprocess.
4951 int flags = SIGCHLD;
4952 void *child_stack = NULL;
4953 void *parent_tidptr = NULL;
4954 void *newtls = NULL;
4955 void *child_tidptr = NULL;
4956
4957 LSS_REG(0, flags);
4958 LSS_REG(1, child_stack);
4959 LSS_REG(2, parent_tidptr);
4960 LSS_REG(3, newtls);
4961 LSS_REG(4, child_tidptr);
4962 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
4963 "r"(__r4));
4964 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004965# elif defined(__x86_64__)
4966 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4967 // Android disallows the fork syscall on x86_64 - implement by means of the
4968 // clone syscall as above for aarch64.
4969 int flags = SIGCHLD;
4970 void *child_stack = NULL;
4971 void *parent_tidptr = NULL;
4972 void *newtls = NULL;
4973 void *child_tidptr = NULL;
4974
4975 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
4976 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
4977 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
4978 }
4979# else
4980# error missing fork polyfill for this architecture
4981# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004982#endif
4983
Michael Forneyf70e2f12020-01-22 19:19:38 -08004984/* These restore the original values of these macros saved by the
4985 * corresponding #pragma push_macro near the top of this file. */
4986#pragma pop_macro("stat64")
4987#pragma pop_macro("fstat64")
4988#pragma pop_macro("lstat64")
4989#pragma pop_macro("pread64")
4990#pragma pop_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -07004991#pragma pop_macro("getdents64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00004992
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004993#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
4994}
4995#endif
4996
4997#endif
4998#endif