blob: e4ac22644c0cfc8a3c0d453eb4a1eedbfbc4ff77 [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__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -040091 defined(__aarch64__) || defined(__s390__)) \
zodiac@gmail.com4f470182010-10-13 03:47:54 +000092 && (defined(__linux) || defined(__ANDROID__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +000093
94#ifndef SYS_CPLUSPLUS
95#ifdef __cplusplus
96/* Some system header files in older versions of gcc neglect to properly
97 * handle being included from C++. As it appears to be harmless to have
98 * multiple nested 'extern "C"' blocks, just add another one here.
99 */
100extern "C" {
101#endif
102
103#include <errno.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000104#include <fcntl.h>
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000105#include <sched.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000106#include <signal.h>
107#include <stdarg.h>
108#include <stddef.h>
vapier@chromium.org2273e812013-04-01 17:52:44 +0000109#include <stdint.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000110#include <string.h>
111#include <sys/ptrace.h>
112#include <sys/resource.h>
113#include <sys/time.h>
114#include <sys/types.h>
zodiac@gmail.com4f470182010-10-13 03:47:54 +0000115#include <sys/syscall.h>
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000116#include <unistd.h>
117#include <linux/unistd.h>
118#include <endian.h>
119
120#ifdef __mips__
121/* Include definitions of the ABI currently in use. */
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000122#ifdef __ANDROID__
123/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h,
124 * which has the definitions we need.
125 */
126#include <asm/sgidefs.h>
127#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000128#include <sgidefs.h>
129#endif
130#endif
mseaborn@chromium.org4fc94222015-08-11 21:15:24 +0000131#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000132
Michael Forneyf70e2f12020-01-22 19:19:38 -0800133/* Some libcs, for example Android NDK and musl, #define these
134 * macros as aliases to their non-64 counterparts. To avoid naming
135 * conflict, remove them.
136 *
137 * These are restored by the corresponding #pragma pop_macro near
138 * the end of this file.
139 */
140#pragma push_macro("stat64")
141#pragma push_macro("fstat64")
142#pragma push_macro("lstat64")
143#pragma push_macro("pread64")
144#pragma push_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700145#pragma push_macro("getdents64")
Michael Forneyf70e2f12020-01-22 19:19:38 -0800146#undef stat64
147#undef fstat64
148#undef lstat64
149#undef pread64
150#undef pwrite64
Michael Forneyfd00dbb2020-03-10 14:12:52 -0700151#undef getdents64
mseaborn@chromium.orgca749372012-09-05 18:26:20 +0000152
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400153#if defined(__ANDROID__) && defined(__x86_64__)
154// A number of x86_64 syscalls are blocked by seccomp on recent Android;
155// undefine them so that modern alternatives will be used instead where
156// possible.
157// The alternative syscalls have been sanity checked against linux-3.4+;
158// older versions might not work.
159# undef __NR_getdents
160# undef __NR_dup2
161# undef __NR_fork
162# undef __NR_getpgrp
163# undef __NR_open
164# undef __NR_poll
165# undef __NR_readlink
166# undef __NR_stat
167# undef __NR_unlink
168# undef __NR_pipe
169#endif
170
171#if defined(__ANDROID__)
172// waitpid is blocked by seccomp on all architectures on recent Android.
173# undef __NR_waitpid
174#endif
175
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000176/* As glibc often provides subtly incompatible data structures (and implicit
177 * wrapper functions that convert them), we provide our own kernel data
178 * structures for use by the system calls.
179 * These structures have been developed by using Linux 2.6.23 headers for
180 * reference. Note though, we do not care about exact API compatibility
181 * with the kernel, and in fact the kernel often does not have a single
182 * API that works across architectures. Instead, we try to mimic the glibc
183 * API where reasonable, and only guarantee ABI compatibility with the
184 * kernel headers.
185 * Most notably, here are a few changes that were made to the structures
186 * defined by kernel headers:
187 *
188 * - we only define structures, but not symbolic names for kernel data
189 * types. For the latter, we directly use the native C datatype
190 * (i.e. "unsigned" instead of "mode_t").
191 * - in a few cases, it is possible to define identical structures for
192 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
193 * standardizing on the 64bit version of the data types. In particular,
194 * this means that we use "unsigned" where the 32bit headers say
195 * "unsigned long".
196 * - overall, we try to minimize the number of cases where we need to
197 * conditionally define different structures.
198 * - the "struct kernel_sigaction" class of structures have been
199 * modified to more closely mimic glibc's API by introducing an
200 * anonymous union for the function pointer.
201 * - a small number of field names had to have an underscore appended to
202 * them, because glibc defines a global macro by the same name.
203 */
204
205/* include/linux/dirent.h */
206struct kernel_dirent64 {
207 unsigned long long d_ino;
208 long long d_off;
209 unsigned short d_reclen;
210 unsigned char d_type;
211 char d_name[256];
212};
213
214/* include/linux/dirent.h */
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400215#if !defined(__NR_getdents)
216// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000217#define kernel_dirent kernel_dirent64
218#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000219struct kernel_dirent {
220 long d_ino;
221 long d_off;
222 unsigned short d_reclen;
223 char d_name[256];
224};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000225#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000226
227/* include/linux/uio.h */
228struct kernel_iovec {
229 void *iov_base;
230 unsigned long iov_len;
231};
232
233/* include/linux/socket.h */
234struct kernel_msghdr {
235 void *msg_name;
236 int msg_namelen;
237 struct kernel_iovec*msg_iov;
238 unsigned long msg_iovlen;
239 void *msg_control;
240 unsigned long msg_controllen;
241 unsigned msg_flags;
242};
243
244/* include/asm-generic/poll.h */
245struct kernel_pollfd {
246 int fd;
247 short events;
248 short revents;
249};
250
251/* include/linux/resource.h */
252struct kernel_rlimit {
253 unsigned long rlim_cur;
254 unsigned long rlim_max;
255};
256
257/* include/linux/time.h */
258struct kernel_timespec {
259 long tv_sec;
260 long tv_nsec;
261};
262
263/* include/linux/time.h */
264struct kernel_timeval {
265 long tv_sec;
266 long tv_usec;
267};
268
269/* include/linux/resource.h */
270struct kernel_rusage {
271 struct kernel_timeval ru_utime;
272 struct kernel_timeval ru_stime;
273 long ru_maxrss;
274 long ru_ixrss;
275 long ru_idrss;
276 long ru_isrss;
277 long ru_minflt;
278 long ru_majflt;
279 long ru_nswap;
280 long ru_inblock;
281 long ru_oublock;
282 long ru_msgsnd;
283 long ru_msgrcv;
284 long ru_nsignals;
285 long ru_nvcsw;
286 long ru_nivcsw;
287};
288
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000289#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
Bryan Chan3f6478a2016-06-14 08:38:17 -0400290 || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000291
292/* include/asm-{arm,i386,mips,ppc}/signal.h */
293struct kernel_old_sigaction {
294 union {
295 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000296 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000297 };
298 unsigned long sa_mask;
299 unsigned long sa_flags;
300 void (*sa_restorer)(void);
301} __attribute__((packed,aligned(4)));
302#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
303 #define kernel_old_sigaction kernel_sigaction
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000304#elif defined(__aarch64__)
305 // No kernel_old_sigaction defined for arm64.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000306#endif
307
308/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
309 * exactly match the size of the signal set, even though the API was
310 * intended to be extensible. We define our own KERNEL_NSIG to deal with
311 * this.
312 * Please note that glibc provides signals [1.._NSIG-1], whereas the
313 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
314 * actual number of signals is obviously the same, but the constants
315 * differ by one.
316 */
317#ifdef __mips__
318#define KERNEL_NSIG 128
319#else
320#define KERNEL_NSIG 64
321#endif
322
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000323/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000324struct kernel_sigset_t {
325 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
326 (8*sizeof(unsigned long))];
327};
328
329/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
330struct kernel_sigaction {
331#ifdef __mips__
332 unsigned long sa_flags;
333 union {
334 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000335 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000336 };
337 struct kernel_sigset_t sa_mask;
338#else
339 union {
340 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000341 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000342 };
343 unsigned long sa_flags;
344 void (*sa_restorer)(void);
345 struct kernel_sigset_t sa_mask;
346#endif
347};
348
349/* include/linux/socket.h */
350struct kernel_sockaddr {
351 unsigned short sa_family;
352 char sa_data[14];
353};
354
Bryan Chan3f6478a2016-06-14 08:38:17 -0400355/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000356#ifdef __mips__
357#if _MIPS_SIM == _MIPS_SIM_ABI64
358struct kernel_stat {
359#else
360struct kernel_stat64 {
361#endif
362 unsigned st_dev;
363 unsigned __pad0[3];
364 unsigned long long st_ino;
365 unsigned st_mode;
366 unsigned st_nlink;
367 unsigned st_uid;
368 unsigned st_gid;
369 unsigned st_rdev;
370 unsigned __pad1[3];
371 long long st_size;
372 unsigned st_atime_;
373 unsigned st_atime_nsec_;
374 unsigned st_mtime_;
375 unsigned st_mtime_nsec_;
376 unsigned st_ctime_;
377 unsigned st_ctime_nsec_;
378 unsigned st_blksize;
379 unsigned __pad2;
380 unsigned long long st_blocks;
381};
382#elif defined __PPC__
383struct kernel_stat64 {
384 unsigned long long st_dev;
385 unsigned long long st_ino;
386 unsigned st_mode;
387 unsigned st_nlink;
388 unsigned st_uid;
389 unsigned st_gid;
390 unsigned long long st_rdev;
391 unsigned short int __pad2;
392 long long st_size;
393 long st_blksize;
394 long long st_blocks;
395 long st_atime_;
396 unsigned long st_atime_nsec_;
397 long st_mtime_;
398 unsigned long st_mtime_nsec_;
399 long st_ctime_;
400 unsigned long st_ctime_nsec_;
401 unsigned long __unused4;
402 unsigned long __unused5;
403};
404#else
405struct kernel_stat64 {
406 unsigned long long st_dev;
407 unsigned char __pad0[4];
408 unsigned __st_ino;
409 unsigned st_mode;
410 unsigned st_nlink;
411 unsigned st_uid;
412 unsigned st_gid;
413 unsigned long long st_rdev;
414 unsigned char __pad3[4];
415 long long st_size;
416 unsigned st_blksize;
417 unsigned long long st_blocks;
418 unsigned st_atime_;
419 unsigned st_atime_nsec_;
420 unsigned st_mtime_;
421 unsigned st_mtime_nsec_;
422 unsigned st_ctime_;
423 unsigned st_ctime_nsec_;
424 unsigned long long st_ino;
425};
426#endif
427
Bryan Chan3f6478a2016-06-14 08:38:17 -0400428/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000429#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
430struct kernel_stat {
431 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
432 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
433 * format. In reality, we do not see useful data in the top bits. So,
434 * we'll leave the padding in here, until we find a better solution.
435 */
436 unsigned short st_dev;
437 short pad1;
438 unsigned st_ino;
439 unsigned short st_mode;
440 unsigned short st_nlink;
441 unsigned short st_uid;
442 unsigned short st_gid;
443 unsigned short st_rdev;
444 short pad2;
445 unsigned st_size;
446 unsigned st_blksize;
447 unsigned st_blocks;
448 unsigned st_atime_;
449 unsigned st_atime_nsec_;
450 unsigned st_mtime_;
451 unsigned st_mtime_nsec_;
452 unsigned st_ctime_;
453 unsigned st_ctime_nsec_;
454 unsigned __unused4;
455 unsigned __unused5;
456};
457#elif defined(__x86_64__)
458struct kernel_stat {
vapier@chromium.org2273e812013-04-01 17:52:44 +0000459 uint64_t st_dev;
460 uint64_t st_ino;
461 uint64_t st_nlink;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000462 unsigned st_mode;
463 unsigned st_uid;
464 unsigned st_gid;
465 unsigned __pad0;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000466 uint64_t st_rdev;
467 int64_t st_size;
468 int64_t st_blksize;
469 int64_t st_blocks;
470 uint64_t st_atime_;
471 uint64_t st_atime_nsec_;
472 uint64_t st_mtime_;
473 uint64_t st_mtime_nsec_;
474 uint64_t st_ctime_;
475 uint64_t st_ctime_nsec_;
anton@chromium.org43de0522014-04-04 11:20:46 +0000476 int64_t __unused4[3];
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000477};
478#elif defined(__PPC__)
479struct kernel_stat {
480 unsigned st_dev;
481 unsigned long st_ino; // ino_t
482 unsigned long st_mode; // mode_t
483 unsigned short st_nlink; // nlink_t
484 unsigned st_uid; // uid_t
485 unsigned st_gid; // gid_t
486 unsigned st_rdev;
487 long st_size; // off_t
488 unsigned long st_blksize;
489 unsigned long st_blocks;
490 unsigned long st_atime_;
491 unsigned long st_atime_nsec_;
492 unsigned long st_mtime_;
493 unsigned long st_mtime_nsec_;
494 unsigned long st_ctime_;
495 unsigned long st_ctime_nsec_;
496 unsigned long __unused4;
497 unsigned long __unused5;
498};
499#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
500struct kernel_stat {
501 unsigned st_dev;
502 int st_pad1[3];
503 unsigned st_ino;
504 unsigned st_mode;
505 unsigned st_nlink;
506 unsigned st_uid;
507 unsigned st_gid;
508 unsigned st_rdev;
509 int st_pad2[2];
510 long st_size;
511 int st_pad3;
512 long st_atime_;
513 long st_atime_nsec_;
514 long st_mtime_;
515 long st_mtime_nsec_;
516 long st_ctime_;
517 long st_ctime_nsec_;
518 int st_blksize;
519 int st_blocks;
520 int st_pad4[14];
521};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000522#elif defined(__aarch64__)
523struct kernel_stat {
524 unsigned long st_dev;
525 unsigned long st_ino;
526 unsigned int st_mode;
527 unsigned int st_nlink;
528 unsigned int st_uid;
529 unsigned int st_gid;
530 unsigned long st_rdev;
531 unsigned long __pad1;
532 long st_size;
533 int st_blksize;
534 int __pad2;
535 long st_blocks;
536 long st_atime_;
537 unsigned long st_atime_nsec_;
538 long st_mtime_;
539 unsigned long st_mtime_nsec_;
540 long st_ctime_;
541 unsigned long st_ctime_nsec_;
542 unsigned int __unused4;
543 unsigned int __unused5;
544};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400545#elif defined(__s390x__)
546struct kernel_stat {
547 unsigned long st_dev;
548 unsigned long st_ino;
549 unsigned long st_nlink;
550 unsigned int st_mode;
551 unsigned int st_uid;
552 unsigned int st_gid;
553 unsigned int __pad1;
554 unsigned long st_rdev;
555 unsigned long st_size;
556 unsigned long st_atime_;
557 unsigned long st_atime_nsec_;
558 unsigned long st_mtime_;
559 unsigned long st_mtime_nsec_;
560 unsigned long st_ctime_;
561 unsigned long st_ctime_nsec_;
562 unsigned long st_blksize;
563 long st_blocks;
564 unsigned long __unused[3];
565};
566#elif defined(__s390__)
567struct kernel_stat {
568 unsigned short st_dev;
569 unsigned short __pad1;
570 unsigned long st_ino;
571 unsigned short st_mode;
572 unsigned short st_nlink;
573 unsigned short st_uid;
574 unsigned short st_gid;
575 unsigned short st_rdev;
576 unsigned short __pad2;
577 unsigned long st_size;
578 unsigned long st_blksize;
579 unsigned long st_blocks;
580 unsigned long st_atime_;
581 unsigned long st_atime_nsec_;
582 unsigned long st_mtime_;
583 unsigned long st_mtime_nsec_;
584 unsigned long st_ctime_;
585 unsigned long st_ctime_nsec_;
586 unsigned long __unused4;
587 unsigned long __unused5;
588};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000589#endif
590
Bryan Chan3f6478a2016-06-14 08:38:17 -0400591/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000592#ifdef __mips__
593#if _MIPS_SIM != _MIPS_SIM_ABI64
594struct kernel_statfs64 {
595 unsigned long f_type;
596 unsigned long f_bsize;
597 unsigned long f_frsize;
598 unsigned long __pad;
599 unsigned long long f_blocks;
600 unsigned long long f_bfree;
601 unsigned long long f_files;
602 unsigned long long f_ffree;
603 unsigned long long f_bavail;
604 struct { int val[2]; } f_fsid;
605 unsigned long f_namelen;
606 unsigned long f_spare[6];
607};
608#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -0400609#elif defined(__s390__)
610/* See also arch/s390/include/asm/compat.h */
611struct kernel_statfs64 {
612 unsigned int f_type;
613 unsigned int f_bsize;
614 unsigned long long f_blocks;
615 unsigned long long f_bfree;
616 unsigned long long f_bavail;
617 unsigned long long f_files;
618 unsigned long long f_ffree;
619 struct { int val[2]; } f_fsid;
620 unsigned int f_namelen;
621 unsigned int f_frsize;
622 unsigned int f_flags;
623 unsigned int f_spare[4];
624};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000625#elif !defined(__x86_64__)
626struct kernel_statfs64 {
627 unsigned long f_type;
628 unsigned long f_bsize;
629 unsigned long long f_blocks;
630 unsigned long long f_bfree;
631 unsigned long long f_bavail;
632 unsigned long long f_files;
633 unsigned long long f_ffree;
634 struct { int val[2]; } f_fsid;
635 unsigned long f_namelen;
636 unsigned long f_frsize;
637 unsigned long f_spare[5];
638};
639#endif
640
Bryan Chan3f6478a2016-06-14 08:38:17 -0400641/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000642#ifdef __mips__
643struct kernel_statfs {
644 long f_type;
645 long f_bsize;
646 long f_frsize;
647 long f_blocks;
648 long f_bfree;
649 long f_files;
650 long f_ffree;
651 long f_bavail;
652 struct { int val[2]; } f_fsid;
653 long f_namelen;
654 long f_spare[6];
655};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000656#elif defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000657struct kernel_statfs {
658 /* x86_64 actually defines all these fields as signed, whereas all other */
659 /* platforms define them as unsigned. Leaving them at unsigned should not */
vapier@chromium.org2273e812013-04-01 17:52:44 +0000660 /* cause any problems. Make sure these are 64-bit even on x32. */
661 uint64_t f_type;
662 uint64_t f_bsize;
663 uint64_t f_blocks;
664 uint64_t f_bfree;
665 uint64_t f_bavail;
666 uint64_t f_files;
667 uint64_t f_ffree;
668 struct { int val[2]; } f_fsid;
669 uint64_t f_namelen;
670 uint64_t f_frsize;
671 uint64_t f_spare[5];
672};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400673#elif defined(__s390__)
674struct kernel_statfs {
675 unsigned int f_type;
676 unsigned int f_bsize;
677 unsigned long f_blocks;
678 unsigned long f_bfree;
679 unsigned long f_bavail;
680 unsigned long f_files;
681 unsigned long f_ffree;
682 struct { int val[2]; } f_fsid;
683 unsigned int f_namelen;
684 unsigned int f_frsize;
685 unsigned int f_flags;
686 unsigned int f_spare[4];
687};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000688#else
689struct kernel_statfs {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000690 unsigned long f_type;
691 unsigned long f_bsize;
692 unsigned long f_blocks;
693 unsigned long f_bfree;
694 unsigned long f_bavail;
695 unsigned long f_files;
696 unsigned long f_ffree;
697 struct { int val[2]; } f_fsid;
698 unsigned long f_namelen;
699 unsigned long f_frsize;
700 unsigned long f_spare[5];
701};
702#endif
703
704
705/* Definitions missing from the standard header files */
706#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000707#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000708#define O_DIRECTORY 0040000
709#else
710#define O_DIRECTORY 0200000
711#endif
712#endif
713#ifndef NT_PRXFPREG
714#define NT_PRXFPREG 0x46e62b7f
715#endif
716#ifndef PTRACE_GETFPXREGS
717#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
718#endif
719#ifndef PR_GET_DUMPABLE
720#define PR_GET_DUMPABLE 3
721#endif
722#ifndef PR_SET_DUMPABLE
723#define PR_SET_DUMPABLE 4
724#endif
725#ifndef PR_GET_SECCOMP
726#define PR_GET_SECCOMP 21
727#endif
728#ifndef PR_SET_SECCOMP
729#define PR_SET_SECCOMP 22
730#endif
731#ifndef AT_FDCWD
732#define AT_FDCWD (-100)
733#endif
734#ifndef AT_SYMLINK_NOFOLLOW
735#define AT_SYMLINK_NOFOLLOW 0x100
736#endif
737#ifndef AT_REMOVEDIR
738#define AT_REMOVEDIR 0x200
739#endif
740#ifndef MREMAP_FIXED
741#define MREMAP_FIXED 2
742#endif
743#ifndef SA_RESTORER
744#define SA_RESTORER 0x04000000
745#endif
746#ifndef CPUCLOCK_PROF
747#define CPUCLOCK_PROF 0
748#endif
749#ifndef CPUCLOCK_VIRT
750#define CPUCLOCK_VIRT 1
751#endif
752#ifndef CPUCLOCK_SCHED
753#define CPUCLOCK_SCHED 2
754#endif
755#ifndef CPUCLOCK_PERTHREAD_MASK
756#define CPUCLOCK_PERTHREAD_MASK 4
757#endif
758#ifndef MAKE_PROCESS_CPUCLOCK
759#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400760 ((int)(~(unsigned)(pid) << 3) | (int)(clock))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000761#endif
762#ifndef MAKE_THREAD_CPUCLOCK
763#define MAKE_THREAD_CPUCLOCK(tid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400764 ((int)(~(unsigned)(tid) << 3) | \
765 (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000766#endif
767
768#ifndef FUTEX_WAIT
769#define FUTEX_WAIT 0
770#endif
771#ifndef FUTEX_WAKE
772#define FUTEX_WAKE 1
773#endif
774#ifndef FUTEX_FD
775#define FUTEX_FD 2
776#endif
777#ifndef FUTEX_REQUEUE
778#define FUTEX_REQUEUE 3
779#endif
780#ifndef FUTEX_CMP_REQUEUE
781#define FUTEX_CMP_REQUEUE 4
782#endif
783#ifndef FUTEX_WAKE_OP
784#define FUTEX_WAKE_OP 5
785#endif
786#ifndef FUTEX_LOCK_PI
787#define FUTEX_LOCK_PI 6
788#endif
789#ifndef FUTEX_UNLOCK_PI
790#define FUTEX_UNLOCK_PI 7
791#endif
792#ifndef FUTEX_TRYLOCK_PI
793#define FUTEX_TRYLOCK_PI 8
794#endif
795#ifndef FUTEX_PRIVATE_FLAG
796#define FUTEX_PRIVATE_FLAG 128
797#endif
798#ifndef FUTEX_CMD_MASK
799#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
800#endif
801#ifndef FUTEX_WAIT_PRIVATE
802#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
803#endif
804#ifndef FUTEX_WAKE_PRIVATE
805#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
806#endif
807#ifndef FUTEX_REQUEUE_PRIVATE
808#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
809#endif
810#ifndef FUTEX_CMP_REQUEUE_PRIVATE
811#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
812#endif
813#ifndef FUTEX_WAKE_OP_PRIVATE
814#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
815#endif
816#ifndef FUTEX_LOCK_PI_PRIVATE
817#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
818#endif
819#ifndef FUTEX_UNLOCK_PI_PRIVATE
820#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
821#endif
822#ifndef FUTEX_TRYLOCK_PI_PRIVATE
823#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
824#endif
825
826
827#if defined(__x86_64__)
828#ifndef ARCH_SET_GS
829#define ARCH_SET_GS 0x1001
830#endif
831#ifndef ARCH_GET_GS
832#define ARCH_GET_GS 0x1004
833#endif
834#endif
835
836#if defined(__i386__)
837#ifndef __NR_quotactl
838#define __NR_quotactl 131
839#endif
840#ifndef __NR_setresuid
841#define __NR_setresuid 164
842#define __NR_getresuid 165
843#define __NR_setresgid 170
844#define __NR_getresgid 171
845#endif
846#ifndef __NR_rt_sigaction
847#define __NR_rt_sigreturn 173
848#define __NR_rt_sigaction 174
849#define __NR_rt_sigprocmask 175
850#define __NR_rt_sigpending 176
851#define __NR_rt_sigsuspend 179
852#endif
853#ifndef __NR_pread64
854#define __NR_pread64 180
855#endif
856#ifndef __NR_pwrite64
857#define __NR_pwrite64 181
858#endif
859#ifndef __NR_ugetrlimit
860#define __NR_ugetrlimit 191
861#endif
862#ifndef __NR_stat64
863#define __NR_stat64 195
864#endif
865#ifndef __NR_fstat64
866#define __NR_fstat64 197
867#endif
868#ifndef __NR_setresuid32
869#define __NR_setresuid32 208
870#define __NR_getresuid32 209
871#define __NR_setresgid32 210
872#define __NR_getresgid32 211
873#endif
874#ifndef __NR_setfsuid32
875#define __NR_setfsuid32 215
876#define __NR_setfsgid32 216
877#endif
878#ifndef __NR_getdents64
879#define __NR_getdents64 220
880#endif
881#ifndef __NR_gettid
882#define __NR_gettid 224
883#endif
884#ifndef __NR_readahead
885#define __NR_readahead 225
886#endif
887#ifndef __NR_setxattr
888#define __NR_setxattr 226
889#endif
890#ifndef __NR_lsetxattr
891#define __NR_lsetxattr 227
892#endif
893#ifndef __NR_getxattr
894#define __NR_getxattr 229
895#endif
896#ifndef __NR_lgetxattr
897#define __NR_lgetxattr 230
898#endif
899#ifndef __NR_listxattr
900#define __NR_listxattr 232
901#endif
902#ifndef __NR_llistxattr
903#define __NR_llistxattr 233
904#endif
905#ifndef __NR_tkill
906#define __NR_tkill 238
907#endif
908#ifndef __NR_futex
909#define __NR_futex 240
910#endif
911#ifndef __NR_sched_setaffinity
912#define __NR_sched_setaffinity 241
913#define __NR_sched_getaffinity 242
914#endif
915#ifndef __NR_set_tid_address
916#define __NR_set_tid_address 258
917#endif
918#ifndef __NR_clock_gettime
919#define __NR_clock_gettime 265
920#endif
921#ifndef __NR_clock_getres
922#define __NR_clock_getres 266
923#endif
924#ifndef __NR_statfs64
925#define __NR_statfs64 268
926#endif
927#ifndef __NR_fstatfs64
928#define __NR_fstatfs64 269
929#endif
930#ifndef __NR_fadvise64_64
931#define __NR_fadvise64_64 272
932#endif
933#ifndef __NR_ioprio_set
934#define __NR_ioprio_set 289
935#endif
936#ifndef __NR_ioprio_get
937#define __NR_ioprio_get 290
938#endif
939#ifndef __NR_openat
940#define __NR_openat 295
941#endif
942#ifndef __NR_fstatat64
943#define __NR_fstatat64 300
944#endif
945#ifndef __NR_unlinkat
946#define __NR_unlinkat 301
947#endif
948#ifndef __NR_move_pages
949#define __NR_move_pages 317
950#endif
951#ifndef __NR_getcpu
952#define __NR_getcpu 318
953#endif
954#ifndef __NR_fallocate
955#define __NR_fallocate 324
956#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -0700957#ifndef __NR_getrandom
958#define __NR_getrandom 355
959#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000960/* End of i386 definitions */
961#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
962#ifndef __NR_setresuid
963#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
964#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
965#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
966#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
967#endif
968#ifndef __NR_rt_sigaction
969#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
970#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
971#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
972#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
973#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
974#endif
975#ifndef __NR_pread64
976#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
977#endif
978#ifndef __NR_pwrite64
979#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
980#endif
981#ifndef __NR_ugetrlimit
982#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
983#endif
984#ifndef __NR_stat64
985#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
986#endif
987#ifndef __NR_fstat64
988#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
989#endif
990#ifndef __NR_setresuid32
991#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
992#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
993#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
994#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
995#endif
996#ifndef __NR_setfsuid32
997#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
998#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
999#endif
1000#ifndef __NR_getdents64
1001#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
1002#endif
1003#ifndef __NR_gettid
1004#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1005#endif
1006#ifndef __NR_readahead
1007#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1008#endif
1009#ifndef __NR_setxattr
1010#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1011#endif
1012#ifndef __NR_lsetxattr
1013#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1014#endif
1015#ifndef __NR_getxattr
1016#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1017#endif
1018#ifndef __NR_lgetxattr
1019#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1020#endif
1021#ifndef __NR_listxattr
1022#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1023#endif
1024#ifndef __NR_llistxattr
1025#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1026#endif
1027#ifndef __NR_tkill
1028#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1029#endif
1030#ifndef __NR_futex
1031#define __NR_futex (__NR_SYSCALL_BASE + 240)
1032#endif
1033#ifndef __NR_sched_setaffinity
1034#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1035#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1036#endif
1037#ifndef __NR_set_tid_address
1038#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1039#endif
1040#ifndef __NR_clock_gettime
1041#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1042#endif
1043#ifndef __NR_clock_getres
1044#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1045#endif
1046#ifndef __NR_statfs64
1047#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1048#endif
1049#ifndef __NR_fstatfs64
1050#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1051#endif
1052#ifndef __NR_ioprio_set
1053#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1054#endif
1055#ifndef __NR_ioprio_get
1056#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1057#endif
1058#ifndef __NR_move_pages
1059#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1060#endif
1061#ifndef __NR_getcpu
1062#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1063#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001064#ifndef __NR_getrandom
1065#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
1066#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001067/* End of ARM 3/EABI definitions */
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001068#elif defined(__aarch64__)
1069#ifndef __NR_setxattr
1070#define __NR_setxattr 5
1071#endif
1072#ifndef __NR_lsetxattr
1073#define __NR_lsetxattr 6
1074#endif
1075#ifndef __NR_getxattr
1076#define __NR_getxattr 8
1077#endif
1078#ifndef __NR_lgetxattr
1079#define __NR_lgetxattr 9
1080#endif
1081#ifndef __NR_listxattr
1082#define __NR_listxattr 11
1083#endif
1084#ifndef __NR_llistxattr
1085#define __NR_llistxattr 12
1086#endif
1087#ifndef __NR_ioprio_set
1088#define __NR_ioprio_set 30
1089#endif
1090#ifndef __NR_ioprio_get
1091#define __NR_ioprio_get 31
1092#endif
1093#ifndef __NR_unlinkat
1094#define __NR_unlinkat 35
1095#endif
1096#ifndef __NR_fallocate
1097#define __NR_fallocate 47
1098#endif
1099#ifndef __NR_openat
1100#define __NR_openat 56
1101#endif
1102#ifndef __NR_quotactl
1103#define __NR_quotactl 60
1104#endif
1105#ifndef __NR_getdents64
1106#define __NR_getdents64 61
1107#endif
1108#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001109// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001110#define __NR_getdents __NR_getdents64
1111#endif
1112#ifndef __NR_pread64
1113#define __NR_pread64 67
1114#endif
1115#ifndef __NR_pwrite64
1116#define __NR_pwrite64 68
1117#endif
1118#ifndef __NR_ppoll
1119#define __NR_ppoll 73
1120#endif
1121#ifndef __NR_readlinkat
1122#define __NR_readlinkat 78
1123#endif
1124#ifndef __NR_newfstatat
1125#define __NR_newfstatat 79
1126#endif
1127#ifndef __NR_set_tid_address
1128#define __NR_set_tid_address 96
1129#endif
1130#ifndef __NR_futex
1131#define __NR_futex 98
1132#endif
1133#ifndef __NR_clock_gettime
1134#define __NR_clock_gettime 113
1135#endif
1136#ifndef __NR_clock_getres
1137#define __NR_clock_getres 114
1138#endif
1139#ifndef __NR_sched_setaffinity
1140#define __NR_sched_setaffinity 122
1141#define __NR_sched_getaffinity 123
1142#endif
1143#ifndef __NR_tkill
1144#define __NR_tkill 130
1145#endif
1146#ifndef __NR_setresuid
1147#define __NR_setresuid 147
1148#define __NR_getresuid 148
1149#define __NR_setresgid 149
1150#define __NR_getresgid 150
1151#endif
1152#ifndef __NR_gettid
1153#define __NR_gettid 178
1154#endif
1155#ifndef __NR_readahead
1156#define __NR_readahead 213
1157#endif
1158#ifndef __NR_fadvise64
1159#define __NR_fadvise64 223
1160#endif
1161#ifndef __NR_move_pages
1162#define __NR_move_pages 239
1163#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001164#ifndef __NR_getrandom
1165#define __NR_getrandom 278
1166#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001167/* End of aarch64 definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001168#elif defined(__x86_64__)
1169#ifndef __NR_pread64
1170#define __NR_pread64 17
1171#endif
1172#ifndef __NR_pwrite64
1173#define __NR_pwrite64 18
1174#endif
1175#ifndef __NR_setresuid
1176#define __NR_setresuid 117
1177#define __NR_getresuid 118
1178#define __NR_setresgid 119
1179#define __NR_getresgid 120
1180#endif
1181#ifndef __NR_quotactl
1182#define __NR_quotactl 179
1183#endif
1184#ifndef __NR_gettid
1185#define __NR_gettid 186
1186#endif
1187#ifndef __NR_readahead
1188#define __NR_readahead 187
1189#endif
1190#ifndef __NR_setxattr
1191#define __NR_setxattr 188
1192#endif
1193#ifndef __NR_lsetxattr
1194#define __NR_lsetxattr 189
1195#endif
1196#ifndef __NR_getxattr
1197#define __NR_getxattr 191
1198#endif
1199#ifndef __NR_lgetxattr
1200#define __NR_lgetxattr 192
1201#endif
1202#ifndef __NR_listxattr
1203#define __NR_listxattr 194
1204#endif
1205#ifndef __NR_llistxattr
1206#define __NR_llistxattr 195
1207#endif
1208#ifndef __NR_tkill
1209#define __NR_tkill 200
1210#endif
1211#ifndef __NR_futex
1212#define __NR_futex 202
1213#endif
1214#ifndef __NR_sched_setaffinity
1215#define __NR_sched_setaffinity 203
1216#define __NR_sched_getaffinity 204
1217#endif
1218#ifndef __NR_getdents64
1219#define __NR_getdents64 217
1220#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001221#ifndef __NR_getdents
1222// when getdents is not available, getdents64 is used for both.
1223#define __NR_getdents __NR_getdents64
1224#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001225#ifndef __NR_set_tid_address
1226#define __NR_set_tid_address 218
1227#endif
1228#ifndef __NR_fadvise64
1229#define __NR_fadvise64 221
1230#endif
1231#ifndef __NR_clock_gettime
1232#define __NR_clock_gettime 228
1233#endif
1234#ifndef __NR_clock_getres
1235#define __NR_clock_getres 229
1236#endif
1237#ifndef __NR_ioprio_set
1238#define __NR_ioprio_set 251
1239#endif
1240#ifndef __NR_ioprio_get
1241#define __NR_ioprio_get 252
1242#endif
1243#ifndef __NR_openat
1244#define __NR_openat 257
1245#endif
1246#ifndef __NR_newfstatat
1247#define __NR_newfstatat 262
1248#endif
1249#ifndef __NR_unlinkat
1250#define __NR_unlinkat 263
1251#endif
1252#ifndef __NR_move_pages
1253#define __NR_move_pages 279
1254#endif
1255#ifndef __NR_fallocate
1256#define __NR_fallocate 285
1257#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001258#ifndef __NR_getrandom
1259#define __NR_getrandom 318
1260#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001261/* End of x86-64 definitions */
1262#elif defined(__mips__)
1263#if _MIPS_SIM == _MIPS_SIM_ABI32
1264#ifndef __NR_setresuid
1265#define __NR_setresuid (__NR_Linux + 185)
1266#define __NR_getresuid (__NR_Linux + 186)
1267#define __NR_setresgid (__NR_Linux + 190)
1268#define __NR_getresgid (__NR_Linux + 191)
1269#endif
1270#ifndef __NR_rt_sigaction
1271#define __NR_rt_sigreturn (__NR_Linux + 193)
1272#define __NR_rt_sigaction (__NR_Linux + 194)
1273#define __NR_rt_sigprocmask (__NR_Linux + 195)
1274#define __NR_rt_sigpending (__NR_Linux + 196)
1275#define __NR_rt_sigsuspend (__NR_Linux + 199)
1276#endif
1277#ifndef __NR_pread64
1278#define __NR_pread64 (__NR_Linux + 200)
1279#endif
1280#ifndef __NR_pwrite64
1281#define __NR_pwrite64 (__NR_Linux + 201)
1282#endif
1283#ifndef __NR_stat64
1284#define __NR_stat64 (__NR_Linux + 213)
1285#endif
1286#ifndef __NR_fstat64
1287#define __NR_fstat64 (__NR_Linux + 215)
1288#endif
1289#ifndef __NR_getdents64
1290#define __NR_getdents64 (__NR_Linux + 219)
1291#endif
1292#ifndef __NR_gettid
1293#define __NR_gettid (__NR_Linux + 222)
1294#endif
1295#ifndef __NR_readahead
1296#define __NR_readahead (__NR_Linux + 223)
1297#endif
1298#ifndef __NR_setxattr
1299#define __NR_setxattr (__NR_Linux + 224)
1300#endif
1301#ifndef __NR_lsetxattr
1302#define __NR_lsetxattr (__NR_Linux + 225)
1303#endif
1304#ifndef __NR_getxattr
1305#define __NR_getxattr (__NR_Linux + 227)
1306#endif
1307#ifndef __NR_lgetxattr
1308#define __NR_lgetxattr (__NR_Linux + 228)
1309#endif
1310#ifndef __NR_listxattr
1311#define __NR_listxattr (__NR_Linux + 230)
1312#endif
1313#ifndef __NR_llistxattr
1314#define __NR_llistxattr (__NR_Linux + 231)
1315#endif
1316#ifndef __NR_tkill
1317#define __NR_tkill (__NR_Linux + 236)
1318#endif
1319#ifndef __NR_futex
1320#define __NR_futex (__NR_Linux + 238)
1321#endif
1322#ifndef __NR_sched_setaffinity
1323#define __NR_sched_setaffinity (__NR_Linux + 239)
1324#define __NR_sched_getaffinity (__NR_Linux + 240)
1325#endif
1326#ifndef __NR_set_tid_address
1327#define __NR_set_tid_address (__NR_Linux + 252)
1328#endif
1329#ifndef __NR_statfs64
1330#define __NR_statfs64 (__NR_Linux + 255)
1331#endif
1332#ifndef __NR_fstatfs64
1333#define __NR_fstatfs64 (__NR_Linux + 256)
1334#endif
1335#ifndef __NR_clock_gettime
1336#define __NR_clock_gettime (__NR_Linux + 263)
1337#endif
1338#ifndef __NR_clock_getres
1339#define __NR_clock_getres (__NR_Linux + 264)
1340#endif
1341#ifndef __NR_openat
1342#define __NR_openat (__NR_Linux + 288)
1343#endif
1344#ifndef __NR_fstatat
1345#define __NR_fstatat (__NR_Linux + 293)
1346#endif
1347#ifndef __NR_unlinkat
1348#define __NR_unlinkat (__NR_Linux + 294)
1349#endif
1350#ifndef __NR_move_pages
1351#define __NR_move_pages (__NR_Linux + 308)
1352#endif
1353#ifndef __NR_getcpu
1354#define __NR_getcpu (__NR_Linux + 312)
1355#endif
1356#ifndef __NR_ioprio_set
1357#define __NR_ioprio_set (__NR_Linux + 314)
1358#endif
1359#ifndef __NR_ioprio_get
1360#define __NR_ioprio_get (__NR_Linux + 315)
1361#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001362#ifndef __NR_getrandom
1363#define __NR_getrandom (__NR_Linux + 353)
1364#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001365/* End of MIPS (old 32bit API) definitions */
1366#elif _MIPS_SIM == _MIPS_SIM_ABI64
1367#ifndef __NR_pread64
1368#define __NR_pread64 (__NR_Linux + 16)
1369#endif
1370#ifndef __NR_pwrite64
1371#define __NR_pwrite64 (__NR_Linux + 17)
1372#endif
1373#ifndef __NR_setresuid
1374#define __NR_setresuid (__NR_Linux + 115)
1375#define __NR_getresuid (__NR_Linux + 116)
1376#define __NR_setresgid (__NR_Linux + 117)
1377#define __NR_getresgid (__NR_Linux + 118)
1378#endif
1379#ifndef __NR_gettid
1380#define __NR_gettid (__NR_Linux + 178)
1381#endif
1382#ifndef __NR_readahead
1383#define __NR_readahead (__NR_Linux + 179)
1384#endif
1385#ifndef __NR_setxattr
1386#define __NR_setxattr (__NR_Linux + 180)
1387#endif
1388#ifndef __NR_lsetxattr
1389#define __NR_lsetxattr (__NR_Linux + 181)
1390#endif
1391#ifndef __NR_getxattr
1392#define __NR_getxattr (__NR_Linux + 183)
1393#endif
1394#ifndef __NR_lgetxattr
1395#define __NR_lgetxattr (__NR_Linux + 184)
1396#endif
1397#ifndef __NR_listxattr
1398#define __NR_listxattr (__NR_Linux + 186)
1399#endif
1400#ifndef __NR_llistxattr
1401#define __NR_llistxattr (__NR_Linux + 187)
1402#endif
1403#ifndef __NR_tkill
1404#define __NR_tkill (__NR_Linux + 192)
1405#endif
1406#ifndef __NR_futex
1407#define __NR_futex (__NR_Linux + 194)
1408#endif
1409#ifndef __NR_sched_setaffinity
1410#define __NR_sched_setaffinity (__NR_Linux + 195)
1411#define __NR_sched_getaffinity (__NR_Linux + 196)
1412#endif
1413#ifndef __NR_set_tid_address
1414#define __NR_set_tid_address (__NR_Linux + 212)
1415#endif
1416#ifndef __NR_clock_gettime
1417#define __NR_clock_gettime (__NR_Linux + 222)
1418#endif
1419#ifndef __NR_clock_getres
1420#define __NR_clock_getres (__NR_Linux + 223)
1421#endif
1422#ifndef __NR_openat
1423#define __NR_openat (__NR_Linux + 247)
1424#endif
1425#ifndef __NR_fstatat
1426#define __NR_fstatat (__NR_Linux + 252)
1427#endif
1428#ifndef __NR_unlinkat
1429#define __NR_unlinkat (__NR_Linux + 253)
1430#endif
1431#ifndef __NR_move_pages
1432#define __NR_move_pages (__NR_Linux + 267)
1433#endif
1434#ifndef __NR_getcpu
1435#define __NR_getcpu (__NR_Linux + 271)
1436#endif
1437#ifndef __NR_ioprio_set
1438#define __NR_ioprio_set (__NR_Linux + 273)
1439#endif
1440#ifndef __NR_ioprio_get
1441#define __NR_ioprio_get (__NR_Linux + 274)
1442#endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07001443#ifndef __NT_getrandom
1444#define (__NR_Linux + 313)
1445#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001446/* End of MIPS (64bit API) definitions */
1447#else
1448#ifndef __NR_setresuid
1449#define __NR_setresuid (__NR_Linux + 115)
1450#define __NR_getresuid (__NR_Linux + 116)
1451#define __NR_setresgid (__NR_Linux + 117)
1452#define __NR_getresgid (__NR_Linux + 118)
1453#endif
1454#ifndef __NR_gettid
1455#define __NR_gettid (__NR_Linux + 178)
1456#endif
1457#ifndef __NR_readahead
1458#define __NR_readahead (__NR_Linux + 179)
1459#endif
1460#ifndef __NR_setxattr
1461#define __NR_setxattr (__NR_Linux + 180)
1462#endif
1463#ifndef __NR_lsetxattr
1464#define __NR_lsetxattr (__NR_Linux + 181)
1465#endif
1466#ifndef __NR_getxattr
1467#define __NR_getxattr (__NR_Linux + 183)
1468#endif
1469#ifndef __NR_lgetxattr
1470#define __NR_lgetxattr (__NR_Linux + 184)
1471#endif
1472#ifndef __NR_listxattr
1473#define __NR_listxattr (__NR_Linux + 186)
1474#endif
1475#ifndef __NR_llistxattr
1476#define __NR_llistxattr (__NR_Linux + 187)
1477#endif
1478#ifndef __NR_tkill
1479#define __NR_tkill (__NR_Linux + 192)
1480#endif
1481#ifndef __NR_futex
1482#define __NR_futex (__NR_Linux + 194)
1483#endif
1484#ifndef __NR_sched_setaffinity
1485#define __NR_sched_setaffinity (__NR_Linux + 195)
1486#define __NR_sched_getaffinity (__NR_Linux + 196)
1487#endif
1488#ifndef __NR_set_tid_address
1489#define __NR_set_tid_address (__NR_Linux + 213)
1490#endif
1491#ifndef __NR_statfs64
1492#define __NR_statfs64 (__NR_Linux + 217)
1493#endif
1494#ifndef __NR_fstatfs64
1495#define __NR_fstatfs64 (__NR_Linux + 218)
1496#endif
1497#ifndef __NR_clock_gettime
1498#define __NR_clock_gettime (__NR_Linux + 226)
1499#endif
1500#ifndef __NR_clock_getres
1501#define __NR_clock_getres (__NR_Linux + 227)
1502#endif
1503#ifndef __NR_openat
1504#define __NR_openat (__NR_Linux + 251)
1505#endif
1506#ifndef __NR_fstatat
1507#define __NR_fstatat (__NR_Linux + 256)
1508#endif
1509#ifndef __NR_unlinkat
1510#define __NR_unlinkat (__NR_Linux + 257)
1511#endif
1512#ifndef __NR_move_pages
1513#define __NR_move_pages (__NR_Linux + 271)
1514#endif
1515#ifndef __NR_getcpu
1516#define __NR_getcpu (__NR_Linux + 275)
1517#endif
1518#ifndef __NR_ioprio_set
1519#define __NR_ioprio_set (__NR_Linux + 277)
1520#endif
1521#ifndef __NR_ioprio_get
1522#define __NR_ioprio_get (__NR_Linux + 278)
1523#endif
1524/* End of MIPS (new 32bit API) definitions */
1525#endif
1526/* End of MIPS definitions */
1527#elif defined(__PPC__)
1528#ifndef __NR_setfsuid
1529#define __NR_setfsuid 138
1530#define __NR_setfsgid 139
1531#endif
1532#ifndef __NR_setresuid
1533#define __NR_setresuid 164
1534#define __NR_getresuid 165
1535#define __NR_setresgid 169
1536#define __NR_getresgid 170
1537#endif
1538#ifndef __NR_rt_sigaction
1539#define __NR_rt_sigreturn 172
1540#define __NR_rt_sigaction 173
1541#define __NR_rt_sigprocmask 174
1542#define __NR_rt_sigpending 175
1543#define __NR_rt_sigsuspend 178
1544#endif
1545#ifndef __NR_pread64
1546#define __NR_pread64 179
1547#endif
1548#ifndef __NR_pwrite64
1549#define __NR_pwrite64 180
1550#endif
1551#ifndef __NR_ugetrlimit
1552#define __NR_ugetrlimit 190
1553#endif
1554#ifndef __NR_readahead
1555#define __NR_readahead 191
1556#endif
1557#ifndef __NR_stat64
1558#define __NR_stat64 195
1559#endif
1560#ifndef __NR_fstat64
1561#define __NR_fstat64 197
1562#endif
1563#ifndef __NR_getdents64
1564#define __NR_getdents64 202
1565#endif
1566#ifndef __NR_gettid
1567#define __NR_gettid 207
1568#endif
1569#ifndef __NR_tkill
1570#define __NR_tkill 208
1571#endif
1572#ifndef __NR_setxattr
1573#define __NR_setxattr 209
1574#endif
1575#ifndef __NR_lsetxattr
1576#define __NR_lsetxattr 210
1577#endif
1578#ifndef __NR_getxattr
1579#define __NR_getxattr 212
1580#endif
1581#ifndef __NR_lgetxattr
1582#define __NR_lgetxattr 213
1583#endif
1584#ifndef __NR_listxattr
1585#define __NR_listxattr 215
1586#endif
1587#ifndef __NR_llistxattr
1588#define __NR_llistxattr 216
1589#endif
1590#ifndef __NR_futex
1591#define __NR_futex 221
1592#endif
1593#ifndef __NR_sched_setaffinity
1594#define __NR_sched_setaffinity 222
1595#define __NR_sched_getaffinity 223
1596#endif
1597#ifndef __NR_set_tid_address
1598#define __NR_set_tid_address 232
1599#endif
1600#ifndef __NR_clock_gettime
1601#define __NR_clock_gettime 246
1602#endif
1603#ifndef __NR_clock_getres
1604#define __NR_clock_getres 247
1605#endif
1606#ifndef __NR_statfs64
1607#define __NR_statfs64 252
1608#endif
1609#ifndef __NR_fstatfs64
1610#define __NR_fstatfs64 253
1611#endif
1612#ifndef __NR_fadvise64_64
1613#define __NR_fadvise64_64 254
1614#endif
1615#ifndef __NR_ioprio_set
1616#define __NR_ioprio_set 273
1617#endif
1618#ifndef __NR_ioprio_get
1619#define __NR_ioprio_get 274
1620#endif
1621#ifndef __NR_openat
1622#define __NR_openat 286
1623#endif
1624#ifndef __NR_fstatat64
1625#define __NR_fstatat64 291
1626#endif
1627#ifndef __NR_unlinkat
1628#define __NR_unlinkat 292
1629#endif
1630#ifndef __NR_move_pages
1631#define __NR_move_pages 301
1632#endif
1633#ifndef __NR_getcpu
1634#define __NR_getcpu 302
1635#endif
1636/* End of powerpc defininitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001637#elif defined(__s390__)
1638#ifndef __NR_quotactl
1639#define __NR_quotactl 131
1640#endif
1641#ifndef __NR_rt_sigreturn
1642#define __NR_rt_sigreturn 173
1643#endif
1644#ifndef __NR_rt_sigaction
1645#define __NR_rt_sigaction 174
1646#endif
1647#ifndef __NR_rt_sigprocmask
1648#define __NR_rt_sigprocmask 175
1649#endif
1650#ifndef __NR_rt_sigpending
1651#define __NR_rt_sigpending 176
1652#endif
1653#ifndef __NR_rt_sigsuspend
1654#define __NR_rt_sigsuspend 179
1655#endif
1656#ifndef __NR_pread64
1657#define __NR_pread64 180
1658#endif
1659#ifndef __NR_pwrite64
1660#define __NR_pwrite64 181
1661#endif
1662#ifndef __NR_getdents64
1663#define __NR_getdents64 220
1664#endif
1665#ifndef __NR_readahead
1666#define __NR_readahead 222
1667#endif
1668#ifndef __NR_setxattr
1669#define __NR_setxattr 224
1670#endif
1671#ifndef __NR_lsetxattr
1672#define __NR_lsetxattr 225
1673#endif
1674#ifndef __NR_getxattr
1675#define __NR_getxattr 227
1676#endif
1677#ifndef __NR_lgetxattr
1678#define __NR_lgetxattr 228
1679#endif
1680#ifndef __NR_listxattr
1681#define __NR_listxattr 230
1682#endif
1683#ifndef __NR_llistxattr
1684#define __NR_llistxattr 231
1685#endif
1686#ifndef __NR_gettid
1687#define __NR_gettid 236
1688#endif
1689#ifndef __NR_tkill
1690#define __NR_tkill 237
1691#endif
1692#ifndef __NR_futex
1693#define __NR_futex 238
1694#endif
1695#ifndef __NR_sched_setaffinity
1696#define __NR_sched_setaffinity 239
1697#endif
1698#ifndef __NR_sched_getaffinity
1699#define __NR_sched_getaffinity 240
1700#endif
1701#ifndef __NR_set_tid_address
1702#define __NR_set_tid_address 252
1703#endif
1704#ifndef __NR_clock_gettime
1705#define __NR_clock_gettime 260
1706#endif
1707#ifndef __NR_clock_getres
1708#define __NR_clock_getres 261
1709#endif
1710#ifndef __NR_statfs64
1711#define __NR_statfs64 265
1712#endif
1713#ifndef __NR_fstatfs64
1714#define __NR_fstatfs64 266
1715#endif
1716#ifndef __NR_ioprio_set
1717#define __NR_ioprio_set 282
1718#endif
1719#ifndef __NR_ioprio_get
1720#define __NR_ioprio_get 283
1721#endif
1722#ifndef __NR_openat
1723#define __NR_openat 288
1724#endif
1725#ifndef __NR_unlinkat
1726#define __NR_unlinkat 294
1727#endif
1728#ifndef __NR_move_pages
1729#define __NR_move_pages 310
1730#endif
1731#ifndef __NR_getcpu
1732#define __NR_getcpu 311
1733#endif
1734#ifndef __NR_fallocate
1735#define __NR_fallocate 314
1736#endif
1737/* Some syscalls are named/numbered differently between s390 and s390x. */
1738#ifdef __s390x__
1739# ifndef __NR_getrlimit
1740# define __NR_getrlimit 191
1741# endif
1742# ifndef __NR_setresuid
1743# define __NR_setresuid 208
1744# endif
1745# ifndef __NR_getresuid
1746# define __NR_getresuid 209
1747# endif
1748# ifndef __NR_setresgid
1749# define __NR_setresgid 210
1750# endif
1751# ifndef __NR_getresgid
1752# define __NR_getresgid 211
1753# endif
1754# ifndef __NR_setfsuid
1755# define __NR_setfsuid 215
1756# endif
1757# ifndef __NR_setfsgid
1758# define __NR_setfsgid 216
1759# endif
1760# ifndef __NR_fadvise64
1761# define __NR_fadvise64 253
1762# endif
1763# ifndef __NR_newfstatat
1764# define __NR_newfstatat 293
1765# endif
1766#else /* __s390x__ */
1767# ifndef __NR_getrlimit
1768# define __NR_getrlimit 76
1769# endif
1770# ifndef __NR_setfsuid
1771# define __NR_setfsuid 138
1772# endif
1773# ifndef __NR_setfsgid
1774# define __NR_setfsgid 139
1775# endif
1776# ifndef __NR_setresuid
1777# define __NR_setresuid 164
1778# endif
1779# ifndef __NR_getresuid
1780# define __NR_getresuid 165
1781# endif
1782# ifndef __NR_setresgid
1783# define __NR_setresgid 170
1784# endif
1785# ifndef __NR_getresgid
1786# define __NR_getresgid 171
1787# endif
1788# ifndef __NR_ugetrlimit
1789# define __NR_ugetrlimit 191
1790# endif
1791# ifndef __NR_mmap2
1792# define __NR_mmap2 192
1793# endif
1794# ifndef __NR_setresuid32
1795# define __NR_setresuid32 208
1796# endif
1797# ifndef __NR_getresuid32
1798# define __NR_getresuid32 209
1799# endif
1800# ifndef __NR_setresgid32
1801# define __NR_setresgid32 210
1802# endif
1803# ifndef __NR_getresgid32
1804# define __NR_getresgid32 211
1805# endif
1806# ifndef __NR_setfsuid32
1807# define __NR_setfsuid32 215
1808# endif
1809# ifndef __NR_setfsgid32
1810# define __NR_setfsgid32 216
1811# endif
1812# ifndef __NR_fadvise64_64
1813# define __NR_fadvise64_64 264
1814# endif
1815# ifndef __NR_fstatat64
1816# define __NR_fstatat64 293
1817# endif
1818#endif /* __s390__ */
1819/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001820#endif
1821
1822
1823/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001824#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001825 #error "Need to port invocations of syscalls for bounded ptrs"
1826#else
1827 /* The core dumper and the thread lister get executed after threads
1828 * have been suspended. As a consequence, we cannot call any functions
1829 * that acquire locks. Unfortunately, libc wraps most system calls
1830 * (e.g. in order to implement pthread_atfork, and to make calls
1831 * cancellable), which means we cannot call these functions. Instead,
1832 * we have to call syscall() directly.
1833 */
1834 #undef LSS_ERRNO
1835 #ifdef SYS_ERRNO
1836 /* Allow the including file to override the location of errno. This can
1837 * be useful when using clone() with the CLONE_VM option.
1838 */
1839 #define LSS_ERRNO SYS_ERRNO
1840 #else
1841 #define LSS_ERRNO errno
1842 #endif
1843
1844 #undef LSS_INLINE
1845 #ifdef SYS_INLINE
1846 #define LSS_INLINE SYS_INLINE
1847 #else
1848 #define LSS_INLINE static inline
1849 #endif
1850
1851 /* Allow the including file to override the prefix used for all new
1852 * system calls. By default, it will be set to "sys_".
1853 */
1854 #undef LSS_NAME
1855 #ifndef SYS_PREFIX
1856 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001857 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001858 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001859 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001860 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001861 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001862 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001863 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001864 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001865 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001866 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001867 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001868 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001869 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001870 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001871 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001872 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001873 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001874 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001875 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001876 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001877 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001878 #define LSS_NAME(name) sys9_##name
1879 #endif
1880
1881 #undef LSS_RETURN
1882 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
Bryan Chan3f6478a2016-06-14 08:38:17 -04001883 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001884 /* Failing system calls return a negative result in the range of
1885 * -1..-4095. These are "errno" values with the sign inverted.
1886 */
1887 #define LSS_RETURN(type, res) \
1888 do { \
1889 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
1890 LSS_ERRNO = -(res); \
1891 res = -1; \
1892 } \
1893 return (type) (res); \
1894 } while (0)
1895 #elif defined(__mips__)
1896 /* On MIPS, failing system calls return -1, and set errno in a
1897 * separate CPU register.
1898 */
1899 #define LSS_RETURN(type, res, err) \
1900 do { \
1901 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00001902 unsigned long __errnovalue = (res); \
1903 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001904 res = -1; \
1905 } \
1906 return (type) (res); \
1907 } while (0)
1908 #elif defined(__PPC__)
1909 /* On PPC, failing system calls return -1, and set errno in a
1910 * separate CPU register. See linux/unistd.h.
1911 */
1912 #define LSS_RETURN(type, res, err) \
1913 do { \
1914 if (err & 0x10000000 ) { \
1915 LSS_ERRNO = (res); \
1916 res = -1; \
1917 } \
1918 return (type) (res); \
1919 } while (0)
1920 #endif
1921 #if defined(__i386__)
1922 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1923 * reserves ebx. Unfortunately, most distribution ship with implementations
1924 * of _syscallX() which clobber ebx.
1925 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1926 * clobbered. This causes problems with compilers, that do a better job
1927 * at optimizing across __asm__ calls.
1928 * So, we just have to redefine all of the _syscallX() macros.
1929 */
1930 #undef LSS_ENTRYPOINT
1931 #ifdef SYS_SYSCALL_ENTRYPOINT
1932 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1933 void (**entrypoint)(void);
1934 asm volatile(".bss\n"
1935 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001936 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1937 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001938 ".previous\n"
1939 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
1940 "call 0f\n"
1941 "0:pop %0\n"
1942 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001943 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001944 : "=r"(entrypoint));
1945 return entrypoint;
1946 }
1947
1948 #define LSS_ENTRYPOINT ".bss\n" \
1949 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001950 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
1951 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001952 ".previous\n" \
1953 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
1954 "push %%eax\n" \
1955 "call 10000f\n" \
1956 "10000:pop %%eax\n" \
1957 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001958 "mov " SYS_SYSCALL_ENTRYPOINT \
1959 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001960 "mov 0(%%eax), %%eax\n" \
1961 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001962 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001963 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001964 "call 10001f\n" \
1965 "10001:pop %%eax\n" \
1966 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001967 "xchg 4(%%esp), %%eax\n" \
1968 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001969 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001970 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001971 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001972 #else
1973 #define LSS_ENTRYPOINT "int $0x80\n"
1974 #endif
1975 #undef LSS_BODY
1976 #define LSS_BODY(type,args...) \
1977 long __res; \
1978 __asm__ __volatile__("push %%ebx\n" \
1979 "movl %2,%%ebx\n" \
1980 LSS_ENTRYPOINT \
1981 "pop %%ebx" \
1982 args \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07001983 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001984 LSS_RETURN(type,__res)
1985 #undef _syscall0
1986 #define _syscall0(type,name) \
1987 type LSS_NAME(name)(void) { \
1988 long __res; \
1989 __asm__ volatile(LSS_ENTRYPOINT \
1990 : "=a" (__res) \
1991 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08001992 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001993 LSS_RETURN(type,__res); \
1994 }
1995 #undef _syscall1
1996 #define _syscall1(type,name,type1,arg1) \
1997 type LSS_NAME(name)(type1 arg1) { \
1998 LSS_BODY(type, \
1999 : "=a" (__res) \
2000 : "0" (__NR_##name), "ri" ((long)(arg1))); \
2001 }
2002 #undef _syscall2
2003 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2004 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
2005 LSS_BODY(type, \
2006 : "=a" (__res) \
2007 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
2008 }
2009 #undef _syscall3
2010 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2011 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
2012 LSS_BODY(type, \
2013 : "=a" (__res) \
2014 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2015 "d" ((long)(arg3))); \
2016 }
2017 #undef _syscall4
2018 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2019 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2020 LSS_BODY(type, \
2021 : "=a" (__res) \
2022 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2023 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2024 }
2025 #undef _syscall5
2026 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2027 type5,arg5) \
2028 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2029 type5 arg5) { \
2030 long __res; \
2031 __asm__ __volatile__("push %%ebx\n" \
2032 "movl %2,%%ebx\n" \
2033 "movl %1,%%eax\n" \
2034 LSS_ENTRYPOINT \
2035 "pop %%ebx" \
2036 : "=a" (__res) \
2037 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2038 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2039 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002040 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002041 LSS_RETURN(type,__res); \
2042 }
2043 #undef _syscall6
2044 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2045 type5,arg5,type6,arg6) \
2046 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2047 type5 arg5, type6 arg6) { \
2048 long __res; \
2049 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2050 __asm__ __volatile__("push %%ebp\n" \
2051 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002052 "movl 4(%2),%%ebp\n" \
2053 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002054 "movl %1,%%eax\n" \
2055 LSS_ENTRYPOINT \
2056 "pop %%ebx\n" \
2057 "pop %%ebp" \
2058 : "=a" (__res) \
2059 : "i" (__NR_##name), "0" ((long)(&__s)), \
2060 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2061 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002062 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002063 LSS_RETURN(type,__res); \
2064 }
2065 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2066 int flags, void *arg, int *parent_tidptr,
2067 void *newtls, int *child_tidptr) {
2068 long __res;
2069 __asm__ __volatile__(/* if (fn == NULL)
2070 * return -EINVAL;
2071 */
2072 "movl %3,%%ecx\n"
2073 "jecxz 1f\n"
2074
2075 /* if (child_stack == NULL)
2076 * return -EINVAL;
2077 */
2078 "movl %4,%%ecx\n"
2079 "jecxz 1f\n"
2080
2081 /* Set up alignment of the child stack:
2082 * child_stack = (child_stack & ~0xF) - 20;
2083 */
2084 "andl $-16,%%ecx\n"
2085 "subl $20,%%ecx\n"
2086
2087 /* Push "arg" and "fn" onto the stack that will be
2088 * used by the child.
2089 */
2090 "movl %6,%%eax\n"
2091 "movl %%eax,4(%%ecx)\n"
2092 "movl %3,%%eax\n"
2093 "movl %%eax,(%%ecx)\n"
2094
2095 /* %eax = syscall(%eax = __NR_clone,
2096 * %ebx = flags,
2097 * %ecx = child_stack,
2098 * %edx = parent_tidptr,
2099 * %esi = newtls,
2100 * %edi = child_tidptr)
2101 * Also, make sure that %ebx gets preserved as it is
2102 * used in PIC mode.
2103 */
2104 "movl %8,%%esi\n"
2105 "movl %7,%%edx\n"
2106 "movl %5,%%eax\n"
2107 "movl %9,%%edi\n"
2108 "pushl %%ebx\n"
2109 "movl %%eax,%%ebx\n"
2110 "movl %2,%%eax\n"
2111 LSS_ENTRYPOINT
2112
2113 /* In the parent: restore %ebx
2114 * In the child: move "fn" into %ebx
2115 */
2116 "popl %%ebx\n"
2117
2118 /* if (%eax != 0)
2119 * return %eax;
2120 */
2121 "test %%eax,%%eax\n"
2122 "jnz 1f\n"
2123
2124 /* In the child, now. Terminate frame pointer chain.
2125 */
2126 "movl $0,%%ebp\n"
2127
2128 /* Call "fn". "arg" is already on the stack.
2129 */
2130 "call *%%ebx\n"
2131
2132 /* Call _exit(%ebx). Unfortunately older versions
2133 * of gcc restrict the number of arguments that can
2134 * be passed to asm(). So, we need to hard-code the
2135 * system call number.
2136 */
2137 "movl %%eax,%%ebx\n"
2138 "movl $1,%%eax\n"
2139 LSS_ENTRYPOINT
2140
2141 /* Return to parent.
2142 */
2143 "1:\n"
2144 : "=a" (__res)
2145 : "0"(-EINVAL), "i"(__NR_clone),
2146 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2147 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002148 : "memory", "ecx", "edx", "esi", "edi");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002149 LSS_RETURN(int, __res);
2150 }
2151
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002152 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2153 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2154
2155 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2156 /* On i386, the kernel does not know how to return from a signal
2157 * handler. Instead, it relies on user space to provide a
2158 * restorer function that calls the {rt_,}sigreturn() system call.
2159 * Unfortunately, we cannot just reference the glibc version of this
2160 * function, as glibc goes out of its way to make it inaccessible.
2161 */
2162 void (*res)(void);
2163 __asm__ __volatile__("call 2f\n"
2164 "0:.align 16\n"
2165 "1:movl %1,%%eax\n"
2166 LSS_ENTRYPOINT
2167 "2:popl %0\n"
2168 "addl $(1b-0b),%0\n"
2169 : "=a" (res)
2170 : "i" (__NR_rt_sigreturn));
2171 return res;
2172 }
2173 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
2174 /* On i386, the kernel does not know how to return from a signal
2175 * handler. Instead, it relies on user space to provide a
2176 * restorer function that calls the {rt_,}sigreturn() system call.
2177 * Unfortunately, we cannot just reference the glibc version of this
2178 * function, as glibc goes out of its way to make it inaccessible.
2179 */
2180 void (*res)(void);
2181 __asm__ __volatile__("call 2f\n"
2182 "0:.align 16\n"
2183 "1:pop %%eax\n"
2184 "movl %1,%%eax\n"
2185 LSS_ENTRYPOINT
2186 "2:popl %0\n"
2187 "addl $(1b-0b),%0\n"
2188 : "=a" (res)
2189 : "i" (__NR_sigreturn));
2190 return res;
2191 }
2192 #elif defined(__x86_64__)
2193 /* There are no known problems with any of the _syscallX() macros
2194 * currently shipping for x86_64, but we still need to be able to define
2195 * our own version so that we can override the location of the errno
2196 * location (e.g. when using the clone() system call with the CLONE_VM
2197 * option).
2198 */
2199 #undef LSS_ENTRYPOINT
2200 #ifdef SYS_SYSCALL_ENTRYPOINT
2201 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2202 void (**entrypoint)(void);
2203 asm volatile(".bss\n"
2204 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002205 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2206 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002207 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002208 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002209 : "=r"(entrypoint));
2210 return entrypoint;
2211 }
2212
2213 #define LSS_ENTRYPOINT \
2214 ".bss\n" \
2215 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002216 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2217 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002218 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002219 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002220 "mov 0(%%rcx), %%rcx\n" \
2221 "test %%rcx, %%rcx\n" \
2222 "jz 10001f\n" \
2223 "call *%%rcx\n" \
2224 "jmp 10002f\n" \
2225 "10001:syscall\n" \
2226 "10002:\n"
2227
2228 #else
2229 #define LSS_ENTRYPOINT "syscall\n"
2230 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002231
2232 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2233 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2234 * sign extension. We can't cast pointers directly because those are
2235 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2236 * to an integer of a different size.
2237 */
2238 #undef LSS_SYSCALL_ARG
2239 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2240 #undef _LSS_RETURN
2241 #define _LSS_RETURN(type, res, cast) \
2242 do { \
2243 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
2244 LSS_ERRNO = -(res); \
2245 res = -1; \
2246 } \
2247 return (type)(cast)(res); \
2248 } while (0)
2249 #undef LSS_RETURN
2250 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2251
2252 #undef _LSS_BODY
2253 #define _LSS_BODY(nr, type, name, cast, ...) \
2254 long long __res; \
2255 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2256 : "=a" (__res) \
2257 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2258 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2259 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002260 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002261 #define LSS_BODY(nr, type, name, args...) \
2262 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2263
2264 #undef LSS_BODY_ASM0
2265 #undef LSS_BODY_ASM1
2266 #undef LSS_BODY_ASM2
2267 #undef LSS_BODY_ASM3
2268 #undef LSS_BODY_ASM4
2269 #undef LSS_BODY_ASM5
2270 #undef LSS_BODY_ASM6
2271 #define LSS_BODY_ASM0
2272 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2273 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2274 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2275 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2276 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2277 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2278
2279 #undef LSS_BODY_CLOBBER0
2280 #undef LSS_BODY_CLOBBER1
2281 #undef LSS_BODY_CLOBBER2
2282 #undef LSS_BODY_CLOBBER3
2283 #undef LSS_BODY_CLOBBER4
2284 #undef LSS_BODY_CLOBBER5
2285 #undef LSS_BODY_CLOBBER6
2286 #define LSS_BODY_CLOBBER0
2287 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2288 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2289 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2290 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2291 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2292 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2293
2294 #undef LSS_BODY_ARG0
2295 #undef LSS_BODY_ARG1
2296 #undef LSS_BODY_ARG2
2297 #undef LSS_BODY_ARG3
2298 #undef LSS_BODY_ARG4
2299 #undef LSS_BODY_ARG5
2300 #undef LSS_BODY_ARG6
2301 #define LSS_BODY_ARG0()
2302 #define LSS_BODY_ARG1(arg1) \
2303 LSS_BODY_ARG0(), "D" (arg1)
2304 #define LSS_BODY_ARG2(arg1, arg2) \
2305 LSS_BODY_ARG1(arg1), "S" (arg2)
2306 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2307 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2308 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2309 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2310 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2311 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2312 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2313 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2314
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002315 #undef _syscall0
2316 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002317 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002318 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002319 }
2320 #undef _syscall1
2321 #define _syscall1(type,name,type1,arg1) \
2322 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002323 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002324 }
2325 #undef _syscall2
2326 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2327 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002328 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002329 }
2330 #undef _syscall3
2331 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2332 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002333 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2334 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002335 }
2336 #undef _syscall4
2337 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2338 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002339 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2340 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002341 }
2342 #undef _syscall5
2343 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2344 type5,arg5) \
2345 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2346 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002347 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2348 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2349 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002350 }
2351 #undef _syscall6
2352 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2353 type5,arg5,type6,arg6) \
2354 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2355 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002356 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2357 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2358 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002359 }
2360 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2361 int flags, void *arg, int *parent_tidptr,
2362 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002363 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002364 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002365 __asm__ __volatile__(/* if (fn == NULL)
2366 * return -EINVAL;
2367 */
2368 "testq %4,%4\n"
2369 "jz 1f\n"
2370
2371 /* if (child_stack == NULL)
2372 * return -EINVAL;
2373 */
2374 "testq %5,%5\n"
2375 "jz 1f\n"
2376
2377 /* childstack -= 2*sizeof(void *);
2378 */
2379 "subq $16,%5\n"
2380
2381 /* Push "arg" and "fn" onto the stack that will be
2382 * used by the child.
2383 */
2384 "movq %7,8(%5)\n"
2385 "movq %4,0(%5)\n"
2386
2387 /* %rax = syscall(%rax = __NR_clone,
2388 * %rdi = flags,
2389 * %rsi = child_stack,
2390 * %rdx = parent_tidptr,
2391 * %r8 = new_tls,
2392 * %r10 = child_tidptr)
2393 */
2394 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002395 "movq %9,%%r8\n"
2396 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002397 LSS_ENTRYPOINT
2398
2399 /* if (%rax != 0)
2400 * return;
2401 */
2402 "testq %%rax,%%rax\n"
2403 "jnz 1f\n"
2404
2405 /* In the child. Terminate frame pointer chain.
2406 */
2407 "xorq %%rbp,%%rbp\n"
2408
2409 /* Call "fn(arg)".
2410 */
2411 "popq %%rax\n"
2412 "popq %%rdi\n"
2413 "call *%%rax\n"
2414
2415 /* Call _exit(%ebx).
2416 */
2417 "movq %%rax,%%rdi\n"
2418 "movq %3,%%rax\n"
2419 LSS_ENTRYPOINT
2420
2421 /* Return to parent.
2422 */
2423 "1:\n"
2424 : "=a" (__res)
2425 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002426 "r"(LSS_SYSCALL_ARG(fn)),
2427 "S"(LSS_SYSCALL_ARG(child_stack)),
2428 "D"(LSS_SYSCALL_ARG(flags)),
2429 "r"(LSS_SYSCALL_ARG(arg)),
2430 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2431 "r"(LSS_SYSCALL_ARG(newtls)),
2432 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002433 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002434 }
2435 LSS_RETURN(int, __res);
2436 }
2437 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002438
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002439 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2440 /* On x86-64, the kernel does not know how to return from
2441 * a signal handler. Instead, it relies on user space to provide a
2442 * restorer function that calls the rt_sigreturn() system call.
2443 * Unfortunately, we cannot just reference the glibc version of this
2444 * function, as glibc goes out of its way to make it inaccessible.
2445 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002446 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002447 __asm__ __volatile__("jmp 2f\n"
2448 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002449 "1:movq %1,%%rax\n"
2450 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002451 "2:leaq 1b(%%rip),%0\n"
2452 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002453 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002454 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002455 }
2456 #elif defined(__ARM_ARCH_3__)
2457 /* Most definitions of _syscallX() neglect to mark "memory" as being
2458 * clobbered. This causes problems with compilers, that do a better job
2459 * at optimizing across __asm__ calls.
2460 * So, we just have to redefine all of the _syscallX() macros.
2461 */
2462 #undef LSS_REG
2463 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2464 #undef LSS_BODY
2465 #define LSS_BODY(type,name,args...) \
2466 register long __res_r0 __asm__("r0"); \
2467 long __res; \
2468 __asm__ __volatile__ (__syscall(name) \
2469 : "=r"(__res_r0) : args : "lr", "memory"); \
2470 __res = __res_r0; \
2471 LSS_RETURN(type, __res)
2472 #undef _syscall0
2473 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002474 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002475 LSS_BODY(type, name); \
2476 }
2477 #undef _syscall1
2478 #define _syscall1(type, name, type1, arg1) \
2479 type LSS_NAME(name)(type1 arg1) { \
2480 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2481 }
2482 #undef _syscall2
2483 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2484 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2485 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2486 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2487 }
2488 #undef _syscall3
2489 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2490 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2491 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2492 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2493 }
2494 #undef _syscall4
2495 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2496 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2497 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2498 LSS_REG(3, arg4); \
2499 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2500 }
2501 #undef _syscall5
2502 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2503 type5,arg5) \
2504 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2505 type5 arg5) { \
2506 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2507 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2508 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2509 "r"(__r4)); \
2510 }
2511 #undef _syscall6
2512 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2513 type5,arg5,type6,arg6) \
2514 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2515 type5 arg5, type6 arg6) { \
2516 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2517 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2518 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2519 "r"(__r4), "r"(__r5)); \
2520 }
2521 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2522 int flags, void *arg, int *parent_tidptr,
2523 void *newtls, int *child_tidptr) {
2524 long __res;
2525 {
2526 register int __flags __asm__("r0") = flags;
2527 register void *__stack __asm__("r1") = child_stack;
2528 register void *__ptid __asm__("r2") = parent_tidptr;
2529 register void *__tls __asm__("r3") = newtls;
2530 register int *__ctid __asm__("r4") = child_tidptr;
2531 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2532 * return -EINVAL;
2533 */
2534 "cmp %2,#0\n"
2535 "cmpne %3,#0\n"
2536 "moveq %0,%1\n"
2537 "beq 1f\n"
2538
2539 /* Push "arg" and "fn" onto the stack that will be
2540 * used by the child.
2541 */
2542 "str %5,[%3,#-4]!\n"
2543 "str %2,[%3,#-4]!\n"
2544
2545 /* %r0 = syscall(%r0 = flags,
2546 * %r1 = child_stack,
2547 * %r2 = parent_tidptr,
2548 * %r3 = newtls,
2549 * %r4 = child_tidptr)
2550 */
2551 __syscall(clone)"\n"
2552
2553 /* if (%r0 != 0)
2554 * return %r0;
2555 */
2556 "movs %0,r0\n"
2557 "bne 1f\n"
2558
2559 /* In the child, now. Call "fn(arg)".
2560 */
2561 "ldr r0,[sp, #4]\n"
2562 "mov lr,pc\n"
2563 "ldr pc,[sp]\n"
2564
2565 /* Call _exit(%r0).
2566 */
2567 __syscall(exit)"\n"
2568 "1:\n"
2569 : "=r" (__res)
2570 : "i"(-EINVAL),
2571 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2572 "r"(__ptid), "r"(__tls), "r"(__ctid)
2573 : "cc", "lr", "memory");
2574 }
2575 LSS_RETURN(int, __res);
2576 }
2577 #elif defined(__ARM_EABI__)
2578 /* Most definitions of _syscallX() neglect to mark "memory" as being
2579 * clobbered. This causes problems with compilers, that do a better job
2580 * at optimizing across __asm__ calls.
2581 * So, we just have to redefine all fo the _syscallX() macros.
2582 */
2583 #undef LSS_REG
2584 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2585 #undef LSS_BODY
2586 #define LSS_BODY(type,name,args...) \
2587 register long __res_r0 __asm__("r0"); \
2588 long __res; \
2589 __asm__ __volatile__ ("push {r7}\n" \
2590 "mov r7, %1\n" \
2591 "swi 0x0\n" \
2592 "pop {r7}\n" \
2593 : "=r"(__res_r0) \
2594 : "i"(__NR_##name) , ## args \
2595 : "lr", "memory"); \
2596 __res = __res_r0; \
2597 LSS_RETURN(type, __res)
2598 #undef _syscall0
2599 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002600 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002601 LSS_BODY(type, name); \
2602 }
2603 #undef _syscall1
2604 #define _syscall1(type, name, type1, arg1) \
2605 type LSS_NAME(name)(type1 arg1) { \
2606 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2607 }
2608 #undef _syscall2
2609 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2610 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2611 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2612 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2613 }
2614 #undef _syscall3
2615 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2616 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2617 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2618 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2619 }
2620 #undef _syscall4
2621 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2622 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2623 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2624 LSS_REG(3, arg4); \
2625 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2626 }
2627 #undef _syscall5
2628 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2629 type5,arg5) \
2630 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2631 type5 arg5) { \
2632 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2633 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2634 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2635 "r"(__r4)); \
2636 }
2637 #undef _syscall6
2638 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2639 type5,arg5,type6,arg6) \
2640 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2641 type5 arg5, type6 arg6) { \
2642 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2643 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2644 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2645 "r"(__r4), "r"(__r5)); \
2646 }
2647 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2648 int flags, void *arg, int *parent_tidptr,
2649 void *newtls, int *child_tidptr) {
2650 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002651 if (fn == NULL || child_stack == NULL) {
2652 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002653 LSS_RETURN(int, __res);
2654 }
2655
2656 /* Push "arg" and "fn" onto the stack that will be
2657 * used by the child.
2658 */
2659 {
2660 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2661 cstack[0] = (uintptr_t)fn;
2662 cstack[1] = (uintptr_t)arg;
2663 child_stack = cstack;
2664 }
2665 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002666 register int __flags __asm__("r0") = flags;
2667 register void *__stack __asm__("r1") = child_stack;
2668 register void *__ptid __asm__("r2") = parent_tidptr;
2669 register void *__tls __asm__("r3") = newtls;
2670 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002671 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002672#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002673 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002674#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002675 /* %r0 = syscall(%r0 = flags,
2676 * %r1 = child_stack,
2677 * %r2 = parent_tidptr,
2678 * %r3 = newtls,
2679 * %r4 = child_tidptr)
2680 */
2681 "mov r7, %6\n"
2682 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002683
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002684 /* if (%r0 != 0)
2685 * return %r0;
2686 */
2687 "cmp r0, #0\n"
2688 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002689
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002690 /* In the child, now. Call "fn(arg)".
2691 */
2692 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002693
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002694 "ldr lr,[sp]\n"
2695 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002696
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002697 /* Call _exit(%r0).
2698 */
2699 "mov r7, %7\n"
2700 "swi 0x0\n"
2701 /* Unreachable */
2702 "bkpt #0\n"
2703 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002704#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002705 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002706#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002707 "movs %0,r0\n"
2708 : "=r"(__res)
2709 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2710 "i"(__NR_clone), "i"(__NR_exit)
2711 : "cc", "lr", "memory"
2712#ifndef __thumb2__
2713 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002714#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002715 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002716 }
2717 LSS_RETURN(int, __res);
2718 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002719 #elif defined(__aarch64__)
2720 /* Most definitions of _syscallX() neglect to mark "memory" as being
2721 * clobbered. This causes problems with compilers, that do a better job
2722 * at optimizing across __asm__ calls.
2723 * So, we just have to redefine all of the _syscallX() macros.
2724 */
2725 #undef LSS_REG
2726 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2727 #undef LSS_BODY
2728 #define LSS_BODY(type,name,args...) \
2729 register int64_t __res_x0 __asm__("x0"); \
2730 int64_t __res; \
2731 __asm__ __volatile__ ("mov x8, %1\n" \
2732 "svc 0x0\n" \
2733 : "=r"(__res_x0) \
2734 : "i"(__NR_##name) , ## args \
2735 : "x8", "memory"); \
2736 __res = __res_x0; \
2737 LSS_RETURN(type, __res)
2738 #undef _syscall0
2739 #define _syscall0(type, name) \
2740 type LSS_NAME(name)(void) { \
2741 LSS_BODY(type, name); \
2742 }
2743 #undef _syscall1
2744 #define _syscall1(type, name, type1, arg1) \
2745 type LSS_NAME(name)(type1 arg1) { \
2746 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2747 }
2748 #undef _syscall2
2749 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2750 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2751 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2752 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2753 }
2754 #undef _syscall3
2755 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2756 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2757 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2758 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2759 }
2760 #undef _syscall4
2761 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2762 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2763 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2764 LSS_REG(3, arg4); \
2765 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2766 }
2767 #undef _syscall5
2768 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2769 type5,arg5) \
2770 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2771 type5 arg5) { \
2772 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2773 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2774 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2775 "r"(__r4)); \
2776 }
2777 #undef _syscall6
2778 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2779 type5,arg5,type6,arg6) \
2780 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2781 type5 arg5, type6 arg6) { \
2782 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2783 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2784 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2785 "r"(__r4), "r"(__r5)); \
2786 }
2787
2788 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2789 int flags, void *arg, int *parent_tidptr,
2790 void *newtls, int *child_tidptr) {
2791 int64_t __res;
2792 {
2793 register uint64_t __flags __asm__("x0") = flags;
2794 register void *__stack __asm__("x1") = child_stack;
2795 register void *__ptid __asm__("x2") = parent_tidptr;
2796 register void *__tls __asm__("x3") = newtls;
2797 register int *__ctid __asm__("x4") = child_tidptr;
2798 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2799 * used by the child.
2800 */
2801 "stp %1, %4, [%2, #-16]!\n"
2802
2803 /* %x0 = syscall(%x0 = flags,
2804 * %x1 = child_stack,
2805 * %x2 = parent_tidptr,
2806 * %x3 = newtls,
2807 * %x4 = child_tidptr)
2808 */
2809 "mov x8, %8\n"
2810 "svc 0x0\n"
2811
2812 /* if (%r0 != 0)
2813 * return %r0;
2814 */
2815 "mov %0, x0\n"
2816 "cbnz x0, 1f\n"
2817
2818 /* In the child, now. Call "fn(arg)".
2819 */
2820 "ldp x1, x0, [sp], #16\n"
2821 "blr x1\n"
2822
2823 /* Call _exit(%r0).
2824 */
2825 "mov x8, %9\n"
2826 "svc 0x0\n"
2827 "1:\n"
2828 : "=r" (__res)
2829 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2830 "r"(__ptid), "r"(__tls), "r"(__ctid),
2831 "i"(__NR_clone), "i"(__NR_exit)
2832 : "cc", "x8", "memory");
2833 }
2834 LSS_RETURN(int, __res);
2835 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002836 #elif defined(__mips__)
2837 #undef LSS_REG
2838 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2839 (unsigned long)(a)
2840 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002841 #undef LSS_SYSCALL_CLOBBERS
2842 #if _MIPS_SIM == _MIPS_SIM_ABI32
2843 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2844 "$11", "$12", "$13", "$14", "$15", \
2845 "$24", "$25", "hi", "lo", "memory"
2846 #else
2847 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2848 "$13", "$14", "$15", "$24", "$25", \
2849 "hi", "lo", "memory"
2850 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002851 #define LSS_BODY(type,name,r7,...) \
2852 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2853 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002854 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002855 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002856 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002857 LSS_RETURN(type, __v0, __r7)
2858 #undef _syscall0
2859 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002860 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002861 register unsigned long __r7 __asm__("$7"); \
2862 LSS_BODY(type, name, "=r"); \
2863 }
2864 #undef _syscall1
2865 #define _syscall1(type, name, type1, arg1) \
2866 type LSS_NAME(name)(type1 arg1) { \
2867 register unsigned long __r7 __asm__("$7"); \
2868 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2869 }
2870 #undef _syscall2
2871 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2872 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2873 register unsigned long __r7 __asm__("$7"); \
2874 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2875 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2876 }
2877 #undef _syscall3
2878 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2879 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2880 register unsigned long __r7 __asm__("$7"); \
2881 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2882 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2883 }
2884 #undef _syscall4
2885 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2886 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2887 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2888 LSS_REG(7, arg4); \
2889 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2890 }
2891 #undef _syscall5
2892 #if _MIPS_SIM == _MIPS_SIM_ABI32
2893 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2894 * on the stack, whereas the new APIs use registers "r8" and "r9".
2895 */
2896 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2897 type5,arg5) \
2898 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2899 type5 arg5) { \
2900 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2901 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002902 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002903 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002904 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002905 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002906 "syscall\n" \
2907 "addiu $29, 32\n" \
2908 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002909 : "+r"(__v0), "+r" (__r7) \
2910 : "r"(__r4), "r"(__r5), \
2911 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002912 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002913 "$13", "$14", "$15", "$24", "$25", \
2914 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002915 LSS_RETURN(type, __v0, __r7); \
2916 }
2917 #else
2918 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2919 type5,arg5) \
2920 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2921 type5 arg5) { \
2922 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2923 LSS_REG(7, arg4); LSS_REG(8, arg5); \
2924 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2925 "r"(__r8)); \
2926 }
2927 #endif
2928 #undef _syscall6
2929 #if _MIPS_SIM == _MIPS_SIM_ABI32
2930 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2931 * on the stack, whereas the new APIs use registers "r8" and "r9".
2932 */
2933 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2934 type5,arg5,type6,arg6) \
2935 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2936 type5 arg5, type6 arg6) { \
2937 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2938 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002939 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002940 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002941 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002942 "sw %5, 16($29)\n" \
2943 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002944 "syscall\n" \
2945 "addiu $29, 32\n" \
2946 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002947 : "+r"(__v0), "+r" (__r7) \
2948 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002949 "r"(__r6), "r" ((unsigned long)arg5), \
2950 "r" ((unsigned long)arg6) \
2951 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002952 "$13", "$14", "$15", "$24", "$25", \
2953 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002954 LSS_RETURN(type, __v0, __r7); \
2955 }
2956 #else
2957 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2958 type5,arg5,type6,arg6) \
2959 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2960 type5 arg5,type6 arg6) { \
2961 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2962 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
2963 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2964 "r"(__r8), "r"(__r9)); \
2965 }
2966 #endif
2967 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2968 int flags, void *arg, int *parent_tidptr,
2969 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00002970 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002971 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
2972 {
2973 register int __flags __asm__("$4") = flags;
2974 register void *__stack __asm__("$5") = child_stack;
2975 register void *__ptid __asm__("$6") = parent_tidptr;
2976 register int *__ctid __asm__("$8") = child_tidptr;
2977 __asm__ __volatile__(
2978 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
2979 "subu $29,24\n"
2980 #elif _MIPS_SIM == _MIPS_SIM_NABI32
2981 "sub $29,16\n"
2982 #else
2983 "dsubu $29,16\n"
2984 #endif
2985
2986 /* if (fn == NULL || child_stack == NULL)
2987 * return -EINVAL;
2988 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002989 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002990 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002991
2992 /* Push "arg" and "fn" onto the stack that will be
2993 * used by the child.
2994 */
2995 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002996 "subu %5,32\n"
2997 "sw %4,0(%5)\n"
2998 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002999 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00003000 "sub %5,32\n"
3001 "sw %4,0(%5)\n"
3002 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003003 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00003004 "dsubu %5,32\n"
3005 "sd %4,0(%5)\n"
3006 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003007 #endif
3008
3009 /* $7 = syscall($4 = flags,
3010 * $5 = child_stack,
3011 * $6 = parent_tidptr,
3012 * $7 = newtls,
3013 * $8 = child_tidptr)
3014 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00003015 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003016 "syscall\n"
3017
3018 /* if ($7 != 0)
3019 * return $2;
3020 */
3021 "bnez $7,1f\n"
3022 "bnez $2,1f\n"
3023
3024 /* In the child, now. Call "fn(arg)".
3025 */
3026 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3027 "lw $25,0($29)\n"
3028 "lw $4,4($29)\n"
3029 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3030 "lw $25,0($29)\n"
3031 "lw $4,8($29)\n"
3032 #else
3033 "ld $25,0($29)\n"
3034 "ld $4,8($29)\n"
3035 #endif
3036 "jalr $25\n"
3037
3038 /* Call _exit($2)
3039 */
3040 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003041 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003042 "syscall\n"
3043
3044 "1:\n"
3045 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3046 "addu $29, 24\n"
3047 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3048 "add $29, 16\n"
3049 #else
3050 "daddu $29,16\n"
3051 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003052 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003053 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3054 "r"(__stack), "r"(__flags), "r"(arg),
3055 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003056 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003057 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003058 }
3059 LSS_RETURN(int, __v0, __r7);
3060 }
3061 #elif defined (__PPC__)
3062 #undef LSS_LOADARGS_0
3063 #define LSS_LOADARGS_0(name, dummy...) \
3064 __sc_0 = __NR_##name
3065 #undef LSS_LOADARGS_1
3066 #define LSS_LOADARGS_1(name, arg1) \
3067 LSS_LOADARGS_0(name); \
3068 __sc_3 = (unsigned long) (arg1)
3069 #undef LSS_LOADARGS_2
3070 #define LSS_LOADARGS_2(name, arg1, arg2) \
3071 LSS_LOADARGS_1(name, arg1); \
3072 __sc_4 = (unsigned long) (arg2)
3073 #undef LSS_LOADARGS_3
3074 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3075 LSS_LOADARGS_2(name, arg1, arg2); \
3076 __sc_5 = (unsigned long) (arg3)
3077 #undef LSS_LOADARGS_4
3078 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3079 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3080 __sc_6 = (unsigned long) (arg4)
3081 #undef LSS_LOADARGS_5
3082 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3083 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3084 __sc_7 = (unsigned long) (arg5)
3085 #undef LSS_LOADARGS_6
3086 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3087 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3088 __sc_8 = (unsigned long) (arg6)
3089 #undef LSS_ASMINPUT_0
3090 #define LSS_ASMINPUT_0 "0" (__sc_0)
3091 #undef LSS_ASMINPUT_1
3092 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3093 #undef LSS_ASMINPUT_2
3094 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3095 #undef LSS_ASMINPUT_3
3096 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3097 #undef LSS_ASMINPUT_4
3098 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3099 #undef LSS_ASMINPUT_5
3100 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3101 #undef LSS_ASMINPUT_6
3102 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3103 #undef LSS_BODY
3104 #define LSS_BODY(nr, type, name, args...) \
3105 long __sc_ret, __sc_err; \
3106 { \
3107 register unsigned long __sc_0 __asm__ ("r0"); \
3108 register unsigned long __sc_3 __asm__ ("r3"); \
3109 register unsigned long __sc_4 __asm__ ("r4"); \
3110 register unsigned long __sc_5 __asm__ ("r5"); \
3111 register unsigned long __sc_6 __asm__ ("r6"); \
3112 register unsigned long __sc_7 __asm__ ("r7"); \
3113 register unsigned long __sc_8 __asm__ ("r8"); \
3114 \
3115 LSS_LOADARGS_##nr(name, args); \
3116 __asm__ __volatile__ \
3117 ("sc\n\t" \
3118 "mfcr %0" \
3119 : "=&r" (__sc_0), \
3120 "=&r" (__sc_3), "=&r" (__sc_4), \
3121 "=&r" (__sc_5), "=&r" (__sc_6), \
3122 "=&r" (__sc_7), "=&r" (__sc_8) \
3123 : LSS_ASMINPUT_##nr \
3124 : "cr0", "ctr", "memory", \
3125 "r9", "r10", "r11", "r12"); \
3126 __sc_ret = __sc_3; \
3127 __sc_err = __sc_0; \
3128 } \
3129 LSS_RETURN(type, __sc_ret, __sc_err)
3130 #undef _syscall0
3131 #define _syscall0(type, name) \
3132 type LSS_NAME(name)(void) { \
3133 LSS_BODY(0, type, name); \
3134 }
3135 #undef _syscall1
3136 #define _syscall1(type, name, type1, arg1) \
3137 type LSS_NAME(name)(type1 arg1) { \
3138 LSS_BODY(1, type, name, arg1); \
3139 }
3140 #undef _syscall2
3141 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3142 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3143 LSS_BODY(2, type, name, arg1, arg2); \
3144 }
3145 #undef _syscall3
3146 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3147 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3148 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3149 }
3150 #undef _syscall4
3151 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3152 type4, arg4) \
3153 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3154 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3155 }
3156 #undef _syscall5
3157 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3158 type4, arg4, type5, arg5) \
3159 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3160 type5 arg5) { \
3161 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3162 }
3163 #undef _syscall6
3164 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3165 type4, arg4, type5, arg5, type6, arg6) \
3166 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3167 type5 arg5, type6 arg6) { \
3168 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3169 }
3170 /* clone function adapted from glibc 2.3.6 clone.S */
3171 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3172 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3173 */
3174 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3175 int flags, void *arg, int *parent_tidptr,
3176 void *newtls, int *child_tidptr) {
3177 long __ret, __err;
3178 {
3179 register int (*__fn)(void *) __asm__ ("r8") = fn;
3180 register void *__cstack __asm__ ("r4") = child_stack;
3181 register int __flags __asm__ ("r3") = flags;
3182 register void * __arg __asm__ ("r9") = arg;
3183 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3184 register void * __newtls __asm__ ("r6") = newtls;
3185 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3186 __asm__ __volatile__(
3187 /* check for fn == NULL
3188 * and child_stack == NULL
3189 */
3190 "cmpwi cr0, %6, 0\n\t"
3191 "cmpwi cr1, %7, 0\n\t"
3192 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3193 "beq- cr0, 1f\n\t"
3194
3195 /* set up stack frame for child */
3196 "clrrwi %7, %7, 4\n\t"
3197 "li 0, 0\n\t"
3198 "stwu 0, -16(%7)\n\t"
3199
3200 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3201 "mr 28, %6\n\t"
3202 "mr 29, %7\n\t"
3203 "mr 27, %9\n\t"
3204
3205 /* syscall */
3206 "li 0, %4\n\t"
3207 /* flags already in r3
3208 * child_stack already in r4
3209 * ptidptr already in r5
3210 * newtls already in r6
3211 * ctidptr already in r7
3212 */
3213 "sc\n\t"
3214
3215 /* Test if syscall was successful */
3216 "cmpwi cr1, 3, 0\n\t"
3217 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3218 "bne- cr1, 1f\n\t"
3219
3220 /* Do the function call */
3221 "mtctr 28\n\t"
3222 "mr 3, 27\n\t"
3223 "bctrl\n\t"
3224
3225 /* Call _exit(r3) */
3226 "li 0, %5\n\t"
3227 "sc\n\t"
3228
3229 /* Return to parent */
3230 "1:\n"
3231 "mfcr %1\n\t"
3232 "mr %0, 3\n\t"
3233 : "=r" (__ret), "=r" (__err)
3234 : "0" (-1), "1" (EINVAL),
3235 "i" (__NR_clone), "i" (__NR_exit),
3236 "r" (__fn), "r" (__cstack), "r" (__flags),
3237 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3238 "r" (__ctidptr)
3239 : "cr0", "cr1", "memory", "ctr",
3240 "r0", "r29", "r27", "r28");
3241 }
3242 LSS_RETURN(int, __ret, __err);
3243 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003244 #elif defined(__s390__)
3245 #undef LSS_REG
3246 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3247 #undef LSS_BODY
3248 #define LSS_BODY(type, name, args...) \
3249 register unsigned long __nr __asm__("r1") \
3250 = (unsigned long)(__NR_##name); \
3251 register long __res_r2 __asm__("r2"); \
3252 long __res; \
3253 __asm__ __volatile__ \
3254 ("svc 0\n\t" \
3255 : "=d"(__res_r2) \
3256 : "d"(__nr), ## args \
3257 : "memory"); \
3258 __res = __res_r2; \
3259 LSS_RETURN(type, __res)
3260 #undef _syscall0
3261 #define _syscall0(type, name) \
3262 type LSS_NAME(name)(void) { \
3263 LSS_BODY(type, name); \
3264 }
3265 #undef _syscall1
3266 #define _syscall1(type, name, type1, arg1) \
3267 type LSS_NAME(name)(type1 arg1) { \
3268 LSS_REG(2, arg1); \
3269 LSS_BODY(type, name, "0"(__r2)); \
3270 }
3271 #undef _syscall2
3272 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3273 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3274 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3275 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3276 }
3277 #undef _syscall3
3278 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3279 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3280 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3281 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3282 }
3283 #undef _syscall4
3284 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3285 type4, arg4) \
3286 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3287 type4 arg4) { \
3288 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3289 LSS_REG(5, arg4); \
3290 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3291 "d"(__r5)); \
3292 }
3293 #undef _syscall5
3294 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3295 type4, arg4, type5, arg5) \
3296 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3297 type4 arg4, type5 arg5) { \
3298 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3299 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3300 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3301 "d"(__r5), "d"(__r6)); \
3302 }
3303 #undef _syscall6
3304 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3305 type4, arg4, type5, arg5, type6, arg6) \
3306 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3307 type4 arg4, type5 arg5, type6 arg6) { \
3308 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3309 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3310 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3311 "d"(__r5), "d"(__r6), "d"(__r7)); \
3312 }
3313 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3314 int flags, void *arg, int *parent_tidptr,
3315 void *newtls, int *child_tidptr) {
3316 long __ret;
3317 {
3318 register int (*__fn)(void *) __asm__ ("r1") = fn;
3319 register void *__cstack __asm__ ("r2") = child_stack;
3320 register int __flags __asm__ ("r3") = flags;
3321 register void *__arg __asm__ ("r0") = arg;
3322 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3323 register void *__newtls __asm__ ("r6") = newtls;
3324 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3325 __asm__ __volatile__ (
3326 #ifndef __s390x__
3327 /* arg already in r0 */
3328 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3329 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3330 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3331 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3332 /* flags already in r3 */
3333 /* parent_tidptr already in r4 */
3334 /* child_tidptr already in r5 */
3335 /* newtls already in r6 */
3336 "svc %2\n\t" /* invoke clone syscall */
3337 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3338 "jnz 1f\n\t" /* return to parent if non-zero */
3339 /* start child thread */
3340 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3341 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3342 "xc 0(4,%%r15), 0(%%r15)\n\t"
3343 "basr %%r14, %4\n\t" /* jump to fn */
3344 "svc %3\n" /* invoke exit syscall */
3345 "1:\n"
3346 #else
3347 /* arg already in r0 */
3348 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3349 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3350 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3351 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3352 /* flags already in r3 */
3353 /* parent_tidptr already in r4 */
3354 /* child_tidptr already in r5 */
3355 /* newtls already in r6 */
3356 "svc %2\n\t" /* invoke clone syscall */
3357 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3358 "jnz 1f\n\t" /* return to parent if non-zero */
3359 /* start child thread */
3360 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3361 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3362 "xc 0(8,%%r15), 0(%%r15)\n\t"
3363 "basr %%r14, %4\n\t" /* jump to fn */
3364 "svc %3\n" /* invoke exit syscall */
3365 "1:\n"
3366 #endif
3367 : "=r" (__ret)
3368 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3369 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3370 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3371 : "cc", "r14", "memory"
3372 );
3373 }
3374 LSS_RETURN(int, __ret);
3375 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003376 #endif
3377 #define __NR__exit __NR_exit
3378 #define __NR__gettid __NR_gettid
3379 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00003380 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003381 LSS_INLINE _syscall1(int, chdir, const char *,p)
3382 LSS_INLINE _syscall1(int, close, int, f)
3383 LSS_INLINE _syscall2(int, clock_getres, int, c,
3384 struct kernel_timespec*, t)
3385 LSS_INLINE _syscall2(int, clock_gettime, int, c,
3386 struct kernel_timespec*, t)
3387 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003388 #if defined(__NR_dup2)
3389 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003390 LSS_INLINE _syscall2(int, dup2, int, s,
3391 int, d)
3392 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003393 #if defined(__NR_dup3)
3394 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3395 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003396 LSS_INLINE _syscall3(int, execve, const char*, f,
3397 const char*const*,a,const char*const*, e)
3398 LSS_INLINE _syscall1(int, _exit, int, e)
3399 LSS_INLINE _syscall1(int, exit_group, int, e)
3400 LSS_INLINE _syscall3(int, fcntl, int, f,
3401 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003402 #if defined(__NR_fork)
3403 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003404 LSS_INLINE _syscall0(pid_t, fork)
3405 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003406 LSS_INLINE _syscall2(int, fstat, int, f,
3407 struct kernel_stat*, b)
3408 LSS_INLINE _syscall2(int, fstatfs, int, f,
3409 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003410 #if defined(__x86_64__)
3411 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3412 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
3413 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
3414 }
3415 #else
3416 LSS_INLINE _syscall2(int, ftruncate, int, f,
3417 off_t, l)
3418 #endif
Mike Frysinger171a36a2019-01-26 23:05:43 -05003419 LSS_INLINE _syscall6(int, futex, int*, u,
3420 int, o, int, v,
3421 struct kernel_timespec*, t,
3422 int*, u2, int, v2)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003423 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003424 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003425 LSS_INLINE _syscall3(int, getdents64, int, f,
3426 struct kernel_dirent64*, d, int, c)
3427 LSS_INLINE _syscall0(gid_t, getegid)
3428 LSS_INLINE _syscall0(uid_t, geteuid)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003429 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003430 LSS_INLINE _syscall0(pid_t, getpgrp)
3431 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003432 LSS_INLINE _syscall0(pid_t, getpid)
3433 LSS_INLINE _syscall0(pid_t, getppid)
3434 LSS_INLINE _syscall2(int, getpriority, int, a,
3435 int, b)
3436 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
3437 gid_t *, e, gid_t *, s)
3438 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
3439 uid_t *, e, uid_t *, s)
3440#if !defined(__ARM_EABI__)
3441 LSS_INLINE _syscall2(int, getrlimit, int, r,
3442 struct kernel_rlimit*, l)
3443#endif
3444 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
3445 LSS_INLINE _syscall0(pid_t, _gettid)
3446 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
3447 void*, tz)
3448 LSS_INLINE _syscall5(int, setxattr, const char *,p,
3449 const char *, n, const void *,v,
3450 size_t, s, int, f)
3451 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
3452 const char *, n, const void *,v,
3453 size_t, s, int, f)
3454 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
3455 const char *, n, void *, v, size_t, s)
3456 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
3457 const char *, n, void *, v, size_t, s)
3458 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
3459 char *, l, size_t, s)
3460 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
3461 char *, l, size_t, s)
3462 LSS_INLINE _syscall3(int, ioctl, int, d,
3463 int, r, void *, a)
3464 LSS_INLINE _syscall2(int, ioprio_get, int, which,
3465 int, who)
3466 LSS_INLINE _syscall3(int, ioprio_set, int, which,
3467 int, who, int, ioprio)
3468 LSS_INLINE _syscall2(int, kill, pid_t, p,
3469 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003470 #if defined(__x86_64__)
3471 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3472 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
3473 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3474 LSS_SYSCALL_ARG(w));
3475 }
3476 #else
3477 LSS_INLINE _syscall3(off_t, lseek, int, f,
3478 off_t, o, int, w)
3479 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003480 LSS_INLINE _syscall2(int, munmap, void*, s,
3481 size_t, l)
3482 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
3483 unsigned long, n, void **,g, int *, d,
3484 int *, s, int, f)
3485 LSS_INLINE _syscall3(int, mprotect, const void *,a,
3486 size_t, l, int, p)
3487 LSS_INLINE _syscall5(void*, _mremap, void*, o,
3488 size_t, os, size_t, ns,
3489 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003490 #if defined(__NR_open)
3491 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003492 LSS_INLINE _syscall3(int, open, const char*, p,
3493 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003494 #endif
3495 #if defined(__NR_poll)
3496 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003497 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
3498 unsigned int, n, int, t)
3499 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003500 #if defined(__NR_ppoll)
3501 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
3502 unsigned int, n, const struct kernel_timespec *, t,
3503 const struct kernel_sigset_t *, sigmask, size_t, s)
3504 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00003505 LSS_INLINE _syscall5(int, prctl, int, option,
3506 unsigned long, arg2,
3507 unsigned long, arg3,
3508 unsigned long, arg4,
3509 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003510 LSS_INLINE _syscall4(long, ptrace, int, r,
3511 pid_t, p, void *, a, void *, d)
3512 #if defined(__NR_quotactl)
3513 // Defined on x86_64 / i386 only
3514 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
3515 int, id, caddr_t, addr)
3516 #endif
3517 LSS_INLINE _syscall3(ssize_t, read, int, f,
3518 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003519 #if defined(__NR_readlink)
3520 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003521 LSS_INLINE _syscall3(int, readlink, const char*, p,
3522 char*, b, size_t, s)
3523 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003524 #if defined(__NR_readlinkat)
3525 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
3526 size_t, s)
3527 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003528 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
3529 const struct kernel_sigaction*, a,
3530 struct kernel_sigaction*, o, size_t, c)
3531 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
3532 size_t, c)
3533 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
3534 const struct kernel_sigset_t*, s,
3535 struct kernel_sigset_t*, o, size_t, c)
3536 LSS_INLINE _syscall2(int, rt_sigsuspend,
3537 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08003538 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
3539 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003540 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
3541 unsigned int, l, unsigned long *, m)
3542 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
3543 unsigned int, l, unsigned long *, m)
3544 LSS_INLINE _syscall0(int, sched_yield)
3545 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
3546 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
3547 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
3548 LSS_INLINE _syscall1(int, setuid, uid_t, u)
3549 LSS_INLINE _syscall1(int, setgid, gid_t, g)
3550 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
3551 pid_t, g)
3552 LSS_INLINE _syscall3(int, setpriority, int, a,
3553 int, b, int, p)
3554 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
3555 gid_t, e, gid_t, s)
3556 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
3557 uid_t, e, uid_t, s)
3558 LSS_INLINE _syscall2(int, setrlimit, int, r,
3559 const struct kernel_rlimit*, l)
3560 LSS_INLINE _syscall0(pid_t, setsid)
3561 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
3562 const stack_t*, o)
3563 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003564 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003565 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003566 #if defined(__NR_stat)
3567 // stat is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003568 LSS_INLINE _syscall2(int, stat, const char*, f,
3569 struct kernel_stat*, b)
3570 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003571 LSS_INLINE _syscall2(int, statfs, const char*, f,
3572 struct kernel_statfs*, b)
3573 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
3574 pid_t, t, int, s)
3575 LSS_INLINE _syscall2(int, tkill, pid_t, p,
3576 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003577 #if defined(__NR_unlink)
3578 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003579 LSS_INLINE _syscall1(int, unlink, const char*, f)
3580 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003581 LSS_INLINE _syscall3(ssize_t, write, int, f,
3582 const void *, b, size_t, c)
3583 LSS_INLINE _syscall3(ssize_t, writev, int, f,
3584 const struct kernel_iovec*, v, size_t, c)
3585 #if defined(__NR_getcpu)
3586 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00003587 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003588 #endif
3589 #if defined(__x86_64__) || \
3590 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
3591 LSS_INLINE _syscall3(int, recvmsg, int, s,
3592 struct kernel_msghdr*, m, int, f)
3593 LSS_INLINE _syscall3(int, sendmsg, int, s,
3594 const struct kernel_msghdr*, m, int, f)
3595 LSS_INLINE _syscall6(int, sendto, int, s,
3596 const void*, m, size_t, l,
3597 int, f,
3598 const struct kernel_sockaddr*, a, int, t)
3599 LSS_INLINE _syscall2(int, shutdown, int, s,
3600 int, h)
3601 LSS_INLINE _syscall3(int, socket, int, d,
3602 int, t, int, p)
3603 LSS_INLINE _syscall4(int, socketpair, int, d,
3604 int, t, int, p, int*, s)
3605 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003606 #if defined(__NR_fadvise64)
3607 #if defined(__x86_64__)
3608 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3609 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
3610 int advice) {
3611 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
3612 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
3613 }
3614 #else
3615 LSS_INLINE _syscall4(int, fadvise64,
3616 int, fd, loff_t, offset, loff_t, len, int, advice)
3617 #endif
3618 #elif defined(__i386__)
3619 #define __NR__fadvise64_64 __NR_fadvise64_64
3620 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
3621 unsigned, offset_lo, unsigned, offset_hi,
3622 unsigned, len_lo, unsigned, len_hi,
3623 int, advice)
3624
3625 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
3626 loff_t len, int advice) {
3627 return LSS_NAME(_fadvise64_64)(fd,
3628 (unsigned)offset, (unsigned)(offset >>32),
3629 (unsigned)len, (unsigned)(len >> 32),
3630 advice);
3631 }
3632
3633 #elif defined(__s390__) && !defined(__s390x__)
3634 #define __NR__fadvise64_64 __NR_fadvise64_64
3635 struct kernel_fadvise64_64_args {
3636 int fd;
3637 long long offset;
3638 long long len;
3639 int advice;
3640 };
3641
3642 LSS_INLINE _syscall1(int, _fadvise64_64,
3643 struct kernel_fadvise64_64_args *args)
3644
3645 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
3646 loff_t len, int advice) {
3647 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
3648 return LSS_NAME(_fadvise64_64)(&args);
3649 }
3650 #endif
3651 #if defined(__NR_fallocate)
3652 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003653 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3654 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
3655 loff_t len) {
3656 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
3657 (uint64_t)(offset), (uint64_t)(len));
3658 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08003659 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
3660 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
3661 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
3662 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04003663 #define __NR__fallocate __NR_fallocate
3664 LSS_INLINE _syscall6(int, _fallocate, int, fd,
3665 int, mode,
3666 unsigned, offset_lo, unsigned, offset_hi,
3667 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003668
Bryan Chan3f6478a2016-06-14 08:38:17 -04003669 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
3670 loff_t offset, loff_t len) {
3671 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
3672 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
3673 }
3674 #else
3675 LSS_INLINE _syscall4(int, fallocate,
3676 int, f, int, mode, loff_t, offset, loff_t, len)
3677 #endif
3678 #endif
Chris Palmer29f7c7e2020-08-12 17:10:59 -07003679 #if defined(__NR_getrandom)
3680 LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length,
3681 unsigned int, flags)
3682 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003683 #if defined(__NR_newfstatat)
3684 LSS_INLINE _syscall4(int, newfstatat, int, d,
3685 const char *, p,
3686 struct kernel_stat*, b, int, f)
3687 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003688 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003689 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3690 gid_t *egid,
3691 gid_t *sgid) {
3692 return LSS_NAME(getresgid)(rgid, egid, sgid);
3693 }
3694
3695 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3696 uid_t *euid,
3697 uid_t *suid) {
3698 return LSS_NAME(getresuid)(ruid, euid, suid);
3699 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003700
3701 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3702 return LSS_NAME(setfsgid)(gid);
3703 }
3704
3705 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3706 return LSS_NAME(setfsuid)(uid);
3707 }
3708
3709 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3710 return LSS_NAME(setresgid)(rgid, egid, sgid);
3711 }
3712
3713 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3714 return LSS_NAME(setresuid)(ruid, euid, suid);
3715 }
3716
3717 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3718 const struct kernel_sigaction *act,
3719 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04003720 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003721 /* On x86_64, the kernel requires us to always set our own
3722 * SA_RESTORER in order to be able to return from a signal handler.
3723 * This function must have a "magic" signature that the "gdb"
3724 * (and maybe the kernel?) can recognize.
3725 */
3726 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
3727 struct kernel_sigaction a = *act;
3728 a.sa_flags |= SA_RESTORER;
3729 a.sa_restorer = LSS_NAME(restore_rt)();
3730 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
3731 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04003732 } else
3733 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003734 return LSS_NAME(rt_sigaction)(signum, act, oldact,
3735 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003736 }
3737
3738 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
3739 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
3740 }
3741
Joshua Peraza726d71e2019-11-13 12:21:13 -08003742 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
3743 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
3744 }
3745 #endif
3746 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003747 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
3748 const struct kernel_sigset_t *set,
3749 struct kernel_sigset_t *oldset) {
3750 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
3751 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08003752 #endif
3753 #if defined(__NR_rt_sigtimedwait)
3754 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
3755 siginfo_t *info,
3756 const struct timespec *timeout) {
3757 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003758 }
3759 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003760 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003761 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
3762 int*, s, int, o,
3763 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003764 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003765 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003766 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04003767 #endif
3768 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003769 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
3770 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003771 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
3772 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003773 #define __NR__getresgid32 __NR_getresgid32
3774 #define __NR__getresuid32 __NR_getresuid32
3775 #define __NR__setfsgid32 __NR_setfsgid32
3776 #define __NR__setfsuid32 __NR_setfsuid32
3777 #define __NR__setresgid32 __NR_setresgid32
3778 #define __NR__setresuid32 __NR_setresuid32
3779#if defined(__ARM_EABI__)
3780 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
3781 struct kernel_rlimit*, l)
3782#endif
3783 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
3784 gid_t *, e, gid_t *, s)
3785 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
3786 uid_t *, e, uid_t *, s)
3787 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
3788 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
3789 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
3790 gid_t, e, gid_t, s)
3791 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
3792 uid_t, e, uid_t, s)
3793
3794 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3795 gid_t *egid,
3796 gid_t *sgid) {
3797 int rc;
3798 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
3799 LSS_ERRNO == ENOSYS) {
3800 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
3801 return EFAULT;
3802 }
3803 // Clear the high bits first, since getresgid only sets 16 bits
3804 *rgid = *egid = *sgid = 0;
3805 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
3806 }
3807 return rc;
3808 }
3809
3810 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3811 uid_t *euid,
3812 uid_t *suid) {
3813 int rc;
3814 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
3815 LSS_ERRNO == ENOSYS) {
3816 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
3817 return EFAULT;
3818 }
3819 // Clear the high bits first, since getresuid only sets 16 bits
3820 *ruid = *euid = *suid = 0;
3821 rc = LSS_NAME(getresuid)(ruid, euid, suid);
3822 }
3823 return rc;
3824 }
3825
3826 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3827 int rc;
3828 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
3829 LSS_ERRNO == ENOSYS) {
3830 if ((unsigned int)gid & ~0xFFFFu) {
3831 rc = EINVAL;
3832 } else {
3833 rc = LSS_NAME(setfsgid)(gid);
3834 }
3835 }
3836 return rc;
3837 }
3838
3839 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3840 int rc;
3841 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
3842 LSS_ERRNO == ENOSYS) {
3843 if ((unsigned int)uid & ~0xFFFFu) {
3844 rc = EINVAL;
3845 } else {
3846 rc = LSS_NAME(setfsuid)(uid);
3847 }
3848 }
3849 return rc;
3850 }
3851
3852 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3853 int rc;
3854 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
3855 LSS_ERRNO == ENOSYS) {
3856 if ((unsigned int)rgid & ~0xFFFFu ||
3857 (unsigned int)egid & ~0xFFFFu ||
3858 (unsigned int)sgid & ~0xFFFFu) {
3859 rc = EINVAL;
3860 } else {
3861 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
3862 }
3863 }
3864 return rc;
3865 }
3866
3867 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3868 int rc;
3869 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
3870 LSS_ERRNO == ENOSYS) {
3871 if ((unsigned int)ruid & ~0xFFFFu ||
3872 (unsigned int)euid & ~0xFFFFu ||
3873 (unsigned int)suid & ~0xFFFFu) {
3874 rc = EINVAL;
3875 } else {
3876 rc = LSS_NAME(setresuid)(ruid, euid, suid);
3877 }
3878 }
3879 return rc;
3880 }
3881 #endif
3882 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
3883 memset(&set->sig, 0, sizeof(set->sig));
3884 return 0;
3885 }
3886
3887 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
3888 memset(&set->sig, -1, sizeof(set->sig));
3889 return 0;
3890 }
3891
3892 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
3893 int signum) {
3894 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3895 LSS_ERRNO = EINVAL;
3896 return -1;
3897 } else {
3898 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3899 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
3900 return 0;
3901 }
3902 }
3903
3904 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
3905 int signum) {
3906 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3907 LSS_ERRNO = EINVAL;
3908 return -1;
3909 } else {
3910 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3911 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
3912 return 0;
3913 }
3914 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003915
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003916 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
3917 int signum) {
3918 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3919 LSS_ERRNO = EINVAL;
3920 return -1;
3921 } else {
3922 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] &
3923 (1UL << ((signum - 1) % (8*sizeof(set->sig[0])))));
3924 }
3925 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003926 #if defined(__i386__) || \
3927 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
3928 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
3929 defined(__PPC__) || \
3930 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003931 #define __NR__sigaction __NR_sigaction
3932 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003933 #define __NR__sigsuspend __NR_sigsuspend
3934 #define __NR__socketcall __NR_socketcall
3935 LSS_INLINE _syscall2(int, fstat64, int, f,
3936 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00003937 LSS_INLINE _syscall5(int, _llseek, uint, fd,
3938 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003939 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04003940#if defined(__s390__) && !defined(__s390x__)
3941 /* On s390, mmap2() arguments are passed in memory. */
3942 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
3943 off_t o) {
3944 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
3945 (unsigned long) p, (unsigned long) f,
3946 (unsigned long) d, (unsigned long) o };
3947 LSS_REG(2, buf);
3948 LSS_BODY(void*, mmap2, "0"(__r2));
3949 }
3950#else
3951 #define __NR__mmap2 __NR_mmap2
3952 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003953 size_t, l, int, p,
3954 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04003955 off_t, o)
3956#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003957 LSS_INLINE _syscall3(int, _sigaction, int, s,
3958 const struct kernel_old_sigaction*, a,
3959 struct kernel_old_sigaction*, o)
3960 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003961 #ifdef __PPC__
3962 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
3963 #else
3964 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
3965 int, b,
3966 unsigned long, s)
3967 #endif
3968 LSS_INLINE _syscall2(int, stat64, const char *, p,
3969 struct kernel_stat64 *, b)
3970
3971 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3972 const struct kernel_sigaction *act,
3973 struct kernel_sigaction *oldact) {
3974 int old_errno = LSS_ERRNO;
3975 int rc;
3976 struct kernel_sigaction a;
3977 if (act != NULL) {
3978 a = *act;
3979 #ifdef __i386__
3980 /* On i386, the kernel requires us to always set our own
3981 * SA_RESTORER when using realtime signals. Otherwise, it does not
3982 * know how to return from a signal handler. This function must have
3983 * a "magic" signature that the "gdb" (and maybe the kernel?) can
3984 * recognize.
3985 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
3986 * using non-realtime signals.
3987 *
3988 * TODO: Test whether ARM needs a restorer
3989 */
3990 if (!(a.sa_flags & SA_RESTORER)) {
3991 a.sa_flags |= SA_RESTORER;
3992 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
3993 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
3994 }
3995 #endif
3996 }
3997 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
3998 (KERNEL_NSIG+7)/8);
3999 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4000 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
4001 if (!act) {
4002 ptr_a = NULL;
4003 } else {
4004 oa.sa_handler_ = act->sa_handler_;
4005 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
4006 #ifndef __mips__
4007 oa.sa_restorer = act->sa_restorer;
4008 #endif
4009 oa.sa_flags = act->sa_flags;
4010 }
4011 if (!oldact) {
4012 ptr_oa = NULL;
4013 }
4014 LSS_ERRNO = old_errno;
4015 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
4016 if (rc == 0 && oldact) {
4017 if (act) {
4018 memcpy(oldact, act, sizeof(*act));
4019 } else {
4020 memset(oldact, 0, sizeof(*oldact));
4021 }
4022 oldact->sa_handler_ = ptr_oa->sa_handler_;
4023 oldact->sa_flags = ptr_oa->sa_flags;
4024 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4025 #ifndef __mips__
4026 oldact->sa_restorer = ptr_oa->sa_restorer;
4027 #endif
4028 }
4029 }
4030 return rc;
4031 }
4032
4033 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4034 int old_errno = LSS_ERRNO;
4035 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4036 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4037 LSS_ERRNO = old_errno;
4038 LSS_NAME(sigemptyset)(set);
4039 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4040 }
4041 return rc;
4042 }
4043
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004044 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4045 int olderrno = LSS_ERRNO;
4046 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4047 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4048 LSS_ERRNO = olderrno;
4049 rc = LSS_NAME(_sigsuspend)(
4050 #ifndef __PPC__
4051 set, 0,
4052 #endif
4053 set->sig[0]);
4054 }
4055 return rc;
4056 }
4057 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004058 #if defined(__i386__) || \
4059 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4060 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4061 defined(__PPC__) || \
4062 (defined(__s390__) && !defined(__s390x__))
4063 /* On these architectures, implement mmap() with mmap2(). */
4064 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4065 int64_t o) {
4066 if (o % 4096) {
4067 LSS_ERRNO = EINVAL;
4068 return (void *) -1;
4069 }
4070 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4071 }
4072 #elif defined(__s390x__)
4073 /* On s390x, mmap() arguments are passed in memory. */
4074 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4075 int64_t o) {
4076 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4077 (unsigned long) p, (unsigned long) f,
4078 (unsigned long) d, (unsigned long) o };
4079 LSS_REG(2, buf);
4080 LSS_BODY(void*, mmap, "0"(__r2));
4081 }
4082 #elif defined(__x86_64__)
4083 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4084 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4085 int64_t o) {
4086 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4087 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4088 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4089 }
4090 #else
4091 /* Remaining 64-bit architectures. */
4092 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4093 int, flags, int, fd, int64_t, offset)
4094 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004095 #if defined(__PPC__)
4096 #undef LSS_SC_LOADARGS_0
4097 #define LSS_SC_LOADARGS_0(dummy...)
4098 #undef LSS_SC_LOADARGS_1
4099 #define LSS_SC_LOADARGS_1(arg1) \
4100 __sc_4 = (unsigned long) (arg1)
4101 #undef LSS_SC_LOADARGS_2
4102 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4103 LSS_SC_LOADARGS_1(arg1); \
4104 __sc_5 = (unsigned long) (arg2)
4105 #undef LSS_SC_LOADARGS_3
4106 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4107 LSS_SC_LOADARGS_2(arg1, arg2); \
4108 __sc_6 = (unsigned long) (arg3)
4109 #undef LSS_SC_LOADARGS_4
4110 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4111 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4112 __sc_7 = (unsigned long) (arg4)
4113 #undef LSS_SC_LOADARGS_5
4114 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4115 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4116 __sc_8 = (unsigned long) (arg5)
4117 #undef LSS_SC_BODY
4118 #define LSS_SC_BODY(nr, type, opt, args...) \
4119 long __sc_ret, __sc_err; \
4120 { \
4121 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4122 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4123 register unsigned long __sc_4 __asm__ ("r4"); \
4124 register unsigned long __sc_5 __asm__ ("r5"); \
4125 register unsigned long __sc_6 __asm__ ("r6"); \
4126 register unsigned long __sc_7 __asm__ ("r7"); \
4127 register unsigned long __sc_8 __asm__ ("r8"); \
4128 LSS_SC_LOADARGS_##nr(args); \
4129 __asm__ __volatile__ \
4130 ("stwu 1, -48(1)\n\t" \
4131 "stw 4, 20(1)\n\t" \
4132 "stw 5, 24(1)\n\t" \
4133 "stw 6, 28(1)\n\t" \
4134 "stw 7, 32(1)\n\t" \
4135 "stw 8, 36(1)\n\t" \
4136 "addi 4, 1, 20\n\t" \
4137 "sc\n\t" \
4138 "mfcr %0" \
4139 : "=&r" (__sc_0), \
4140 "=&r" (__sc_3), "=&r" (__sc_4), \
4141 "=&r" (__sc_5), "=&r" (__sc_6), \
4142 "=&r" (__sc_7), "=&r" (__sc_8) \
4143 : LSS_ASMINPUT_##nr \
4144 : "cr0", "ctr", "memory"); \
4145 __sc_ret = __sc_3; \
4146 __sc_err = __sc_0; \
4147 } \
4148 LSS_RETURN(type, __sc_ret, __sc_err)
4149
4150 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4151 int flags){
4152 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4153 }
4154
4155 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4156 const struct kernel_msghdr *msg,
4157 int flags) {
4158 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4159 }
4160
4161 // TODO(csilvers): why is this ifdef'ed out?
4162#if 0
4163 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4164 int flags,
4165 const struct kernel_sockaddr *to,
4166 unsigned int tolen) {
4167 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4168 }
4169#endif
4170
4171 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4172 LSS_SC_BODY(2, int, 13, s, how);
4173 }
4174
4175 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4176 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4177 }
4178
4179 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4180 int sv[2]) {
4181 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4182 }
4183 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004184 #if defined(__ARM_EABI__) || defined (__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004185 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4186 int, flags)
4187 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4188 msg, int, flags)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004189 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4190 int, flags, const struct kernel_sockaddr*, to,
4191 unsigned int, tolen)
4192 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
4193 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
4194 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4195 int*, sv)
4196 #endif
4197 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004198 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4199 defined(__s390__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004200 #define __NR__socketcall __NR_socketcall
4201 LSS_INLINE _syscall2(int, _socketcall, int, c,
4202 va_list, a)
4203 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4204 int rc;
4205 va_list ap;
4206 va_start(ap, op);
4207 rc = LSS_NAME(_socketcall)(op, ap);
4208 va_end(ap);
4209 return rc;
4210 }
4211
4212 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4213 int flags){
4214 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4215 }
4216
4217 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4218 const struct kernel_msghdr *msg,
4219 int flags) {
4220 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4221 }
4222
4223 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4224 int flags,
4225 const struct kernel_sockaddr *to,
4226 unsigned int tolen) {
4227 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4228 }
4229
4230 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4231 return LSS_NAME(socketcall)(13, s, how);
4232 }
4233
4234 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4235 return LSS_NAME(socketcall)(1, domain, type, protocol);
4236 }
4237
4238 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4239 int sv[2]) {
4240 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4241 }
4242 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004243 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004244 LSS_INLINE _syscall4(int, fstatat64, int, d,
4245 const char *, p,
4246 struct kernel_stat64 *, b, int, f)
4247 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004248 #if defined(__NR_waitpid)
4249 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004250 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4251 int*, s, int, o)
4252 #endif
4253 #if defined(__mips__)
4254 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4255 * both file handles through CPU registers.
4256 */
4257 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4258 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4259 register unsigned long __v1 __asm__("$3");
4260 register unsigned long __r7 __asm__("$7");
4261 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004262 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004263 : "0"(__v0)
4264 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004265 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004266 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004267 unsigned long __errnovalue = __v0;
4268 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004269 return -1;
4270 } else {
4271 p[0] = __v0;
4272 p[1] = __v1;
4273 return 0;
4274 }
4275 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004276 #elif defined(__NR_pipe)
4277 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004278 LSS_INLINE _syscall1(int, pipe, int *, p)
4279 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004280 #if defined(__NR_pipe2)
4281 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4282 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004283 /* TODO(csilvers): see if ppc can/should support this as well */
4284 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004285 defined(__ARM_EABI__) || \
4286 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4287 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004288 #define __NR__statfs64 __NR_statfs64
4289 #define __NR__fstatfs64 __NR_fstatfs64
4290 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4291 size_t, s,struct kernel_statfs64*, b)
4292 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4293 size_t, s,struct kernel_statfs64*, b)
4294 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
4295 struct kernel_statfs64 *b) {
4296 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
4297 }
4298 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
4299 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
4300 }
4301 #endif
4302
4303 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
4304 extern char **environ;
4305 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
4306 }
4307
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004308 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004309 pid_t tid = LSS_NAME(_gettid)();
4310 if (tid != -1) {
4311 return tid;
4312 }
4313 return LSS_NAME(getpid)();
4314 }
4315
4316 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
4317 size_t new_size, int flags, ...) {
4318 va_list ap;
4319 void *new_address, *rc;
4320 va_start(ap, flags);
4321 new_address = va_arg(ap, void *);
4322 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
4323 flags, new_address);
4324 va_end(ap);
4325 return rc;
4326 }
4327
4328 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
4329 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
4330 * then sends job control signals to the real parent, rather than to
4331 * the tracer. We reduce the risk of this happening by starting a
4332 * whole new time slice, and then quickly sending a SIGCONT signal
4333 * right after detaching from the tracee.
4334 *
4335 * We use tkill to ensure that we only issue a wakeup for the thread being
4336 * detached. Large multi threaded apps can take a long time in the kernel
4337 * processing SIGCONT.
4338 */
4339 int rc, err;
4340 LSS_NAME(sched_yield)();
4341 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
4342 err = LSS_ERRNO;
4343 LSS_NAME(tkill)(pid, SIGCONT);
4344 /* Old systems don't have tkill */
4345 if (LSS_ERRNO == ENOSYS)
4346 LSS_NAME(kill)(pid, SIGCONT);
4347 LSS_ERRNO = err;
4348 return rc;
4349 }
4350
4351 LSS_INLINE int LSS_NAME(raise)(int sig) {
4352 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
4353 }
4354
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004355 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004356 return LSS_NAME(setpgid)(0, 0);
4357 }
4358
vapier@chromium.org2273e812013-04-01 17:52:44 +00004359 #if defined(__x86_64__)
4360 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4361 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
4362 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4363 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4364 }
4365
4366 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
4367 loff_t o) {
4368 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4369 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4370 }
4371
4372 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) {
4373 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4374 LSS_SYSCALL_ARG(c));
4375 }
4376 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004377 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
4378 void *, b, size_t, c,
4379 loff_t, o)
4380 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
4381 const void *, b, size_t, c,
4382 loff_t, o)
4383 LSS_INLINE _syscall3(int, readahead, int, f,
4384 loff_t, o, unsigned, c)
4385 #else
4386 #define __NR__pread64 __NR_pread64
4387 #define __NR__pwrite64 __NR_pwrite64
4388 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00004389 #if defined(__ARM_EABI__) || defined(__mips__)
4390 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
4391 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004392 * fifth and sixth make such a pair (r4,r5).
4393 */
4394 #define LSS_LLARG_PAD 0,
4395 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
4396 void *, b, size_t, c,
4397 unsigned, skip, unsigned, o1, unsigned, o2)
4398 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
4399 const void *, b, size_t, c,
4400 unsigned, skip, unsigned, o1, unsigned, o2)
4401 LSS_INLINE _syscall5(int, _readahead, int, f,
4402 unsigned, skip,
4403 unsigned, o1, unsigned, o2, size_t, c)
4404 #else
4405 #define LSS_LLARG_PAD
4406 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
4407 void *, b, size_t, c, unsigned, o1,
4408 unsigned, o2)
4409 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
4410 const void *, b, size_t, c, unsigned, o1,
4411 long, o2)
4412 LSS_INLINE _syscall4(int, _readahead, int, f,
4413 unsigned, o1, unsigned, o2, size_t, c)
4414 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004415 /* We force 64bit-wide parameters onto the stack, then access each
4416 * 32-bit component individually. This guarantees that we build the
4417 * correct parameters independent of the native byte-order of the
4418 * underlying architecture.
4419 */
4420 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
4421 loff_t off) {
4422 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004423 return LSS_NAME(_pread64)(fd, buf, count,
4424 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004425 }
4426 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
4427 size_t count, loff_t off) {
4428 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004429 return LSS_NAME(_pwrite64)(fd, buf, count,
4430 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004431 }
4432 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {
4433 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004434 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004435 }
4436 #endif
4437#endif
4438
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004439/*
4440 * Polyfills for deprecated syscalls.
4441 */
4442
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004443#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004444 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
4445 return LSS_NAME(dup3)(s, d, 0);
4446 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004447#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004448
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004449#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004450 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
4451 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
4452 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004453#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004454
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004455#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004456 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
4457 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
4458 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004459#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004460
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004461#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004462 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
4463 size_t size) {
4464 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
4465 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004466#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004467
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004468#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05004469 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004470 return LSS_NAME(pipe2)(pipefd, 0);
4471 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004472#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004473
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004474#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004475 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
4476 int timeout) {
4477 struct kernel_timespec timeout_ts;
4478 struct kernel_timespec *timeout_ts_p = NULL;
4479
4480 if (timeout >= 0) {
4481 timeout_ts.tv_sec = timeout / 1000;
4482 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
4483 timeout_ts_p = &timeout_ts;
4484 }
4485 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
4486 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004487#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004488
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004489#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004490 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
4491 struct kernel_stat *buf) {
4492 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
4493 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004494#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004495
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004496#if !defined(__NR_waitpid)
4497 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
4498 return LSS_NAME(wait4)(pid, status, options, 0);
4499 }
4500#endif
4501
4502#if !defined(__NR_fork)
4503// TODO: define this in an arch-independant way instead of inlining the clone
4504// syscall body.
4505
4506# if defined(__aarch64__)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004507 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4508 // No fork syscall on aarch64 - implement by means of the clone syscall.
4509 // Note that this does not reset glibc's cached view of the PID/TID, so
4510 // some glibc interfaces might go wrong in the forked subprocess.
4511 int flags = SIGCHLD;
4512 void *child_stack = NULL;
4513 void *parent_tidptr = NULL;
4514 void *newtls = NULL;
4515 void *child_tidptr = NULL;
4516
4517 LSS_REG(0, flags);
4518 LSS_REG(1, child_stack);
4519 LSS_REG(2, parent_tidptr);
4520 LSS_REG(3, newtls);
4521 LSS_REG(4, child_tidptr);
4522 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
4523 "r"(__r4));
4524 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004525# elif defined(__x86_64__)
4526 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4527 // Android disallows the fork syscall on x86_64 - implement by means of the
4528 // clone syscall as above for aarch64.
4529 int flags = SIGCHLD;
4530 void *child_stack = NULL;
4531 void *parent_tidptr = NULL;
4532 void *newtls = NULL;
4533 void *child_tidptr = NULL;
4534
4535 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
4536 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
4537 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
4538 }
4539# else
4540# error missing fork polyfill for this architecture
4541# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004542#endif
4543
Michael Forneyf70e2f12020-01-22 19:19:38 -08004544/* These restore the original values of these macros saved by the
4545 * corresponding #pragma push_macro near the top of this file. */
4546#pragma pop_macro("stat64")
4547#pragma pop_macro("fstat64")
4548#pragma pop_macro("lstat64")
4549#pragma pop_macro("pread64")
4550#pragma pop_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -07004551#pragma pop_macro("getdents64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00004552
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004553#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
4554}
4555#endif
4556
4557#endif
4558#endif