blob: a0879033f6bb74bf4de36cc5a87faabcd4eabced [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
957/* End of i386 definitions */
958#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
959#ifndef __NR_setresuid
960#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
961#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
962#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
963#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
964#endif
965#ifndef __NR_rt_sigaction
966#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
967#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
968#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
969#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
970#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
971#endif
972#ifndef __NR_pread64
973#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
974#endif
975#ifndef __NR_pwrite64
976#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
977#endif
978#ifndef __NR_ugetrlimit
979#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
980#endif
981#ifndef __NR_stat64
982#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
983#endif
984#ifndef __NR_fstat64
985#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
986#endif
987#ifndef __NR_setresuid32
988#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
989#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
990#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
991#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
992#endif
993#ifndef __NR_setfsuid32
994#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
995#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
996#endif
997#ifndef __NR_getdents64
998#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
999#endif
1000#ifndef __NR_gettid
1001#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1002#endif
1003#ifndef __NR_readahead
1004#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1005#endif
1006#ifndef __NR_setxattr
1007#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1008#endif
1009#ifndef __NR_lsetxattr
1010#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1011#endif
1012#ifndef __NR_getxattr
1013#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1014#endif
1015#ifndef __NR_lgetxattr
1016#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1017#endif
1018#ifndef __NR_listxattr
1019#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1020#endif
1021#ifndef __NR_llistxattr
1022#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1023#endif
1024#ifndef __NR_tkill
1025#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1026#endif
1027#ifndef __NR_futex
1028#define __NR_futex (__NR_SYSCALL_BASE + 240)
1029#endif
1030#ifndef __NR_sched_setaffinity
1031#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1032#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1033#endif
1034#ifndef __NR_set_tid_address
1035#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1036#endif
1037#ifndef __NR_clock_gettime
1038#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1039#endif
1040#ifndef __NR_clock_getres
1041#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1042#endif
1043#ifndef __NR_statfs64
1044#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1045#endif
1046#ifndef __NR_fstatfs64
1047#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1048#endif
1049#ifndef __NR_ioprio_set
1050#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1051#endif
1052#ifndef __NR_ioprio_get
1053#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1054#endif
1055#ifndef __NR_move_pages
1056#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1057#endif
1058#ifndef __NR_getcpu
1059#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1060#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001061/* End of ARM 3/EABI definitions */
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001062#elif defined(__aarch64__)
1063#ifndef __NR_setxattr
1064#define __NR_setxattr 5
1065#endif
1066#ifndef __NR_lsetxattr
1067#define __NR_lsetxattr 6
1068#endif
1069#ifndef __NR_getxattr
1070#define __NR_getxattr 8
1071#endif
1072#ifndef __NR_lgetxattr
1073#define __NR_lgetxattr 9
1074#endif
1075#ifndef __NR_listxattr
1076#define __NR_listxattr 11
1077#endif
1078#ifndef __NR_llistxattr
1079#define __NR_llistxattr 12
1080#endif
1081#ifndef __NR_ioprio_set
1082#define __NR_ioprio_set 30
1083#endif
1084#ifndef __NR_ioprio_get
1085#define __NR_ioprio_get 31
1086#endif
1087#ifndef __NR_unlinkat
1088#define __NR_unlinkat 35
1089#endif
1090#ifndef __NR_fallocate
1091#define __NR_fallocate 47
1092#endif
1093#ifndef __NR_openat
1094#define __NR_openat 56
1095#endif
1096#ifndef __NR_quotactl
1097#define __NR_quotactl 60
1098#endif
1099#ifndef __NR_getdents64
1100#define __NR_getdents64 61
1101#endif
1102#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001103// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001104#define __NR_getdents __NR_getdents64
1105#endif
1106#ifndef __NR_pread64
1107#define __NR_pread64 67
1108#endif
1109#ifndef __NR_pwrite64
1110#define __NR_pwrite64 68
1111#endif
1112#ifndef __NR_ppoll
1113#define __NR_ppoll 73
1114#endif
1115#ifndef __NR_readlinkat
1116#define __NR_readlinkat 78
1117#endif
1118#ifndef __NR_newfstatat
1119#define __NR_newfstatat 79
1120#endif
1121#ifndef __NR_set_tid_address
1122#define __NR_set_tid_address 96
1123#endif
1124#ifndef __NR_futex
1125#define __NR_futex 98
1126#endif
1127#ifndef __NR_clock_gettime
1128#define __NR_clock_gettime 113
1129#endif
1130#ifndef __NR_clock_getres
1131#define __NR_clock_getres 114
1132#endif
1133#ifndef __NR_sched_setaffinity
1134#define __NR_sched_setaffinity 122
1135#define __NR_sched_getaffinity 123
1136#endif
1137#ifndef __NR_tkill
1138#define __NR_tkill 130
1139#endif
1140#ifndef __NR_setresuid
1141#define __NR_setresuid 147
1142#define __NR_getresuid 148
1143#define __NR_setresgid 149
1144#define __NR_getresgid 150
1145#endif
1146#ifndef __NR_gettid
1147#define __NR_gettid 178
1148#endif
1149#ifndef __NR_readahead
1150#define __NR_readahead 213
1151#endif
1152#ifndef __NR_fadvise64
1153#define __NR_fadvise64 223
1154#endif
1155#ifndef __NR_move_pages
1156#define __NR_move_pages 239
1157#endif
1158/* End of aarch64 definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001159#elif defined(__x86_64__)
1160#ifndef __NR_pread64
1161#define __NR_pread64 17
1162#endif
1163#ifndef __NR_pwrite64
1164#define __NR_pwrite64 18
1165#endif
1166#ifndef __NR_setresuid
1167#define __NR_setresuid 117
1168#define __NR_getresuid 118
1169#define __NR_setresgid 119
1170#define __NR_getresgid 120
1171#endif
1172#ifndef __NR_quotactl
1173#define __NR_quotactl 179
1174#endif
1175#ifndef __NR_gettid
1176#define __NR_gettid 186
1177#endif
1178#ifndef __NR_readahead
1179#define __NR_readahead 187
1180#endif
1181#ifndef __NR_setxattr
1182#define __NR_setxattr 188
1183#endif
1184#ifndef __NR_lsetxattr
1185#define __NR_lsetxattr 189
1186#endif
1187#ifndef __NR_getxattr
1188#define __NR_getxattr 191
1189#endif
1190#ifndef __NR_lgetxattr
1191#define __NR_lgetxattr 192
1192#endif
1193#ifndef __NR_listxattr
1194#define __NR_listxattr 194
1195#endif
1196#ifndef __NR_llistxattr
1197#define __NR_llistxattr 195
1198#endif
1199#ifndef __NR_tkill
1200#define __NR_tkill 200
1201#endif
1202#ifndef __NR_futex
1203#define __NR_futex 202
1204#endif
1205#ifndef __NR_sched_setaffinity
1206#define __NR_sched_setaffinity 203
1207#define __NR_sched_getaffinity 204
1208#endif
1209#ifndef __NR_getdents64
1210#define __NR_getdents64 217
1211#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001212#ifndef __NR_getdents
1213// when getdents is not available, getdents64 is used for both.
1214#define __NR_getdents __NR_getdents64
1215#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001216#ifndef __NR_set_tid_address
1217#define __NR_set_tid_address 218
1218#endif
1219#ifndef __NR_fadvise64
1220#define __NR_fadvise64 221
1221#endif
1222#ifndef __NR_clock_gettime
1223#define __NR_clock_gettime 228
1224#endif
1225#ifndef __NR_clock_getres
1226#define __NR_clock_getres 229
1227#endif
1228#ifndef __NR_ioprio_set
1229#define __NR_ioprio_set 251
1230#endif
1231#ifndef __NR_ioprio_get
1232#define __NR_ioprio_get 252
1233#endif
1234#ifndef __NR_openat
1235#define __NR_openat 257
1236#endif
1237#ifndef __NR_newfstatat
1238#define __NR_newfstatat 262
1239#endif
1240#ifndef __NR_unlinkat
1241#define __NR_unlinkat 263
1242#endif
1243#ifndef __NR_move_pages
1244#define __NR_move_pages 279
1245#endif
1246#ifndef __NR_fallocate
1247#define __NR_fallocate 285
1248#endif
1249/* End of x86-64 definitions */
1250#elif defined(__mips__)
1251#if _MIPS_SIM == _MIPS_SIM_ABI32
1252#ifndef __NR_setresuid
1253#define __NR_setresuid (__NR_Linux + 185)
1254#define __NR_getresuid (__NR_Linux + 186)
1255#define __NR_setresgid (__NR_Linux + 190)
1256#define __NR_getresgid (__NR_Linux + 191)
1257#endif
1258#ifndef __NR_rt_sigaction
1259#define __NR_rt_sigreturn (__NR_Linux + 193)
1260#define __NR_rt_sigaction (__NR_Linux + 194)
1261#define __NR_rt_sigprocmask (__NR_Linux + 195)
1262#define __NR_rt_sigpending (__NR_Linux + 196)
1263#define __NR_rt_sigsuspend (__NR_Linux + 199)
1264#endif
1265#ifndef __NR_pread64
1266#define __NR_pread64 (__NR_Linux + 200)
1267#endif
1268#ifndef __NR_pwrite64
1269#define __NR_pwrite64 (__NR_Linux + 201)
1270#endif
1271#ifndef __NR_stat64
1272#define __NR_stat64 (__NR_Linux + 213)
1273#endif
1274#ifndef __NR_fstat64
1275#define __NR_fstat64 (__NR_Linux + 215)
1276#endif
1277#ifndef __NR_getdents64
1278#define __NR_getdents64 (__NR_Linux + 219)
1279#endif
1280#ifndef __NR_gettid
1281#define __NR_gettid (__NR_Linux + 222)
1282#endif
1283#ifndef __NR_readahead
1284#define __NR_readahead (__NR_Linux + 223)
1285#endif
1286#ifndef __NR_setxattr
1287#define __NR_setxattr (__NR_Linux + 224)
1288#endif
1289#ifndef __NR_lsetxattr
1290#define __NR_lsetxattr (__NR_Linux + 225)
1291#endif
1292#ifndef __NR_getxattr
1293#define __NR_getxattr (__NR_Linux + 227)
1294#endif
1295#ifndef __NR_lgetxattr
1296#define __NR_lgetxattr (__NR_Linux + 228)
1297#endif
1298#ifndef __NR_listxattr
1299#define __NR_listxattr (__NR_Linux + 230)
1300#endif
1301#ifndef __NR_llistxattr
1302#define __NR_llistxattr (__NR_Linux + 231)
1303#endif
1304#ifndef __NR_tkill
1305#define __NR_tkill (__NR_Linux + 236)
1306#endif
1307#ifndef __NR_futex
1308#define __NR_futex (__NR_Linux + 238)
1309#endif
1310#ifndef __NR_sched_setaffinity
1311#define __NR_sched_setaffinity (__NR_Linux + 239)
1312#define __NR_sched_getaffinity (__NR_Linux + 240)
1313#endif
1314#ifndef __NR_set_tid_address
1315#define __NR_set_tid_address (__NR_Linux + 252)
1316#endif
1317#ifndef __NR_statfs64
1318#define __NR_statfs64 (__NR_Linux + 255)
1319#endif
1320#ifndef __NR_fstatfs64
1321#define __NR_fstatfs64 (__NR_Linux + 256)
1322#endif
1323#ifndef __NR_clock_gettime
1324#define __NR_clock_gettime (__NR_Linux + 263)
1325#endif
1326#ifndef __NR_clock_getres
1327#define __NR_clock_getres (__NR_Linux + 264)
1328#endif
1329#ifndef __NR_openat
1330#define __NR_openat (__NR_Linux + 288)
1331#endif
1332#ifndef __NR_fstatat
1333#define __NR_fstatat (__NR_Linux + 293)
1334#endif
1335#ifndef __NR_unlinkat
1336#define __NR_unlinkat (__NR_Linux + 294)
1337#endif
1338#ifndef __NR_move_pages
1339#define __NR_move_pages (__NR_Linux + 308)
1340#endif
1341#ifndef __NR_getcpu
1342#define __NR_getcpu (__NR_Linux + 312)
1343#endif
1344#ifndef __NR_ioprio_set
1345#define __NR_ioprio_set (__NR_Linux + 314)
1346#endif
1347#ifndef __NR_ioprio_get
1348#define __NR_ioprio_get (__NR_Linux + 315)
1349#endif
1350/* End of MIPS (old 32bit API) definitions */
1351#elif _MIPS_SIM == _MIPS_SIM_ABI64
1352#ifndef __NR_pread64
1353#define __NR_pread64 (__NR_Linux + 16)
1354#endif
1355#ifndef __NR_pwrite64
1356#define __NR_pwrite64 (__NR_Linux + 17)
1357#endif
1358#ifndef __NR_setresuid
1359#define __NR_setresuid (__NR_Linux + 115)
1360#define __NR_getresuid (__NR_Linux + 116)
1361#define __NR_setresgid (__NR_Linux + 117)
1362#define __NR_getresgid (__NR_Linux + 118)
1363#endif
1364#ifndef __NR_gettid
1365#define __NR_gettid (__NR_Linux + 178)
1366#endif
1367#ifndef __NR_readahead
1368#define __NR_readahead (__NR_Linux + 179)
1369#endif
1370#ifndef __NR_setxattr
1371#define __NR_setxattr (__NR_Linux + 180)
1372#endif
1373#ifndef __NR_lsetxattr
1374#define __NR_lsetxattr (__NR_Linux + 181)
1375#endif
1376#ifndef __NR_getxattr
1377#define __NR_getxattr (__NR_Linux + 183)
1378#endif
1379#ifndef __NR_lgetxattr
1380#define __NR_lgetxattr (__NR_Linux + 184)
1381#endif
1382#ifndef __NR_listxattr
1383#define __NR_listxattr (__NR_Linux + 186)
1384#endif
1385#ifndef __NR_llistxattr
1386#define __NR_llistxattr (__NR_Linux + 187)
1387#endif
1388#ifndef __NR_tkill
1389#define __NR_tkill (__NR_Linux + 192)
1390#endif
1391#ifndef __NR_futex
1392#define __NR_futex (__NR_Linux + 194)
1393#endif
1394#ifndef __NR_sched_setaffinity
1395#define __NR_sched_setaffinity (__NR_Linux + 195)
1396#define __NR_sched_getaffinity (__NR_Linux + 196)
1397#endif
1398#ifndef __NR_set_tid_address
1399#define __NR_set_tid_address (__NR_Linux + 212)
1400#endif
1401#ifndef __NR_clock_gettime
1402#define __NR_clock_gettime (__NR_Linux + 222)
1403#endif
1404#ifndef __NR_clock_getres
1405#define __NR_clock_getres (__NR_Linux + 223)
1406#endif
1407#ifndef __NR_openat
1408#define __NR_openat (__NR_Linux + 247)
1409#endif
1410#ifndef __NR_fstatat
1411#define __NR_fstatat (__NR_Linux + 252)
1412#endif
1413#ifndef __NR_unlinkat
1414#define __NR_unlinkat (__NR_Linux + 253)
1415#endif
1416#ifndef __NR_move_pages
1417#define __NR_move_pages (__NR_Linux + 267)
1418#endif
1419#ifndef __NR_getcpu
1420#define __NR_getcpu (__NR_Linux + 271)
1421#endif
1422#ifndef __NR_ioprio_set
1423#define __NR_ioprio_set (__NR_Linux + 273)
1424#endif
1425#ifndef __NR_ioprio_get
1426#define __NR_ioprio_get (__NR_Linux + 274)
1427#endif
1428/* End of MIPS (64bit API) definitions */
1429#else
1430#ifndef __NR_setresuid
1431#define __NR_setresuid (__NR_Linux + 115)
1432#define __NR_getresuid (__NR_Linux + 116)
1433#define __NR_setresgid (__NR_Linux + 117)
1434#define __NR_getresgid (__NR_Linux + 118)
1435#endif
1436#ifndef __NR_gettid
1437#define __NR_gettid (__NR_Linux + 178)
1438#endif
1439#ifndef __NR_readahead
1440#define __NR_readahead (__NR_Linux + 179)
1441#endif
1442#ifndef __NR_setxattr
1443#define __NR_setxattr (__NR_Linux + 180)
1444#endif
1445#ifndef __NR_lsetxattr
1446#define __NR_lsetxattr (__NR_Linux + 181)
1447#endif
1448#ifndef __NR_getxattr
1449#define __NR_getxattr (__NR_Linux + 183)
1450#endif
1451#ifndef __NR_lgetxattr
1452#define __NR_lgetxattr (__NR_Linux + 184)
1453#endif
1454#ifndef __NR_listxattr
1455#define __NR_listxattr (__NR_Linux + 186)
1456#endif
1457#ifndef __NR_llistxattr
1458#define __NR_llistxattr (__NR_Linux + 187)
1459#endif
1460#ifndef __NR_tkill
1461#define __NR_tkill (__NR_Linux + 192)
1462#endif
1463#ifndef __NR_futex
1464#define __NR_futex (__NR_Linux + 194)
1465#endif
1466#ifndef __NR_sched_setaffinity
1467#define __NR_sched_setaffinity (__NR_Linux + 195)
1468#define __NR_sched_getaffinity (__NR_Linux + 196)
1469#endif
1470#ifndef __NR_set_tid_address
1471#define __NR_set_tid_address (__NR_Linux + 213)
1472#endif
1473#ifndef __NR_statfs64
1474#define __NR_statfs64 (__NR_Linux + 217)
1475#endif
1476#ifndef __NR_fstatfs64
1477#define __NR_fstatfs64 (__NR_Linux + 218)
1478#endif
1479#ifndef __NR_clock_gettime
1480#define __NR_clock_gettime (__NR_Linux + 226)
1481#endif
1482#ifndef __NR_clock_getres
1483#define __NR_clock_getres (__NR_Linux + 227)
1484#endif
1485#ifndef __NR_openat
1486#define __NR_openat (__NR_Linux + 251)
1487#endif
1488#ifndef __NR_fstatat
1489#define __NR_fstatat (__NR_Linux + 256)
1490#endif
1491#ifndef __NR_unlinkat
1492#define __NR_unlinkat (__NR_Linux + 257)
1493#endif
1494#ifndef __NR_move_pages
1495#define __NR_move_pages (__NR_Linux + 271)
1496#endif
1497#ifndef __NR_getcpu
1498#define __NR_getcpu (__NR_Linux + 275)
1499#endif
1500#ifndef __NR_ioprio_set
1501#define __NR_ioprio_set (__NR_Linux + 277)
1502#endif
1503#ifndef __NR_ioprio_get
1504#define __NR_ioprio_get (__NR_Linux + 278)
1505#endif
1506/* End of MIPS (new 32bit API) definitions */
1507#endif
1508/* End of MIPS definitions */
1509#elif defined(__PPC__)
1510#ifndef __NR_setfsuid
1511#define __NR_setfsuid 138
1512#define __NR_setfsgid 139
1513#endif
1514#ifndef __NR_setresuid
1515#define __NR_setresuid 164
1516#define __NR_getresuid 165
1517#define __NR_setresgid 169
1518#define __NR_getresgid 170
1519#endif
1520#ifndef __NR_rt_sigaction
1521#define __NR_rt_sigreturn 172
1522#define __NR_rt_sigaction 173
1523#define __NR_rt_sigprocmask 174
1524#define __NR_rt_sigpending 175
1525#define __NR_rt_sigsuspend 178
1526#endif
1527#ifndef __NR_pread64
1528#define __NR_pread64 179
1529#endif
1530#ifndef __NR_pwrite64
1531#define __NR_pwrite64 180
1532#endif
1533#ifndef __NR_ugetrlimit
1534#define __NR_ugetrlimit 190
1535#endif
1536#ifndef __NR_readahead
1537#define __NR_readahead 191
1538#endif
1539#ifndef __NR_stat64
1540#define __NR_stat64 195
1541#endif
1542#ifndef __NR_fstat64
1543#define __NR_fstat64 197
1544#endif
1545#ifndef __NR_getdents64
1546#define __NR_getdents64 202
1547#endif
1548#ifndef __NR_gettid
1549#define __NR_gettid 207
1550#endif
1551#ifndef __NR_tkill
1552#define __NR_tkill 208
1553#endif
1554#ifndef __NR_setxattr
1555#define __NR_setxattr 209
1556#endif
1557#ifndef __NR_lsetxattr
1558#define __NR_lsetxattr 210
1559#endif
1560#ifndef __NR_getxattr
1561#define __NR_getxattr 212
1562#endif
1563#ifndef __NR_lgetxattr
1564#define __NR_lgetxattr 213
1565#endif
1566#ifndef __NR_listxattr
1567#define __NR_listxattr 215
1568#endif
1569#ifndef __NR_llistxattr
1570#define __NR_llistxattr 216
1571#endif
1572#ifndef __NR_futex
1573#define __NR_futex 221
1574#endif
1575#ifndef __NR_sched_setaffinity
1576#define __NR_sched_setaffinity 222
1577#define __NR_sched_getaffinity 223
1578#endif
1579#ifndef __NR_set_tid_address
1580#define __NR_set_tid_address 232
1581#endif
1582#ifndef __NR_clock_gettime
1583#define __NR_clock_gettime 246
1584#endif
1585#ifndef __NR_clock_getres
1586#define __NR_clock_getres 247
1587#endif
1588#ifndef __NR_statfs64
1589#define __NR_statfs64 252
1590#endif
1591#ifndef __NR_fstatfs64
1592#define __NR_fstatfs64 253
1593#endif
1594#ifndef __NR_fadvise64_64
1595#define __NR_fadvise64_64 254
1596#endif
1597#ifndef __NR_ioprio_set
1598#define __NR_ioprio_set 273
1599#endif
1600#ifndef __NR_ioprio_get
1601#define __NR_ioprio_get 274
1602#endif
1603#ifndef __NR_openat
1604#define __NR_openat 286
1605#endif
1606#ifndef __NR_fstatat64
1607#define __NR_fstatat64 291
1608#endif
1609#ifndef __NR_unlinkat
1610#define __NR_unlinkat 292
1611#endif
1612#ifndef __NR_move_pages
1613#define __NR_move_pages 301
1614#endif
1615#ifndef __NR_getcpu
1616#define __NR_getcpu 302
1617#endif
1618/* End of powerpc defininitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001619#elif defined(__s390__)
1620#ifndef __NR_quotactl
1621#define __NR_quotactl 131
1622#endif
1623#ifndef __NR_rt_sigreturn
1624#define __NR_rt_sigreturn 173
1625#endif
1626#ifndef __NR_rt_sigaction
1627#define __NR_rt_sigaction 174
1628#endif
1629#ifndef __NR_rt_sigprocmask
1630#define __NR_rt_sigprocmask 175
1631#endif
1632#ifndef __NR_rt_sigpending
1633#define __NR_rt_sigpending 176
1634#endif
1635#ifndef __NR_rt_sigsuspend
1636#define __NR_rt_sigsuspend 179
1637#endif
1638#ifndef __NR_pread64
1639#define __NR_pread64 180
1640#endif
1641#ifndef __NR_pwrite64
1642#define __NR_pwrite64 181
1643#endif
1644#ifndef __NR_getdents64
1645#define __NR_getdents64 220
1646#endif
1647#ifndef __NR_readahead
1648#define __NR_readahead 222
1649#endif
1650#ifndef __NR_setxattr
1651#define __NR_setxattr 224
1652#endif
1653#ifndef __NR_lsetxattr
1654#define __NR_lsetxattr 225
1655#endif
1656#ifndef __NR_getxattr
1657#define __NR_getxattr 227
1658#endif
1659#ifndef __NR_lgetxattr
1660#define __NR_lgetxattr 228
1661#endif
1662#ifndef __NR_listxattr
1663#define __NR_listxattr 230
1664#endif
1665#ifndef __NR_llistxattr
1666#define __NR_llistxattr 231
1667#endif
1668#ifndef __NR_gettid
1669#define __NR_gettid 236
1670#endif
1671#ifndef __NR_tkill
1672#define __NR_tkill 237
1673#endif
1674#ifndef __NR_futex
1675#define __NR_futex 238
1676#endif
1677#ifndef __NR_sched_setaffinity
1678#define __NR_sched_setaffinity 239
1679#endif
1680#ifndef __NR_sched_getaffinity
1681#define __NR_sched_getaffinity 240
1682#endif
1683#ifndef __NR_set_tid_address
1684#define __NR_set_tid_address 252
1685#endif
1686#ifndef __NR_clock_gettime
1687#define __NR_clock_gettime 260
1688#endif
1689#ifndef __NR_clock_getres
1690#define __NR_clock_getres 261
1691#endif
1692#ifndef __NR_statfs64
1693#define __NR_statfs64 265
1694#endif
1695#ifndef __NR_fstatfs64
1696#define __NR_fstatfs64 266
1697#endif
1698#ifndef __NR_ioprio_set
1699#define __NR_ioprio_set 282
1700#endif
1701#ifndef __NR_ioprio_get
1702#define __NR_ioprio_get 283
1703#endif
1704#ifndef __NR_openat
1705#define __NR_openat 288
1706#endif
1707#ifndef __NR_unlinkat
1708#define __NR_unlinkat 294
1709#endif
1710#ifndef __NR_move_pages
1711#define __NR_move_pages 310
1712#endif
1713#ifndef __NR_getcpu
1714#define __NR_getcpu 311
1715#endif
1716#ifndef __NR_fallocate
1717#define __NR_fallocate 314
1718#endif
1719/* Some syscalls are named/numbered differently between s390 and s390x. */
1720#ifdef __s390x__
1721# ifndef __NR_getrlimit
1722# define __NR_getrlimit 191
1723# endif
1724# ifndef __NR_setresuid
1725# define __NR_setresuid 208
1726# endif
1727# ifndef __NR_getresuid
1728# define __NR_getresuid 209
1729# endif
1730# ifndef __NR_setresgid
1731# define __NR_setresgid 210
1732# endif
1733# ifndef __NR_getresgid
1734# define __NR_getresgid 211
1735# endif
1736# ifndef __NR_setfsuid
1737# define __NR_setfsuid 215
1738# endif
1739# ifndef __NR_setfsgid
1740# define __NR_setfsgid 216
1741# endif
1742# ifndef __NR_fadvise64
1743# define __NR_fadvise64 253
1744# endif
1745# ifndef __NR_newfstatat
1746# define __NR_newfstatat 293
1747# endif
1748#else /* __s390x__ */
1749# ifndef __NR_getrlimit
1750# define __NR_getrlimit 76
1751# endif
1752# ifndef __NR_setfsuid
1753# define __NR_setfsuid 138
1754# endif
1755# ifndef __NR_setfsgid
1756# define __NR_setfsgid 139
1757# endif
1758# ifndef __NR_setresuid
1759# define __NR_setresuid 164
1760# endif
1761# ifndef __NR_getresuid
1762# define __NR_getresuid 165
1763# endif
1764# ifndef __NR_setresgid
1765# define __NR_setresgid 170
1766# endif
1767# ifndef __NR_getresgid
1768# define __NR_getresgid 171
1769# endif
1770# ifndef __NR_ugetrlimit
1771# define __NR_ugetrlimit 191
1772# endif
1773# ifndef __NR_mmap2
1774# define __NR_mmap2 192
1775# endif
1776# ifndef __NR_setresuid32
1777# define __NR_setresuid32 208
1778# endif
1779# ifndef __NR_getresuid32
1780# define __NR_getresuid32 209
1781# endif
1782# ifndef __NR_setresgid32
1783# define __NR_setresgid32 210
1784# endif
1785# ifndef __NR_getresgid32
1786# define __NR_getresgid32 211
1787# endif
1788# ifndef __NR_setfsuid32
1789# define __NR_setfsuid32 215
1790# endif
1791# ifndef __NR_setfsgid32
1792# define __NR_setfsgid32 216
1793# endif
1794# ifndef __NR_fadvise64_64
1795# define __NR_fadvise64_64 264
1796# endif
1797# ifndef __NR_fstatat64
1798# define __NR_fstatat64 293
1799# endif
1800#endif /* __s390__ */
1801/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001802#endif
1803
1804
1805/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001806#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001807 #error "Need to port invocations of syscalls for bounded ptrs"
1808#else
1809 /* The core dumper and the thread lister get executed after threads
1810 * have been suspended. As a consequence, we cannot call any functions
1811 * that acquire locks. Unfortunately, libc wraps most system calls
1812 * (e.g. in order to implement pthread_atfork, and to make calls
1813 * cancellable), which means we cannot call these functions. Instead,
1814 * we have to call syscall() directly.
1815 */
1816 #undef LSS_ERRNO
1817 #ifdef SYS_ERRNO
1818 /* Allow the including file to override the location of errno. This can
1819 * be useful when using clone() with the CLONE_VM option.
1820 */
1821 #define LSS_ERRNO SYS_ERRNO
1822 #else
1823 #define LSS_ERRNO errno
1824 #endif
1825
1826 #undef LSS_INLINE
1827 #ifdef SYS_INLINE
1828 #define LSS_INLINE SYS_INLINE
1829 #else
1830 #define LSS_INLINE static inline
1831 #endif
1832
1833 /* Allow the including file to override the prefix used for all new
1834 * system calls. By default, it will be set to "sys_".
1835 */
1836 #undef LSS_NAME
1837 #ifndef SYS_PREFIX
1838 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001839 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001840 #define LSS_NAME(name) name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001841 #elif defined(SYS_PREFIX) && SYS_PREFIX == 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001842 #define LSS_NAME(name) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001843 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001844 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001845 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001846 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001847 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001848 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001849 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001850 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001851 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001852 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001853 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001854 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001855 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001856 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001857 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001858 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001859 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001860 #define LSS_NAME(name) sys9_##name
1861 #endif
1862
1863 #undef LSS_RETURN
1864 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
Bryan Chan3f6478a2016-06-14 08:38:17 -04001865 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001866 /* Failing system calls return a negative result in the range of
1867 * -1..-4095. These are "errno" values with the sign inverted.
1868 */
1869 #define LSS_RETURN(type, res) \
1870 do { \
1871 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
1872 LSS_ERRNO = -(res); \
1873 res = -1; \
1874 } \
1875 return (type) (res); \
1876 } while (0)
1877 #elif defined(__mips__)
1878 /* On MIPS, failing system calls return -1, and set errno in a
1879 * separate CPU register.
1880 */
1881 #define LSS_RETURN(type, res, err) \
1882 do { \
1883 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00001884 unsigned long __errnovalue = (res); \
1885 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001886 res = -1; \
1887 } \
1888 return (type) (res); \
1889 } while (0)
1890 #elif defined(__PPC__)
1891 /* On PPC, failing system calls return -1, and set errno in a
1892 * separate CPU register. See linux/unistd.h.
1893 */
1894 #define LSS_RETURN(type, res, err) \
1895 do { \
1896 if (err & 0x10000000 ) { \
1897 LSS_ERRNO = (res); \
1898 res = -1; \
1899 } \
1900 return (type) (res); \
1901 } while (0)
1902 #endif
1903 #if defined(__i386__)
1904 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1905 * reserves ebx. Unfortunately, most distribution ship with implementations
1906 * of _syscallX() which clobber ebx.
1907 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1908 * clobbered. This causes problems with compilers, that do a better job
1909 * at optimizing across __asm__ calls.
1910 * So, we just have to redefine all of the _syscallX() macros.
1911 */
1912 #undef LSS_ENTRYPOINT
1913 #ifdef SYS_SYSCALL_ENTRYPOINT
1914 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1915 void (**entrypoint)(void);
1916 asm volatile(".bss\n"
1917 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001918 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1919 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001920 ".previous\n"
1921 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
1922 "call 0f\n"
1923 "0:pop %0\n"
1924 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001925 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001926 : "=r"(entrypoint));
1927 return entrypoint;
1928 }
1929
1930 #define LSS_ENTRYPOINT ".bss\n" \
1931 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001932 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
1933 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001934 ".previous\n" \
1935 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
1936 "push %%eax\n" \
1937 "call 10000f\n" \
1938 "10000:pop %%eax\n" \
1939 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001940 "mov " SYS_SYSCALL_ENTRYPOINT \
1941 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001942 "mov 0(%%eax), %%eax\n" \
1943 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001944 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001945 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001946 "call 10001f\n" \
1947 "10001:pop %%eax\n" \
1948 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001949 "xchg 4(%%esp), %%eax\n" \
1950 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001951 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001952 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001953 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001954 #else
1955 #define LSS_ENTRYPOINT "int $0x80\n"
1956 #endif
1957 #undef LSS_BODY
1958 #define LSS_BODY(type,args...) \
1959 long __res; \
1960 __asm__ __volatile__("push %%ebx\n" \
1961 "movl %2,%%ebx\n" \
1962 LSS_ENTRYPOINT \
1963 "pop %%ebx" \
1964 args \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07001965 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001966 LSS_RETURN(type,__res)
1967 #undef _syscall0
1968 #define _syscall0(type,name) \
1969 type LSS_NAME(name)(void) { \
1970 long __res; \
1971 __asm__ volatile(LSS_ENTRYPOINT \
1972 : "=a" (__res) \
1973 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08001974 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001975 LSS_RETURN(type,__res); \
1976 }
1977 #undef _syscall1
1978 #define _syscall1(type,name,type1,arg1) \
1979 type LSS_NAME(name)(type1 arg1) { \
1980 LSS_BODY(type, \
1981 : "=a" (__res) \
1982 : "0" (__NR_##name), "ri" ((long)(arg1))); \
1983 }
1984 #undef _syscall2
1985 #define _syscall2(type,name,type1,arg1,type2,arg2) \
1986 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
1987 LSS_BODY(type, \
1988 : "=a" (__res) \
1989 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
1990 }
1991 #undef _syscall3
1992 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
1993 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
1994 LSS_BODY(type, \
1995 : "=a" (__res) \
1996 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
1997 "d" ((long)(arg3))); \
1998 }
1999 #undef _syscall4
2000 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2001 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2002 LSS_BODY(type, \
2003 : "=a" (__res) \
2004 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2005 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2006 }
2007 #undef _syscall5
2008 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2009 type5,arg5) \
2010 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2011 type5 arg5) { \
2012 long __res; \
2013 __asm__ __volatile__("push %%ebx\n" \
2014 "movl %2,%%ebx\n" \
2015 "movl %1,%%eax\n" \
2016 LSS_ENTRYPOINT \
2017 "pop %%ebx" \
2018 : "=a" (__res) \
2019 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2020 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2021 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002022 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002023 LSS_RETURN(type,__res); \
2024 }
2025 #undef _syscall6
2026 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2027 type5,arg5,type6,arg6) \
2028 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2029 type5 arg5, type6 arg6) { \
2030 long __res; \
2031 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2032 __asm__ __volatile__("push %%ebp\n" \
2033 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002034 "movl 4(%2),%%ebp\n" \
2035 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002036 "movl %1,%%eax\n" \
2037 LSS_ENTRYPOINT \
2038 "pop %%ebx\n" \
2039 "pop %%ebp" \
2040 : "=a" (__res) \
2041 : "i" (__NR_##name), "0" ((long)(&__s)), \
2042 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2043 "S" ((long)(arg4)), "D" ((long)(arg5)) \
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002044 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002045 LSS_RETURN(type,__res); \
2046 }
2047 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2048 int flags, void *arg, int *parent_tidptr,
2049 void *newtls, int *child_tidptr) {
2050 long __res;
2051 __asm__ __volatile__(/* if (fn == NULL)
2052 * return -EINVAL;
2053 */
2054 "movl %3,%%ecx\n"
2055 "jecxz 1f\n"
2056
2057 /* if (child_stack == NULL)
2058 * return -EINVAL;
2059 */
2060 "movl %4,%%ecx\n"
2061 "jecxz 1f\n"
2062
2063 /* Set up alignment of the child stack:
2064 * child_stack = (child_stack & ~0xF) - 20;
2065 */
2066 "andl $-16,%%ecx\n"
2067 "subl $20,%%ecx\n"
2068
2069 /* Push "arg" and "fn" onto the stack that will be
2070 * used by the child.
2071 */
2072 "movl %6,%%eax\n"
2073 "movl %%eax,4(%%ecx)\n"
2074 "movl %3,%%eax\n"
2075 "movl %%eax,(%%ecx)\n"
2076
2077 /* %eax = syscall(%eax = __NR_clone,
2078 * %ebx = flags,
2079 * %ecx = child_stack,
2080 * %edx = parent_tidptr,
2081 * %esi = newtls,
2082 * %edi = child_tidptr)
2083 * Also, make sure that %ebx gets preserved as it is
2084 * used in PIC mode.
2085 */
2086 "movl %8,%%esi\n"
2087 "movl %7,%%edx\n"
2088 "movl %5,%%eax\n"
2089 "movl %9,%%edi\n"
2090 "pushl %%ebx\n"
2091 "movl %%eax,%%ebx\n"
2092 "movl %2,%%eax\n"
2093 LSS_ENTRYPOINT
2094
2095 /* In the parent: restore %ebx
2096 * In the child: move "fn" into %ebx
2097 */
2098 "popl %%ebx\n"
2099
2100 /* if (%eax != 0)
2101 * return %eax;
2102 */
2103 "test %%eax,%%eax\n"
2104 "jnz 1f\n"
2105
2106 /* In the child, now. Terminate frame pointer chain.
2107 */
2108 "movl $0,%%ebp\n"
2109
2110 /* Call "fn". "arg" is already on the stack.
2111 */
2112 "call *%%ebx\n"
2113
2114 /* Call _exit(%ebx). Unfortunately older versions
2115 * of gcc restrict the number of arguments that can
2116 * be passed to asm(). So, we need to hard-code the
2117 * system call number.
2118 */
2119 "movl %%eax,%%ebx\n"
2120 "movl $1,%%eax\n"
2121 LSS_ENTRYPOINT
2122
2123 /* Return to parent.
2124 */
2125 "1:\n"
2126 : "=a" (__res)
2127 : "0"(-EINVAL), "i"(__NR_clone),
2128 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2129 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
Joshua Perazabe2d5a82020-04-15 14:36:21 -07002130 : "memory", "ecx", "edx", "esi", "edi");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002131 LSS_RETURN(int, __res);
2132 }
2133
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002134 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2135 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2136
2137 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2138 /* On i386, the kernel does not know how to return from a signal
2139 * handler. Instead, it relies on user space to provide a
2140 * restorer function that calls the {rt_,}sigreturn() system call.
2141 * Unfortunately, we cannot just reference the glibc version of this
2142 * function, as glibc goes out of its way to make it inaccessible.
2143 */
2144 void (*res)(void);
2145 __asm__ __volatile__("call 2f\n"
2146 "0:.align 16\n"
2147 "1:movl %1,%%eax\n"
2148 LSS_ENTRYPOINT
2149 "2:popl %0\n"
2150 "addl $(1b-0b),%0\n"
2151 : "=a" (res)
2152 : "i" (__NR_rt_sigreturn));
2153 return res;
2154 }
2155 LSS_INLINE void (*LSS_NAME(restore)(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:pop %%eax\n"
2166 "movl %1,%%eax\n"
2167 LSS_ENTRYPOINT
2168 "2:popl %0\n"
2169 "addl $(1b-0b),%0\n"
2170 : "=a" (res)
2171 : "i" (__NR_sigreturn));
2172 return res;
2173 }
2174 #elif defined(__x86_64__)
2175 /* There are no known problems with any of the _syscallX() macros
2176 * currently shipping for x86_64, but we still need to be able to define
2177 * our own version so that we can override the location of the errno
2178 * location (e.g. when using the clone() system call with the CLONE_VM
2179 * option).
2180 */
2181 #undef LSS_ENTRYPOINT
2182 #ifdef SYS_SYSCALL_ENTRYPOINT
2183 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2184 void (**entrypoint)(void);
2185 asm volatile(".bss\n"
2186 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002187 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2188 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002189 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002190 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002191 : "=r"(entrypoint));
2192 return entrypoint;
2193 }
2194
2195 #define LSS_ENTRYPOINT \
2196 ".bss\n" \
2197 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002198 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2199 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002200 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002201 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002202 "mov 0(%%rcx), %%rcx\n" \
2203 "test %%rcx, %%rcx\n" \
2204 "jz 10001f\n" \
2205 "call *%%rcx\n" \
2206 "jmp 10002f\n" \
2207 "10001:syscall\n" \
2208 "10002:\n"
2209
2210 #else
2211 #define LSS_ENTRYPOINT "syscall\n"
2212 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002213
2214 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2215 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2216 * sign extension. We can't cast pointers directly because those are
2217 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2218 * to an integer of a different size.
2219 */
2220 #undef LSS_SYSCALL_ARG
2221 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2222 #undef _LSS_RETURN
2223 #define _LSS_RETURN(type, res, cast) \
2224 do { \
2225 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
2226 LSS_ERRNO = -(res); \
2227 res = -1; \
2228 } \
2229 return (type)(cast)(res); \
2230 } while (0)
2231 #undef LSS_RETURN
2232 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2233
2234 #undef _LSS_BODY
2235 #define _LSS_BODY(nr, type, name, cast, ...) \
2236 long long __res; \
2237 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2238 : "=a" (__res) \
2239 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2240 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2241 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002242 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002243 #define LSS_BODY(nr, type, name, args...) \
2244 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2245
2246 #undef LSS_BODY_ASM0
2247 #undef LSS_BODY_ASM1
2248 #undef LSS_BODY_ASM2
2249 #undef LSS_BODY_ASM3
2250 #undef LSS_BODY_ASM4
2251 #undef LSS_BODY_ASM5
2252 #undef LSS_BODY_ASM6
2253 #define LSS_BODY_ASM0
2254 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2255 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2256 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2257 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2258 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2259 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2260
2261 #undef LSS_BODY_CLOBBER0
2262 #undef LSS_BODY_CLOBBER1
2263 #undef LSS_BODY_CLOBBER2
2264 #undef LSS_BODY_CLOBBER3
2265 #undef LSS_BODY_CLOBBER4
2266 #undef LSS_BODY_CLOBBER5
2267 #undef LSS_BODY_CLOBBER6
2268 #define LSS_BODY_CLOBBER0
2269 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2270 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2271 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2272 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2273 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2274 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2275
2276 #undef LSS_BODY_ARG0
2277 #undef LSS_BODY_ARG1
2278 #undef LSS_BODY_ARG2
2279 #undef LSS_BODY_ARG3
2280 #undef LSS_BODY_ARG4
2281 #undef LSS_BODY_ARG5
2282 #undef LSS_BODY_ARG6
2283 #define LSS_BODY_ARG0()
2284 #define LSS_BODY_ARG1(arg1) \
2285 LSS_BODY_ARG0(), "D" (arg1)
2286 #define LSS_BODY_ARG2(arg1, arg2) \
2287 LSS_BODY_ARG1(arg1), "S" (arg2)
2288 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2289 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2290 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2291 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2292 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2293 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2294 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2295 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2296
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002297 #undef _syscall0
2298 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002299 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002300 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002301 }
2302 #undef _syscall1
2303 #define _syscall1(type,name,type1,arg1) \
2304 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002305 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002306 }
2307 #undef _syscall2
2308 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2309 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002310 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002311 }
2312 #undef _syscall3
2313 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2314 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002315 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2316 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002317 }
2318 #undef _syscall4
2319 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2320 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002321 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2322 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002323 }
2324 #undef _syscall5
2325 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2326 type5,arg5) \
2327 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2328 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002329 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2330 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2331 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002332 }
2333 #undef _syscall6
2334 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2335 type5,arg5,type6,arg6) \
2336 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2337 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002338 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2339 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2340 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002341 }
2342 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2343 int flags, void *arg, int *parent_tidptr,
2344 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002345 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002346 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002347 __asm__ __volatile__(/* if (fn == NULL)
2348 * return -EINVAL;
2349 */
2350 "testq %4,%4\n"
2351 "jz 1f\n"
2352
2353 /* if (child_stack == NULL)
2354 * return -EINVAL;
2355 */
2356 "testq %5,%5\n"
2357 "jz 1f\n"
2358
2359 /* childstack -= 2*sizeof(void *);
2360 */
2361 "subq $16,%5\n"
2362
2363 /* Push "arg" and "fn" onto the stack that will be
2364 * used by the child.
2365 */
2366 "movq %7,8(%5)\n"
2367 "movq %4,0(%5)\n"
2368
2369 /* %rax = syscall(%rax = __NR_clone,
2370 * %rdi = flags,
2371 * %rsi = child_stack,
2372 * %rdx = parent_tidptr,
2373 * %r8 = new_tls,
2374 * %r10 = child_tidptr)
2375 */
2376 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002377 "movq %9,%%r8\n"
2378 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002379 LSS_ENTRYPOINT
2380
2381 /* if (%rax != 0)
2382 * return;
2383 */
2384 "testq %%rax,%%rax\n"
2385 "jnz 1f\n"
2386
2387 /* In the child. Terminate frame pointer chain.
2388 */
2389 "xorq %%rbp,%%rbp\n"
2390
2391 /* Call "fn(arg)".
2392 */
2393 "popq %%rax\n"
2394 "popq %%rdi\n"
2395 "call *%%rax\n"
2396
2397 /* Call _exit(%ebx).
2398 */
2399 "movq %%rax,%%rdi\n"
2400 "movq %3,%%rax\n"
2401 LSS_ENTRYPOINT
2402
2403 /* Return to parent.
2404 */
2405 "1:\n"
2406 : "=a" (__res)
2407 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002408 "r"(LSS_SYSCALL_ARG(fn)),
2409 "S"(LSS_SYSCALL_ARG(child_stack)),
2410 "D"(LSS_SYSCALL_ARG(flags)),
2411 "r"(LSS_SYSCALL_ARG(arg)),
2412 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2413 "r"(LSS_SYSCALL_ARG(newtls)),
2414 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002415 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002416 }
2417 LSS_RETURN(int, __res);
2418 }
2419 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002420
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002421 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2422 /* On x86-64, the kernel does not know how to return from
2423 * a signal handler. Instead, it relies on user space to provide a
2424 * restorer function that calls the rt_sigreturn() system call.
2425 * Unfortunately, we cannot just reference the glibc version of this
2426 * function, as glibc goes out of its way to make it inaccessible.
2427 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002428 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002429 __asm__ __volatile__("jmp 2f\n"
2430 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002431 "1:movq %1,%%rax\n"
2432 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002433 "2:leaq 1b(%%rip),%0\n"
2434 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002435 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002436 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002437 }
2438 #elif defined(__ARM_ARCH_3__)
2439 /* Most definitions of _syscallX() neglect to mark "memory" as being
2440 * clobbered. This causes problems with compilers, that do a better job
2441 * at optimizing across __asm__ calls.
2442 * So, we just have to redefine all of the _syscallX() macros.
2443 */
2444 #undef LSS_REG
2445 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2446 #undef LSS_BODY
2447 #define LSS_BODY(type,name,args...) \
2448 register long __res_r0 __asm__("r0"); \
2449 long __res; \
2450 __asm__ __volatile__ (__syscall(name) \
2451 : "=r"(__res_r0) : args : "lr", "memory"); \
2452 __res = __res_r0; \
2453 LSS_RETURN(type, __res)
2454 #undef _syscall0
2455 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002456 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002457 LSS_BODY(type, name); \
2458 }
2459 #undef _syscall1
2460 #define _syscall1(type, name, type1, arg1) \
2461 type LSS_NAME(name)(type1 arg1) { \
2462 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2463 }
2464 #undef _syscall2
2465 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2466 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2467 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2468 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2469 }
2470 #undef _syscall3
2471 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2472 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2473 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2474 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2475 }
2476 #undef _syscall4
2477 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2478 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2479 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2480 LSS_REG(3, arg4); \
2481 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2482 }
2483 #undef _syscall5
2484 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2485 type5,arg5) \
2486 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2487 type5 arg5) { \
2488 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2489 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2490 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2491 "r"(__r4)); \
2492 }
2493 #undef _syscall6
2494 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2495 type5,arg5,type6,arg6) \
2496 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2497 type5 arg5, type6 arg6) { \
2498 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2499 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2500 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2501 "r"(__r4), "r"(__r5)); \
2502 }
2503 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2504 int flags, void *arg, int *parent_tidptr,
2505 void *newtls, int *child_tidptr) {
2506 long __res;
2507 {
2508 register int __flags __asm__("r0") = flags;
2509 register void *__stack __asm__("r1") = child_stack;
2510 register void *__ptid __asm__("r2") = parent_tidptr;
2511 register void *__tls __asm__("r3") = newtls;
2512 register int *__ctid __asm__("r4") = child_tidptr;
2513 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2514 * return -EINVAL;
2515 */
2516 "cmp %2,#0\n"
2517 "cmpne %3,#0\n"
2518 "moveq %0,%1\n"
2519 "beq 1f\n"
2520
2521 /* Push "arg" and "fn" onto the stack that will be
2522 * used by the child.
2523 */
2524 "str %5,[%3,#-4]!\n"
2525 "str %2,[%3,#-4]!\n"
2526
2527 /* %r0 = syscall(%r0 = flags,
2528 * %r1 = child_stack,
2529 * %r2 = parent_tidptr,
2530 * %r3 = newtls,
2531 * %r4 = child_tidptr)
2532 */
2533 __syscall(clone)"\n"
2534
2535 /* if (%r0 != 0)
2536 * return %r0;
2537 */
2538 "movs %0,r0\n"
2539 "bne 1f\n"
2540
2541 /* In the child, now. Call "fn(arg)".
2542 */
2543 "ldr r0,[sp, #4]\n"
2544 "mov lr,pc\n"
2545 "ldr pc,[sp]\n"
2546
2547 /* Call _exit(%r0).
2548 */
2549 __syscall(exit)"\n"
2550 "1:\n"
2551 : "=r" (__res)
2552 : "i"(-EINVAL),
2553 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2554 "r"(__ptid), "r"(__tls), "r"(__ctid)
2555 : "cc", "lr", "memory");
2556 }
2557 LSS_RETURN(int, __res);
2558 }
2559 #elif defined(__ARM_EABI__)
2560 /* Most definitions of _syscallX() neglect to mark "memory" as being
2561 * clobbered. This causes problems with compilers, that do a better job
2562 * at optimizing across __asm__ calls.
2563 * So, we just have to redefine all fo the _syscallX() macros.
2564 */
2565 #undef LSS_REG
2566 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2567 #undef LSS_BODY
2568 #define LSS_BODY(type,name,args...) \
2569 register long __res_r0 __asm__("r0"); \
2570 long __res; \
2571 __asm__ __volatile__ ("push {r7}\n" \
2572 "mov r7, %1\n" \
2573 "swi 0x0\n" \
2574 "pop {r7}\n" \
2575 : "=r"(__res_r0) \
2576 : "i"(__NR_##name) , ## args \
2577 : "lr", "memory"); \
2578 __res = __res_r0; \
2579 LSS_RETURN(type, __res)
2580 #undef _syscall0
2581 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002582 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002583 LSS_BODY(type, name); \
2584 }
2585 #undef _syscall1
2586 #define _syscall1(type, name, type1, arg1) \
2587 type LSS_NAME(name)(type1 arg1) { \
2588 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2589 }
2590 #undef _syscall2
2591 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2592 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2593 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2594 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2595 }
2596 #undef _syscall3
2597 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2598 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2599 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2600 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2601 }
2602 #undef _syscall4
2603 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2604 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2605 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2606 LSS_REG(3, arg4); \
2607 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2608 }
2609 #undef _syscall5
2610 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2611 type5,arg5) \
2612 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2613 type5 arg5) { \
2614 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2615 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2616 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2617 "r"(__r4)); \
2618 }
2619 #undef _syscall6
2620 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2621 type5,arg5,type6,arg6) \
2622 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2623 type5 arg5, type6 arg6) { \
2624 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2625 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2626 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2627 "r"(__r4), "r"(__r5)); \
2628 }
2629 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2630 int flags, void *arg, int *parent_tidptr,
2631 void *newtls, int *child_tidptr) {
2632 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002633 if (fn == NULL || child_stack == NULL) {
2634 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002635 LSS_RETURN(int, __res);
2636 }
2637
2638 /* Push "arg" and "fn" onto the stack that will be
2639 * used by the child.
2640 */
2641 {
2642 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2643 cstack[0] = (uintptr_t)fn;
2644 cstack[1] = (uintptr_t)arg;
2645 child_stack = cstack;
2646 }
2647 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002648 register int __flags __asm__("r0") = flags;
2649 register void *__stack __asm__("r1") = child_stack;
2650 register void *__ptid __asm__("r2") = parent_tidptr;
2651 register void *__tls __asm__("r3") = newtls;
2652 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002653 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002654#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002655 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002656#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002657 /* %r0 = syscall(%r0 = flags,
2658 * %r1 = child_stack,
2659 * %r2 = parent_tidptr,
2660 * %r3 = newtls,
2661 * %r4 = child_tidptr)
2662 */
2663 "mov r7, %6\n"
2664 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002665
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002666 /* if (%r0 != 0)
2667 * return %r0;
2668 */
2669 "cmp r0, #0\n"
2670 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002671
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002672 /* In the child, now. Call "fn(arg)".
2673 */
2674 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002675
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002676 "ldr lr,[sp]\n"
2677 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002678
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002679 /* Call _exit(%r0).
2680 */
2681 "mov r7, %7\n"
2682 "swi 0x0\n"
2683 /* Unreachable */
2684 "bkpt #0\n"
2685 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002686#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002687 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002688#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002689 "movs %0,r0\n"
2690 : "=r"(__res)
2691 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2692 "i"(__NR_clone), "i"(__NR_exit)
2693 : "cc", "lr", "memory"
2694#ifndef __thumb2__
2695 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002696#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002697 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002698 }
2699 LSS_RETURN(int, __res);
2700 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002701 #elif defined(__aarch64__)
2702 /* Most definitions of _syscallX() neglect to mark "memory" as being
2703 * clobbered. This causes problems with compilers, that do a better job
2704 * at optimizing across __asm__ calls.
2705 * So, we just have to redefine all of the _syscallX() macros.
2706 */
2707 #undef LSS_REG
2708 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2709 #undef LSS_BODY
2710 #define LSS_BODY(type,name,args...) \
2711 register int64_t __res_x0 __asm__("x0"); \
2712 int64_t __res; \
2713 __asm__ __volatile__ ("mov x8, %1\n" \
2714 "svc 0x0\n" \
2715 : "=r"(__res_x0) \
2716 : "i"(__NR_##name) , ## args \
2717 : "x8", "memory"); \
2718 __res = __res_x0; \
2719 LSS_RETURN(type, __res)
2720 #undef _syscall0
2721 #define _syscall0(type, name) \
2722 type LSS_NAME(name)(void) { \
2723 LSS_BODY(type, name); \
2724 }
2725 #undef _syscall1
2726 #define _syscall1(type, name, type1, arg1) \
2727 type LSS_NAME(name)(type1 arg1) { \
2728 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2729 }
2730 #undef _syscall2
2731 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2732 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2733 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2734 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2735 }
2736 #undef _syscall3
2737 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2738 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2739 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2740 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2741 }
2742 #undef _syscall4
2743 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2744 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2745 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2746 LSS_REG(3, arg4); \
2747 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2748 }
2749 #undef _syscall5
2750 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2751 type5,arg5) \
2752 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2753 type5 arg5) { \
2754 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2755 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2756 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2757 "r"(__r4)); \
2758 }
2759 #undef _syscall6
2760 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2761 type5,arg5,type6,arg6) \
2762 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2763 type5 arg5, type6 arg6) { \
2764 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2765 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2766 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2767 "r"(__r4), "r"(__r5)); \
2768 }
2769
2770 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2771 int flags, void *arg, int *parent_tidptr,
2772 void *newtls, int *child_tidptr) {
2773 int64_t __res;
2774 {
2775 register uint64_t __flags __asm__("x0") = flags;
2776 register void *__stack __asm__("x1") = child_stack;
2777 register void *__ptid __asm__("x2") = parent_tidptr;
2778 register void *__tls __asm__("x3") = newtls;
2779 register int *__ctid __asm__("x4") = child_tidptr;
2780 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2781 * used by the child.
2782 */
2783 "stp %1, %4, [%2, #-16]!\n"
2784
2785 /* %x0 = syscall(%x0 = flags,
2786 * %x1 = child_stack,
2787 * %x2 = parent_tidptr,
2788 * %x3 = newtls,
2789 * %x4 = child_tidptr)
2790 */
2791 "mov x8, %8\n"
2792 "svc 0x0\n"
2793
2794 /* if (%r0 != 0)
2795 * return %r0;
2796 */
2797 "mov %0, x0\n"
2798 "cbnz x0, 1f\n"
2799
2800 /* In the child, now. Call "fn(arg)".
2801 */
2802 "ldp x1, x0, [sp], #16\n"
2803 "blr x1\n"
2804
2805 /* Call _exit(%r0).
2806 */
2807 "mov x8, %9\n"
2808 "svc 0x0\n"
2809 "1:\n"
2810 : "=r" (__res)
2811 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2812 "r"(__ptid), "r"(__tls), "r"(__ctid),
2813 "i"(__NR_clone), "i"(__NR_exit)
2814 : "cc", "x8", "memory");
2815 }
2816 LSS_RETURN(int, __res);
2817 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002818 #elif defined(__mips__)
2819 #undef LSS_REG
2820 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2821 (unsigned long)(a)
2822 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002823 #undef LSS_SYSCALL_CLOBBERS
2824 #if _MIPS_SIM == _MIPS_SIM_ABI32
2825 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2826 "$11", "$12", "$13", "$14", "$15", \
2827 "$24", "$25", "hi", "lo", "memory"
2828 #else
2829 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2830 "$13", "$14", "$15", "$24", "$25", \
2831 "hi", "lo", "memory"
2832 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002833 #define LSS_BODY(type,name,r7,...) \
2834 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2835 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002836 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002837 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002838 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002839 LSS_RETURN(type, __v0, __r7)
2840 #undef _syscall0
2841 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002842 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002843 register unsigned long __r7 __asm__("$7"); \
2844 LSS_BODY(type, name, "=r"); \
2845 }
2846 #undef _syscall1
2847 #define _syscall1(type, name, type1, arg1) \
2848 type LSS_NAME(name)(type1 arg1) { \
2849 register unsigned long __r7 __asm__("$7"); \
2850 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2851 }
2852 #undef _syscall2
2853 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2854 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2855 register unsigned long __r7 __asm__("$7"); \
2856 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2857 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2858 }
2859 #undef _syscall3
2860 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2861 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2862 register unsigned long __r7 __asm__("$7"); \
2863 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2864 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2865 }
2866 #undef _syscall4
2867 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2868 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2869 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2870 LSS_REG(7, arg4); \
2871 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2872 }
2873 #undef _syscall5
2874 #if _MIPS_SIM == _MIPS_SIM_ABI32
2875 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2876 * on the stack, whereas the new APIs use registers "r8" and "r9".
2877 */
2878 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2879 type5,arg5) \
2880 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2881 type5 arg5) { \
2882 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2883 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002884 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002885 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002886 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002887 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002888 "syscall\n" \
2889 "addiu $29, 32\n" \
2890 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002891 : "+r"(__v0), "+r" (__r7) \
2892 : "r"(__r4), "r"(__r5), \
2893 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002894 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002895 "$13", "$14", "$15", "$24", "$25", \
2896 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002897 LSS_RETURN(type, __v0, __r7); \
2898 }
2899 #else
2900 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2901 type5,arg5) \
2902 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2903 type5 arg5) { \
2904 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2905 LSS_REG(7, arg4); LSS_REG(8, arg5); \
2906 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2907 "r"(__r8)); \
2908 }
2909 #endif
2910 #undef _syscall6
2911 #if _MIPS_SIM == _MIPS_SIM_ABI32
2912 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2913 * on the stack, whereas the new APIs use registers "r8" and "r9".
2914 */
2915 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2916 type5,arg5,type6,arg6) \
2917 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2918 type5 arg5, type6 arg6) { \
2919 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2920 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002921 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002922 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002923 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002924 "sw %5, 16($29)\n" \
2925 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002926 "syscall\n" \
2927 "addiu $29, 32\n" \
2928 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002929 : "+r"(__v0), "+r" (__r7) \
2930 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002931 "r"(__r6), "r" ((unsigned long)arg5), \
2932 "r" ((unsigned long)arg6) \
2933 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002934 "$13", "$14", "$15", "$24", "$25", \
2935 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002936 LSS_RETURN(type, __v0, __r7); \
2937 }
2938 #else
2939 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2940 type5,arg5,type6,arg6) \
2941 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2942 type5 arg5,type6 arg6) { \
2943 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2944 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
2945 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2946 "r"(__r8), "r"(__r9)); \
2947 }
2948 #endif
2949 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2950 int flags, void *arg, int *parent_tidptr,
2951 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00002952 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002953 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
2954 {
2955 register int __flags __asm__("$4") = flags;
2956 register void *__stack __asm__("$5") = child_stack;
2957 register void *__ptid __asm__("$6") = parent_tidptr;
2958 register int *__ctid __asm__("$8") = child_tidptr;
2959 __asm__ __volatile__(
2960 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
2961 "subu $29,24\n"
2962 #elif _MIPS_SIM == _MIPS_SIM_NABI32
2963 "sub $29,16\n"
2964 #else
2965 "dsubu $29,16\n"
2966 #endif
2967
2968 /* if (fn == NULL || child_stack == NULL)
2969 * return -EINVAL;
2970 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002971 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002972 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002973
2974 /* Push "arg" and "fn" onto the stack that will be
2975 * used by the child.
2976 */
2977 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002978 "subu %5,32\n"
2979 "sw %4,0(%5)\n"
2980 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002981 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002982 "sub %5,32\n"
2983 "sw %4,0(%5)\n"
2984 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002985 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00002986 "dsubu %5,32\n"
2987 "sd %4,0(%5)\n"
2988 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002989 #endif
2990
2991 /* $7 = syscall($4 = flags,
2992 * $5 = child_stack,
2993 * $6 = parent_tidptr,
2994 * $7 = newtls,
2995 * $8 = child_tidptr)
2996 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002997 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002998 "syscall\n"
2999
3000 /* if ($7 != 0)
3001 * return $2;
3002 */
3003 "bnez $7,1f\n"
3004 "bnez $2,1f\n"
3005
3006 /* In the child, now. Call "fn(arg)".
3007 */
3008 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3009 "lw $25,0($29)\n"
3010 "lw $4,4($29)\n"
3011 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3012 "lw $25,0($29)\n"
3013 "lw $4,8($29)\n"
3014 #else
3015 "ld $25,0($29)\n"
3016 "ld $4,8($29)\n"
3017 #endif
3018 "jalr $25\n"
3019
3020 /* Call _exit($2)
3021 */
3022 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003023 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003024 "syscall\n"
3025
3026 "1:\n"
3027 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3028 "addu $29, 24\n"
3029 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3030 "add $29, 16\n"
3031 #else
3032 "daddu $29,16\n"
3033 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003034 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003035 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3036 "r"(__stack), "r"(__flags), "r"(arg),
3037 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003038 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003039 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003040 }
3041 LSS_RETURN(int, __v0, __r7);
3042 }
3043 #elif defined (__PPC__)
3044 #undef LSS_LOADARGS_0
3045 #define LSS_LOADARGS_0(name, dummy...) \
3046 __sc_0 = __NR_##name
3047 #undef LSS_LOADARGS_1
3048 #define LSS_LOADARGS_1(name, arg1) \
3049 LSS_LOADARGS_0(name); \
3050 __sc_3 = (unsigned long) (arg1)
3051 #undef LSS_LOADARGS_2
3052 #define LSS_LOADARGS_2(name, arg1, arg2) \
3053 LSS_LOADARGS_1(name, arg1); \
3054 __sc_4 = (unsigned long) (arg2)
3055 #undef LSS_LOADARGS_3
3056 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3057 LSS_LOADARGS_2(name, arg1, arg2); \
3058 __sc_5 = (unsigned long) (arg3)
3059 #undef LSS_LOADARGS_4
3060 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3061 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3062 __sc_6 = (unsigned long) (arg4)
3063 #undef LSS_LOADARGS_5
3064 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3065 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3066 __sc_7 = (unsigned long) (arg5)
3067 #undef LSS_LOADARGS_6
3068 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3069 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3070 __sc_8 = (unsigned long) (arg6)
3071 #undef LSS_ASMINPUT_0
3072 #define LSS_ASMINPUT_0 "0" (__sc_0)
3073 #undef LSS_ASMINPUT_1
3074 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3075 #undef LSS_ASMINPUT_2
3076 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3077 #undef LSS_ASMINPUT_3
3078 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3079 #undef LSS_ASMINPUT_4
3080 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3081 #undef LSS_ASMINPUT_5
3082 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3083 #undef LSS_ASMINPUT_6
3084 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3085 #undef LSS_BODY
3086 #define LSS_BODY(nr, type, name, args...) \
3087 long __sc_ret, __sc_err; \
3088 { \
3089 register unsigned long __sc_0 __asm__ ("r0"); \
3090 register unsigned long __sc_3 __asm__ ("r3"); \
3091 register unsigned long __sc_4 __asm__ ("r4"); \
3092 register unsigned long __sc_5 __asm__ ("r5"); \
3093 register unsigned long __sc_6 __asm__ ("r6"); \
3094 register unsigned long __sc_7 __asm__ ("r7"); \
3095 register unsigned long __sc_8 __asm__ ("r8"); \
3096 \
3097 LSS_LOADARGS_##nr(name, args); \
3098 __asm__ __volatile__ \
3099 ("sc\n\t" \
3100 "mfcr %0" \
3101 : "=&r" (__sc_0), \
3102 "=&r" (__sc_3), "=&r" (__sc_4), \
3103 "=&r" (__sc_5), "=&r" (__sc_6), \
3104 "=&r" (__sc_7), "=&r" (__sc_8) \
3105 : LSS_ASMINPUT_##nr \
3106 : "cr0", "ctr", "memory", \
3107 "r9", "r10", "r11", "r12"); \
3108 __sc_ret = __sc_3; \
3109 __sc_err = __sc_0; \
3110 } \
3111 LSS_RETURN(type, __sc_ret, __sc_err)
3112 #undef _syscall0
3113 #define _syscall0(type, name) \
3114 type LSS_NAME(name)(void) { \
3115 LSS_BODY(0, type, name); \
3116 }
3117 #undef _syscall1
3118 #define _syscall1(type, name, type1, arg1) \
3119 type LSS_NAME(name)(type1 arg1) { \
3120 LSS_BODY(1, type, name, arg1); \
3121 }
3122 #undef _syscall2
3123 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3124 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3125 LSS_BODY(2, type, name, arg1, arg2); \
3126 }
3127 #undef _syscall3
3128 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3129 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3130 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3131 }
3132 #undef _syscall4
3133 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3134 type4, arg4) \
3135 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3136 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3137 }
3138 #undef _syscall5
3139 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3140 type4, arg4, type5, arg5) \
3141 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3142 type5 arg5) { \
3143 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3144 }
3145 #undef _syscall6
3146 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3147 type4, arg4, type5, arg5, type6, arg6) \
3148 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3149 type5 arg5, type6 arg6) { \
3150 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3151 }
3152 /* clone function adapted from glibc 2.3.6 clone.S */
3153 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3154 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3155 */
3156 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3157 int flags, void *arg, int *parent_tidptr,
3158 void *newtls, int *child_tidptr) {
3159 long __ret, __err;
3160 {
3161 register int (*__fn)(void *) __asm__ ("r8") = fn;
3162 register void *__cstack __asm__ ("r4") = child_stack;
3163 register int __flags __asm__ ("r3") = flags;
3164 register void * __arg __asm__ ("r9") = arg;
3165 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3166 register void * __newtls __asm__ ("r6") = newtls;
3167 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3168 __asm__ __volatile__(
3169 /* check for fn == NULL
3170 * and child_stack == NULL
3171 */
3172 "cmpwi cr0, %6, 0\n\t"
3173 "cmpwi cr1, %7, 0\n\t"
3174 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3175 "beq- cr0, 1f\n\t"
3176
3177 /* set up stack frame for child */
3178 "clrrwi %7, %7, 4\n\t"
3179 "li 0, 0\n\t"
3180 "stwu 0, -16(%7)\n\t"
3181
3182 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3183 "mr 28, %6\n\t"
3184 "mr 29, %7\n\t"
3185 "mr 27, %9\n\t"
3186
3187 /* syscall */
3188 "li 0, %4\n\t"
3189 /* flags already in r3
3190 * child_stack already in r4
3191 * ptidptr already in r5
3192 * newtls already in r6
3193 * ctidptr already in r7
3194 */
3195 "sc\n\t"
3196
3197 /* Test if syscall was successful */
3198 "cmpwi cr1, 3, 0\n\t"
3199 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3200 "bne- cr1, 1f\n\t"
3201
3202 /* Do the function call */
3203 "mtctr 28\n\t"
3204 "mr 3, 27\n\t"
3205 "bctrl\n\t"
3206
3207 /* Call _exit(r3) */
3208 "li 0, %5\n\t"
3209 "sc\n\t"
3210
3211 /* Return to parent */
3212 "1:\n"
3213 "mfcr %1\n\t"
3214 "mr %0, 3\n\t"
3215 : "=r" (__ret), "=r" (__err)
3216 : "0" (-1), "1" (EINVAL),
3217 "i" (__NR_clone), "i" (__NR_exit),
3218 "r" (__fn), "r" (__cstack), "r" (__flags),
3219 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3220 "r" (__ctidptr)
3221 : "cr0", "cr1", "memory", "ctr",
3222 "r0", "r29", "r27", "r28");
3223 }
3224 LSS_RETURN(int, __ret, __err);
3225 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003226 #elif defined(__s390__)
3227 #undef LSS_REG
3228 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3229 #undef LSS_BODY
3230 #define LSS_BODY(type, name, args...) \
3231 register unsigned long __nr __asm__("r1") \
3232 = (unsigned long)(__NR_##name); \
3233 register long __res_r2 __asm__("r2"); \
3234 long __res; \
3235 __asm__ __volatile__ \
3236 ("svc 0\n\t" \
3237 : "=d"(__res_r2) \
3238 : "d"(__nr), ## args \
3239 : "memory"); \
3240 __res = __res_r2; \
3241 LSS_RETURN(type, __res)
3242 #undef _syscall0
3243 #define _syscall0(type, name) \
3244 type LSS_NAME(name)(void) { \
3245 LSS_BODY(type, name); \
3246 }
3247 #undef _syscall1
3248 #define _syscall1(type, name, type1, arg1) \
3249 type LSS_NAME(name)(type1 arg1) { \
3250 LSS_REG(2, arg1); \
3251 LSS_BODY(type, name, "0"(__r2)); \
3252 }
3253 #undef _syscall2
3254 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3255 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3256 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3257 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3258 }
3259 #undef _syscall3
3260 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3261 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3262 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3263 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3264 }
3265 #undef _syscall4
3266 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3267 type4, arg4) \
3268 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3269 type4 arg4) { \
3270 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3271 LSS_REG(5, arg4); \
3272 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3273 "d"(__r5)); \
3274 }
3275 #undef _syscall5
3276 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3277 type4, arg4, type5, arg5) \
3278 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3279 type4 arg4, type5 arg5) { \
3280 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3281 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3282 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3283 "d"(__r5), "d"(__r6)); \
3284 }
3285 #undef _syscall6
3286 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3287 type4, arg4, type5, arg5, type6, arg6) \
3288 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3289 type4 arg4, type5 arg5, type6 arg6) { \
3290 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3291 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3292 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3293 "d"(__r5), "d"(__r6), "d"(__r7)); \
3294 }
3295 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3296 int flags, void *arg, int *parent_tidptr,
3297 void *newtls, int *child_tidptr) {
3298 long __ret;
3299 {
3300 register int (*__fn)(void *) __asm__ ("r1") = fn;
3301 register void *__cstack __asm__ ("r2") = child_stack;
3302 register int __flags __asm__ ("r3") = flags;
3303 register void *__arg __asm__ ("r0") = arg;
3304 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3305 register void *__newtls __asm__ ("r6") = newtls;
3306 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3307 __asm__ __volatile__ (
3308 #ifndef __s390x__
3309 /* arg already in r0 */
3310 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3311 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3312 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3313 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3314 /* flags already in r3 */
3315 /* parent_tidptr already in r4 */
3316 /* child_tidptr already in r5 */
3317 /* newtls already in r6 */
3318 "svc %2\n\t" /* invoke clone syscall */
3319 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3320 "jnz 1f\n\t" /* return to parent if non-zero */
3321 /* start child thread */
3322 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3323 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3324 "xc 0(4,%%r15), 0(%%r15)\n\t"
3325 "basr %%r14, %4\n\t" /* jump to fn */
3326 "svc %3\n" /* invoke exit syscall */
3327 "1:\n"
3328 #else
3329 /* arg already in r0 */
3330 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3331 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3332 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3333 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3334 /* flags already in r3 */
3335 /* parent_tidptr already in r4 */
3336 /* child_tidptr already in r5 */
3337 /* newtls already in r6 */
3338 "svc %2\n\t" /* invoke clone syscall */
3339 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3340 "jnz 1f\n\t" /* return to parent if non-zero */
3341 /* start child thread */
3342 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3343 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3344 "xc 0(8,%%r15), 0(%%r15)\n\t"
3345 "basr %%r14, %4\n\t" /* jump to fn */
3346 "svc %3\n" /* invoke exit syscall */
3347 "1:\n"
3348 #endif
3349 : "=r" (__ret)
3350 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3351 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3352 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3353 : "cc", "r14", "memory"
3354 );
3355 }
3356 LSS_RETURN(int, __ret);
3357 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003358 #endif
3359 #define __NR__exit __NR_exit
3360 #define __NR__gettid __NR_gettid
3361 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00003362 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003363 LSS_INLINE _syscall1(int, chdir, const char *,p)
3364 LSS_INLINE _syscall1(int, close, int, f)
3365 LSS_INLINE _syscall2(int, clock_getres, int, c,
3366 struct kernel_timespec*, t)
3367 LSS_INLINE _syscall2(int, clock_gettime, int, c,
3368 struct kernel_timespec*, t)
3369 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003370 #if defined(__NR_dup2)
3371 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003372 LSS_INLINE _syscall2(int, dup2, int, s,
3373 int, d)
3374 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003375 #if defined(__NR_dup3)
3376 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3377 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003378 LSS_INLINE _syscall3(int, execve, const char*, f,
3379 const char*const*,a,const char*const*, e)
3380 LSS_INLINE _syscall1(int, _exit, int, e)
3381 LSS_INLINE _syscall1(int, exit_group, int, e)
3382 LSS_INLINE _syscall3(int, fcntl, int, f,
3383 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003384 #if defined(__NR_fork)
3385 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003386 LSS_INLINE _syscall0(pid_t, fork)
3387 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003388 LSS_INLINE _syscall2(int, fstat, int, f,
3389 struct kernel_stat*, b)
3390 LSS_INLINE _syscall2(int, fstatfs, int, f,
3391 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003392 #if defined(__x86_64__)
3393 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3394 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
3395 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
3396 }
3397 #else
3398 LSS_INLINE _syscall2(int, ftruncate, int, f,
3399 off_t, l)
3400 #endif
Mike Frysinger171a36a2019-01-26 23:05:43 -05003401 LSS_INLINE _syscall6(int, futex, int*, u,
3402 int, o, int, v,
3403 struct kernel_timespec*, t,
3404 int*, u2, int, v2)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003405 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003406 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003407 LSS_INLINE _syscall3(int, getdents64, int, f,
3408 struct kernel_dirent64*, d, int, c)
3409 LSS_INLINE _syscall0(gid_t, getegid)
3410 LSS_INLINE _syscall0(uid_t, geteuid)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003411 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003412 LSS_INLINE _syscall0(pid_t, getpgrp)
3413 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003414 LSS_INLINE _syscall0(pid_t, getpid)
3415 LSS_INLINE _syscall0(pid_t, getppid)
3416 LSS_INLINE _syscall2(int, getpriority, int, a,
3417 int, b)
3418 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
3419 gid_t *, e, gid_t *, s)
3420 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
3421 uid_t *, e, uid_t *, s)
3422#if !defined(__ARM_EABI__)
3423 LSS_INLINE _syscall2(int, getrlimit, int, r,
3424 struct kernel_rlimit*, l)
3425#endif
3426 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
3427 LSS_INLINE _syscall0(pid_t, _gettid)
3428 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
3429 void*, tz)
3430 LSS_INLINE _syscall5(int, setxattr, const char *,p,
3431 const char *, n, const void *,v,
3432 size_t, s, int, f)
3433 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
3434 const char *, n, const void *,v,
3435 size_t, s, int, f)
3436 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
3437 const char *, n, void *, v, size_t, s)
3438 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
3439 const char *, n, void *, v, size_t, s)
3440 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
3441 char *, l, size_t, s)
3442 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
3443 char *, l, size_t, s)
3444 LSS_INLINE _syscall3(int, ioctl, int, d,
3445 int, r, void *, a)
3446 LSS_INLINE _syscall2(int, ioprio_get, int, which,
3447 int, who)
3448 LSS_INLINE _syscall3(int, ioprio_set, int, which,
3449 int, who, int, ioprio)
3450 LSS_INLINE _syscall2(int, kill, pid_t, p,
3451 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003452 #if defined(__x86_64__)
3453 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3454 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
3455 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3456 LSS_SYSCALL_ARG(w));
3457 }
3458 #else
3459 LSS_INLINE _syscall3(off_t, lseek, int, f,
3460 off_t, o, int, w)
3461 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003462 LSS_INLINE _syscall2(int, munmap, void*, s,
3463 size_t, l)
3464 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
3465 unsigned long, n, void **,g, int *, d,
3466 int *, s, int, f)
3467 LSS_INLINE _syscall3(int, mprotect, const void *,a,
3468 size_t, l, int, p)
3469 LSS_INLINE _syscall5(void*, _mremap, void*, o,
3470 size_t, os, size_t, ns,
3471 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003472 #if defined(__NR_open)
3473 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003474 LSS_INLINE _syscall3(int, open, const char*, p,
3475 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003476 #endif
3477 #if defined(__NR_poll)
3478 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003479 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
3480 unsigned int, n, int, t)
3481 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003482 #if defined(__NR_ppoll)
3483 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
3484 unsigned int, n, const struct kernel_timespec *, t,
3485 const struct kernel_sigset_t *, sigmask, size_t, s)
3486 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00003487 LSS_INLINE _syscall5(int, prctl, int, option,
3488 unsigned long, arg2,
3489 unsigned long, arg3,
3490 unsigned long, arg4,
3491 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003492 LSS_INLINE _syscall4(long, ptrace, int, r,
3493 pid_t, p, void *, a, void *, d)
3494 #if defined(__NR_quotactl)
3495 // Defined on x86_64 / i386 only
3496 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
3497 int, id, caddr_t, addr)
3498 #endif
3499 LSS_INLINE _syscall3(ssize_t, read, int, f,
3500 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003501 #if defined(__NR_readlink)
3502 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003503 LSS_INLINE _syscall3(int, readlink, const char*, p,
3504 char*, b, size_t, s)
3505 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003506 #if defined(__NR_readlinkat)
3507 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
3508 size_t, s)
3509 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003510 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
3511 const struct kernel_sigaction*, a,
3512 struct kernel_sigaction*, o, size_t, c)
3513 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
3514 size_t, c)
3515 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
3516 const struct kernel_sigset_t*, s,
3517 struct kernel_sigset_t*, o, size_t, c)
3518 LSS_INLINE _syscall2(int, rt_sigsuspend,
3519 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08003520 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
3521 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003522 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
3523 unsigned int, l, unsigned long *, m)
3524 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
3525 unsigned int, l, unsigned long *, m)
3526 LSS_INLINE _syscall0(int, sched_yield)
3527 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
3528 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
3529 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
3530 LSS_INLINE _syscall1(int, setuid, uid_t, u)
3531 LSS_INLINE _syscall1(int, setgid, gid_t, g)
3532 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
3533 pid_t, g)
3534 LSS_INLINE _syscall3(int, setpriority, int, a,
3535 int, b, int, p)
3536 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
3537 gid_t, e, gid_t, s)
3538 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
3539 uid_t, e, uid_t, s)
3540 LSS_INLINE _syscall2(int, setrlimit, int, r,
3541 const struct kernel_rlimit*, l)
3542 LSS_INLINE _syscall0(pid_t, setsid)
3543 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
3544 const stack_t*, o)
3545 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003546 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003547 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003548 #if defined(__NR_stat)
3549 // stat is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003550 LSS_INLINE _syscall2(int, stat, const char*, f,
3551 struct kernel_stat*, b)
3552 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003553 LSS_INLINE _syscall2(int, statfs, const char*, f,
3554 struct kernel_statfs*, b)
3555 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
3556 pid_t, t, int, s)
3557 LSS_INLINE _syscall2(int, tkill, pid_t, p,
3558 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003559 #if defined(__NR_unlink)
3560 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003561 LSS_INLINE _syscall1(int, unlink, const char*, f)
3562 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003563 LSS_INLINE _syscall3(ssize_t, write, int, f,
3564 const void *, b, size_t, c)
3565 LSS_INLINE _syscall3(ssize_t, writev, int, f,
3566 const struct kernel_iovec*, v, size_t, c)
3567 #if defined(__NR_getcpu)
3568 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00003569 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003570 #endif
3571 #if defined(__x86_64__) || \
3572 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
3573 LSS_INLINE _syscall3(int, recvmsg, int, s,
3574 struct kernel_msghdr*, m, int, f)
3575 LSS_INLINE _syscall3(int, sendmsg, int, s,
3576 const struct kernel_msghdr*, m, int, f)
3577 LSS_INLINE _syscall6(int, sendto, int, s,
3578 const void*, m, size_t, l,
3579 int, f,
3580 const struct kernel_sockaddr*, a, int, t)
3581 LSS_INLINE _syscall2(int, shutdown, int, s,
3582 int, h)
3583 LSS_INLINE _syscall3(int, socket, int, d,
3584 int, t, int, p)
3585 LSS_INLINE _syscall4(int, socketpair, int, d,
3586 int, t, int, p, int*, s)
3587 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003588 #if defined(__NR_fadvise64)
3589 #if defined(__x86_64__)
3590 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3591 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
3592 int advice) {
3593 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
3594 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
3595 }
3596 #else
3597 LSS_INLINE _syscall4(int, fadvise64,
3598 int, fd, loff_t, offset, loff_t, len, int, advice)
3599 #endif
3600 #elif defined(__i386__)
3601 #define __NR__fadvise64_64 __NR_fadvise64_64
3602 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
3603 unsigned, offset_lo, unsigned, offset_hi,
3604 unsigned, len_lo, unsigned, len_hi,
3605 int, advice)
3606
3607 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
3608 loff_t len, int advice) {
3609 return LSS_NAME(_fadvise64_64)(fd,
3610 (unsigned)offset, (unsigned)(offset >>32),
3611 (unsigned)len, (unsigned)(len >> 32),
3612 advice);
3613 }
3614
3615 #elif defined(__s390__) && !defined(__s390x__)
3616 #define __NR__fadvise64_64 __NR_fadvise64_64
3617 struct kernel_fadvise64_64_args {
3618 int fd;
3619 long long offset;
3620 long long len;
3621 int advice;
3622 };
3623
3624 LSS_INLINE _syscall1(int, _fadvise64_64,
3625 struct kernel_fadvise64_64_args *args)
3626
3627 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
3628 loff_t len, int advice) {
3629 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
3630 return LSS_NAME(_fadvise64_64)(&args);
3631 }
3632 #endif
3633 #if defined(__NR_fallocate)
3634 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003635 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3636 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
3637 loff_t len) {
3638 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
3639 (uint64_t)(offset), (uint64_t)(len));
3640 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08003641 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
3642 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
3643 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
3644 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04003645 #define __NR__fallocate __NR_fallocate
3646 LSS_INLINE _syscall6(int, _fallocate, int, fd,
3647 int, mode,
3648 unsigned, offset_lo, unsigned, offset_hi,
3649 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003650
Bryan Chan3f6478a2016-06-14 08:38:17 -04003651 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
3652 loff_t offset, loff_t len) {
3653 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
3654 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
3655 }
3656 #else
3657 LSS_INLINE _syscall4(int, fallocate,
3658 int, f, int, mode, loff_t, offset, loff_t, len)
3659 #endif
3660 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003661 #if defined(__NR_newfstatat)
3662 LSS_INLINE _syscall4(int, newfstatat, int, d,
3663 const char *, p,
3664 struct kernel_stat*, b, int, f)
3665 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003666 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003667 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3668 gid_t *egid,
3669 gid_t *sgid) {
3670 return LSS_NAME(getresgid)(rgid, egid, sgid);
3671 }
3672
3673 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3674 uid_t *euid,
3675 uid_t *suid) {
3676 return LSS_NAME(getresuid)(ruid, euid, suid);
3677 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003678
3679 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3680 return LSS_NAME(setfsgid)(gid);
3681 }
3682
3683 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3684 return LSS_NAME(setfsuid)(uid);
3685 }
3686
3687 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3688 return LSS_NAME(setresgid)(rgid, egid, sgid);
3689 }
3690
3691 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3692 return LSS_NAME(setresuid)(ruid, euid, suid);
3693 }
3694
3695 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3696 const struct kernel_sigaction *act,
3697 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04003698 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003699 /* On x86_64, the kernel requires us to always set our own
3700 * SA_RESTORER in order to be able to return from a signal handler.
3701 * This function must have a "magic" signature that the "gdb"
3702 * (and maybe the kernel?) can recognize.
3703 */
3704 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
3705 struct kernel_sigaction a = *act;
3706 a.sa_flags |= SA_RESTORER;
3707 a.sa_restorer = LSS_NAME(restore_rt)();
3708 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
3709 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04003710 } else
3711 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003712 return LSS_NAME(rt_sigaction)(signum, act, oldact,
3713 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003714 }
3715
3716 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
3717 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
3718 }
3719
Joshua Peraza726d71e2019-11-13 12:21:13 -08003720 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
3721 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
3722 }
3723 #endif
3724 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003725 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
3726 const struct kernel_sigset_t *set,
3727 struct kernel_sigset_t *oldset) {
3728 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
3729 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08003730 #endif
3731 #if defined(__NR_rt_sigtimedwait)
3732 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
3733 siginfo_t *info,
3734 const struct timespec *timeout) {
3735 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003736 }
3737 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003738 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003739 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
3740 int*, s, int, o,
3741 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003742 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003743 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003744 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04003745 #endif
3746 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003747 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
3748 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003749 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
3750 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003751 #define __NR__getresgid32 __NR_getresgid32
3752 #define __NR__getresuid32 __NR_getresuid32
3753 #define __NR__setfsgid32 __NR_setfsgid32
3754 #define __NR__setfsuid32 __NR_setfsuid32
3755 #define __NR__setresgid32 __NR_setresgid32
3756 #define __NR__setresuid32 __NR_setresuid32
3757#if defined(__ARM_EABI__)
3758 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
3759 struct kernel_rlimit*, l)
3760#endif
3761 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
3762 gid_t *, e, gid_t *, s)
3763 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
3764 uid_t *, e, uid_t *, s)
3765 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
3766 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
3767 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
3768 gid_t, e, gid_t, s)
3769 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
3770 uid_t, e, uid_t, s)
3771
3772 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3773 gid_t *egid,
3774 gid_t *sgid) {
3775 int rc;
3776 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
3777 LSS_ERRNO == ENOSYS) {
3778 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
3779 return EFAULT;
3780 }
3781 // Clear the high bits first, since getresgid only sets 16 bits
3782 *rgid = *egid = *sgid = 0;
3783 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
3784 }
3785 return rc;
3786 }
3787
3788 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3789 uid_t *euid,
3790 uid_t *suid) {
3791 int rc;
3792 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
3793 LSS_ERRNO == ENOSYS) {
3794 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
3795 return EFAULT;
3796 }
3797 // Clear the high bits first, since getresuid only sets 16 bits
3798 *ruid = *euid = *suid = 0;
3799 rc = LSS_NAME(getresuid)(ruid, euid, suid);
3800 }
3801 return rc;
3802 }
3803
3804 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3805 int rc;
3806 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
3807 LSS_ERRNO == ENOSYS) {
3808 if ((unsigned int)gid & ~0xFFFFu) {
3809 rc = EINVAL;
3810 } else {
3811 rc = LSS_NAME(setfsgid)(gid);
3812 }
3813 }
3814 return rc;
3815 }
3816
3817 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3818 int rc;
3819 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
3820 LSS_ERRNO == ENOSYS) {
3821 if ((unsigned int)uid & ~0xFFFFu) {
3822 rc = EINVAL;
3823 } else {
3824 rc = LSS_NAME(setfsuid)(uid);
3825 }
3826 }
3827 return rc;
3828 }
3829
3830 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3831 int rc;
3832 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
3833 LSS_ERRNO == ENOSYS) {
3834 if ((unsigned int)rgid & ~0xFFFFu ||
3835 (unsigned int)egid & ~0xFFFFu ||
3836 (unsigned int)sgid & ~0xFFFFu) {
3837 rc = EINVAL;
3838 } else {
3839 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
3840 }
3841 }
3842 return rc;
3843 }
3844
3845 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3846 int rc;
3847 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
3848 LSS_ERRNO == ENOSYS) {
3849 if ((unsigned int)ruid & ~0xFFFFu ||
3850 (unsigned int)euid & ~0xFFFFu ||
3851 (unsigned int)suid & ~0xFFFFu) {
3852 rc = EINVAL;
3853 } else {
3854 rc = LSS_NAME(setresuid)(ruid, euid, suid);
3855 }
3856 }
3857 return rc;
3858 }
3859 #endif
3860 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
3861 memset(&set->sig, 0, sizeof(set->sig));
3862 return 0;
3863 }
3864
3865 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
3866 memset(&set->sig, -1, sizeof(set->sig));
3867 return 0;
3868 }
3869
3870 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
3871 int signum) {
3872 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3873 LSS_ERRNO = EINVAL;
3874 return -1;
3875 } else {
3876 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3877 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
3878 return 0;
3879 }
3880 }
3881
3882 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
3883 int signum) {
3884 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3885 LSS_ERRNO = EINVAL;
3886 return -1;
3887 } else {
3888 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3889 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
3890 return 0;
3891 }
3892 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003893
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003894 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
3895 int signum) {
3896 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3897 LSS_ERRNO = EINVAL;
3898 return -1;
3899 } else {
3900 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] &
3901 (1UL << ((signum - 1) % (8*sizeof(set->sig[0])))));
3902 }
3903 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003904 #if defined(__i386__) || \
3905 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
3906 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
3907 defined(__PPC__) || \
3908 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003909 #define __NR__sigaction __NR_sigaction
3910 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003911 #define __NR__sigsuspend __NR_sigsuspend
3912 #define __NR__socketcall __NR_socketcall
3913 LSS_INLINE _syscall2(int, fstat64, int, f,
3914 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00003915 LSS_INLINE _syscall5(int, _llseek, uint, fd,
3916 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003917 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04003918#if defined(__s390__) && !defined(__s390x__)
3919 /* On s390, mmap2() arguments are passed in memory. */
3920 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
3921 off_t o) {
3922 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
3923 (unsigned long) p, (unsigned long) f,
3924 (unsigned long) d, (unsigned long) o };
3925 LSS_REG(2, buf);
3926 LSS_BODY(void*, mmap2, "0"(__r2));
3927 }
3928#else
3929 #define __NR__mmap2 __NR_mmap2
3930 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003931 size_t, l, int, p,
3932 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04003933 off_t, o)
3934#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003935 LSS_INLINE _syscall3(int, _sigaction, int, s,
3936 const struct kernel_old_sigaction*, a,
3937 struct kernel_old_sigaction*, o)
3938 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003939 #ifdef __PPC__
3940 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
3941 #else
3942 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
3943 int, b,
3944 unsigned long, s)
3945 #endif
3946 LSS_INLINE _syscall2(int, stat64, const char *, p,
3947 struct kernel_stat64 *, b)
3948
3949 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3950 const struct kernel_sigaction *act,
3951 struct kernel_sigaction *oldact) {
3952 int old_errno = LSS_ERRNO;
3953 int rc;
3954 struct kernel_sigaction a;
3955 if (act != NULL) {
3956 a = *act;
3957 #ifdef __i386__
3958 /* On i386, the kernel requires us to always set our own
3959 * SA_RESTORER when using realtime signals. Otherwise, it does not
3960 * know how to return from a signal handler. This function must have
3961 * a "magic" signature that the "gdb" (and maybe the kernel?) can
3962 * recognize.
3963 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
3964 * using non-realtime signals.
3965 *
3966 * TODO: Test whether ARM needs a restorer
3967 */
3968 if (!(a.sa_flags & SA_RESTORER)) {
3969 a.sa_flags |= SA_RESTORER;
3970 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
3971 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
3972 }
3973 #endif
3974 }
3975 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
3976 (KERNEL_NSIG+7)/8);
3977 if (rc < 0 && LSS_ERRNO == ENOSYS) {
3978 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
3979 if (!act) {
3980 ptr_a = NULL;
3981 } else {
3982 oa.sa_handler_ = act->sa_handler_;
3983 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
3984 #ifndef __mips__
3985 oa.sa_restorer = act->sa_restorer;
3986 #endif
3987 oa.sa_flags = act->sa_flags;
3988 }
3989 if (!oldact) {
3990 ptr_oa = NULL;
3991 }
3992 LSS_ERRNO = old_errno;
3993 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
3994 if (rc == 0 && oldact) {
3995 if (act) {
3996 memcpy(oldact, act, sizeof(*act));
3997 } else {
3998 memset(oldact, 0, sizeof(*oldact));
3999 }
4000 oldact->sa_handler_ = ptr_oa->sa_handler_;
4001 oldact->sa_flags = ptr_oa->sa_flags;
4002 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4003 #ifndef __mips__
4004 oldact->sa_restorer = ptr_oa->sa_restorer;
4005 #endif
4006 }
4007 }
4008 return rc;
4009 }
4010
4011 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4012 int old_errno = LSS_ERRNO;
4013 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4014 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4015 LSS_ERRNO = old_errno;
4016 LSS_NAME(sigemptyset)(set);
4017 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4018 }
4019 return rc;
4020 }
4021
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004022 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4023 int olderrno = LSS_ERRNO;
4024 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4025 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4026 LSS_ERRNO = olderrno;
4027 rc = LSS_NAME(_sigsuspend)(
4028 #ifndef __PPC__
4029 set, 0,
4030 #endif
4031 set->sig[0]);
4032 }
4033 return rc;
4034 }
4035 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004036 #if defined(__i386__) || \
4037 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4038 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4039 defined(__PPC__) || \
4040 (defined(__s390__) && !defined(__s390x__))
4041 /* On these architectures, implement mmap() with mmap2(). */
4042 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4043 int64_t o) {
4044 if (o % 4096) {
4045 LSS_ERRNO = EINVAL;
4046 return (void *) -1;
4047 }
4048 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4049 }
4050 #elif defined(__s390x__)
4051 /* On s390x, mmap() arguments are passed in memory. */
4052 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4053 int64_t o) {
4054 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4055 (unsigned long) p, (unsigned long) f,
4056 (unsigned long) d, (unsigned long) o };
4057 LSS_REG(2, buf);
4058 LSS_BODY(void*, mmap, "0"(__r2));
4059 }
4060 #elif defined(__x86_64__)
4061 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4062 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4063 int64_t o) {
4064 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4065 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4066 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4067 }
4068 #else
4069 /* Remaining 64-bit architectures. */
4070 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4071 int, flags, int, fd, int64_t, offset)
4072 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004073 #if defined(__PPC__)
4074 #undef LSS_SC_LOADARGS_0
4075 #define LSS_SC_LOADARGS_0(dummy...)
4076 #undef LSS_SC_LOADARGS_1
4077 #define LSS_SC_LOADARGS_1(arg1) \
4078 __sc_4 = (unsigned long) (arg1)
4079 #undef LSS_SC_LOADARGS_2
4080 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4081 LSS_SC_LOADARGS_1(arg1); \
4082 __sc_5 = (unsigned long) (arg2)
4083 #undef LSS_SC_LOADARGS_3
4084 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4085 LSS_SC_LOADARGS_2(arg1, arg2); \
4086 __sc_6 = (unsigned long) (arg3)
4087 #undef LSS_SC_LOADARGS_4
4088 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4089 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4090 __sc_7 = (unsigned long) (arg4)
4091 #undef LSS_SC_LOADARGS_5
4092 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4093 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4094 __sc_8 = (unsigned long) (arg5)
4095 #undef LSS_SC_BODY
4096 #define LSS_SC_BODY(nr, type, opt, args...) \
4097 long __sc_ret, __sc_err; \
4098 { \
4099 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4100 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4101 register unsigned long __sc_4 __asm__ ("r4"); \
4102 register unsigned long __sc_5 __asm__ ("r5"); \
4103 register unsigned long __sc_6 __asm__ ("r6"); \
4104 register unsigned long __sc_7 __asm__ ("r7"); \
4105 register unsigned long __sc_8 __asm__ ("r8"); \
4106 LSS_SC_LOADARGS_##nr(args); \
4107 __asm__ __volatile__ \
4108 ("stwu 1, -48(1)\n\t" \
4109 "stw 4, 20(1)\n\t" \
4110 "stw 5, 24(1)\n\t" \
4111 "stw 6, 28(1)\n\t" \
4112 "stw 7, 32(1)\n\t" \
4113 "stw 8, 36(1)\n\t" \
4114 "addi 4, 1, 20\n\t" \
4115 "sc\n\t" \
4116 "mfcr %0" \
4117 : "=&r" (__sc_0), \
4118 "=&r" (__sc_3), "=&r" (__sc_4), \
4119 "=&r" (__sc_5), "=&r" (__sc_6), \
4120 "=&r" (__sc_7), "=&r" (__sc_8) \
4121 : LSS_ASMINPUT_##nr \
4122 : "cr0", "ctr", "memory"); \
4123 __sc_ret = __sc_3; \
4124 __sc_err = __sc_0; \
4125 } \
4126 LSS_RETURN(type, __sc_ret, __sc_err)
4127
4128 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4129 int flags){
4130 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4131 }
4132
4133 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4134 const struct kernel_msghdr *msg,
4135 int flags) {
4136 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4137 }
4138
4139 // TODO(csilvers): why is this ifdef'ed out?
4140#if 0
4141 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4142 int flags,
4143 const struct kernel_sockaddr *to,
4144 unsigned int tolen) {
4145 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4146 }
4147#endif
4148
4149 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4150 LSS_SC_BODY(2, int, 13, s, how);
4151 }
4152
4153 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4154 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4155 }
4156
4157 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4158 int sv[2]) {
4159 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4160 }
4161 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004162 #if defined(__ARM_EABI__) || defined (__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004163 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4164 int, flags)
4165 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4166 msg, int, flags)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004167 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4168 int, flags, const struct kernel_sockaddr*, to,
4169 unsigned int, tolen)
4170 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
4171 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
4172 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4173 int*, sv)
4174 #endif
4175 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004176 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4177 defined(__s390__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004178 #define __NR__socketcall __NR_socketcall
4179 LSS_INLINE _syscall2(int, _socketcall, int, c,
4180 va_list, a)
4181 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4182 int rc;
4183 va_list ap;
4184 va_start(ap, op);
4185 rc = LSS_NAME(_socketcall)(op, ap);
4186 va_end(ap);
4187 return rc;
4188 }
4189
4190 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4191 int flags){
4192 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4193 }
4194
4195 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4196 const struct kernel_msghdr *msg,
4197 int flags) {
4198 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4199 }
4200
4201 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4202 int flags,
4203 const struct kernel_sockaddr *to,
4204 unsigned int tolen) {
4205 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4206 }
4207
4208 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4209 return LSS_NAME(socketcall)(13, s, how);
4210 }
4211
4212 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4213 return LSS_NAME(socketcall)(1, domain, type, protocol);
4214 }
4215
4216 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4217 int sv[2]) {
4218 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4219 }
4220 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004221 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004222 LSS_INLINE _syscall4(int, fstatat64, int, d,
4223 const char *, p,
4224 struct kernel_stat64 *, b, int, f)
4225 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004226 #if defined(__NR_waitpid)
4227 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004228 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4229 int*, s, int, o)
4230 #endif
4231 #if defined(__mips__)
4232 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4233 * both file handles through CPU registers.
4234 */
4235 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4236 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4237 register unsigned long __v1 __asm__("$3");
4238 register unsigned long __r7 __asm__("$7");
4239 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004240 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004241 : "0"(__v0)
4242 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004243 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004244 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004245 unsigned long __errnovalue = __v0;
4246 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004247 return -1;
4248 } else {
4249 p[0] = __v0;
4250 p[1] = __v1;
4251 return 0;
4252 }
4253 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004254 #elif defined(__NR_pipe)
4255 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004256 LSS_INLINE _syscall1(int, pipe, int *, p)
4257 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004258 #if defined(__NR_pipe2)
4259 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4260 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004261 /* TODO(csilvers): see if ppc can/should support this as well */
4262 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004263 defined(__ARM_EABI__) || \
4264 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4265 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004266 #define __NR__statfs64 __NR_statfs64
4267 #define __NR__fstatfs64 __NR_fstatfs64
4268 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4269 size_t, s,struct kernel_statfs64*, b)
4270 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4271 size_t, s,struct kernel_statfs64*, b)
4272 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
4273 struct kernel_statfs64 *b) {
4274 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
4275 }
4276 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
4277 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
4278 }
4279 #endif
4280
4281 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
4282 extern char **environ;
4283 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
4284 }
4285
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004286 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004287 pid_t tid = LSS_NAME(_gettid)();
4288 if (tid != -1) {
4289 return tid;
4290 }
4291 return LSS_NAME(getpid)();
4292 }
4293
4294 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
4295 size_t new_size, int flags, ...) {
4296 va_list ap;
4297 void *new_address, *rc;
4298 va_start(ap, flags);
4299 new_address = va_arg(ap, void *);
4300 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
4301 flags, new_address);
4302 va_end(ap);
4303 return rc;
4304 }
4305
4306 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
4307 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
4308 * then sends job control signals to the real parent, rather than to
4309 * the tracer. We reduce the risk of this happening by starting a
4310 * whole new time slice, and then quickly sending a SIGCONT signal
4311 * right after detaching from the tracee.
4312 *
4313 * We use tkill to ensure that we only issue a wakeup for the thread being
4314 * detached. Large multi threaded apps can take a long time in the kernel
4315 * processing SIGCONT.
4316 */
4317 int rc, err;
4318 LSS_NAME(sched_yield)();
4319 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
4320 err = LSS_ERRNO;
4321 LSS_NAME(tkill)(pid, SIGCONT);
4322 /* Old systems don't have tkill */
4323 if (LSS_ERRNO == ENOSYS)
4324 LSS_NAME(kill)(pid, SIGCONT);
4325 LSS_ERRNO = err;
4326 return rc;
4327 }
4328
4329 LSS_INLINE int LSS_NAME(raise)(int sig) {
4330 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
4331 }
4332
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004333 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004334 return LSS_NAME(setpgid)(0, 0);
4335 }
4336
vapier@chromium.org2273e812013-04-01 17:52:44 +00004337 #if defined(__x86_64__)
4338 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4339 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
4340 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4341 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4342 }
4343
4344 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
4345 loff_t o) {
4346 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4347 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4348 }
4349
4350 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) {
4351 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4352 LSS_SYSCALL_ARG(c));
4353 }
4354 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004355 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
4356 void *, b, size_t, c,
4357 loff_t, o)
4358 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
4359 const void *, b, size_t, c,
4360 loff_t, o)
4361 LSS_INLINE _syscall3(int, readahead, int, f,
4362 loff_t, o, unsigned, c)
4363 #else
4364 #define __NR__pread64 __NR_pread64
4365 #define __NR__pwrite64 __NR_pwrite64
4366 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00004367 #if defined(__ARM_EABI__) || defined(__mips__)
4368 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
4369 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004370 * fifth and sixth make such a pair (r4,r5).
4371 */
4372 #define LSS_LLARG_PAD 0,
4373 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
4374 void *, b, size_t, c,
4375 unsigned, skip, unsigned, o1, unsigned, o2)
4376 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
4377 const void *, b, size_t, c,
4378 unsigned, skip, unsigned, o1, unsigned, o2)
4379 LSS_INLINE _syscall5(int, _readahead, int, f,
4380 unsigned, skip,
4381 unsigned, o1, unsigned, o2, size_t, c)
4382 #else
4383 #define LSS_LLARG_PAD
4384 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
4385 void *, b, size_t, c, unsigned, o1,
4386 unsigned, o2)
4387 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
4388 const void *, b, size_t, c, unsigned, o1,
4389 long, o2)
4390 LSS_INLINE _syscall4(int, _readahead, int, f,
4391 unsigned, o1, unsigned, o2, size_t, c)
4392 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004393 /* We force 64bit-wide parameters onto the stack, then access each
4394 * 32-bit component individually. This guarantees that we build the
4395 * correct parameters independent of the native byte-order of the
4396 * underlying architecture.
4397 */
4398 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
4399 loff_t off) {
4400 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004401 return LSS_NAME(_pread64)(fd, buf, count,
4402 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004403 }
4404 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
4405 size_t count, loff_t off) {
4406 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004407 return LSS_NAME(_pwrite64)(fd, buf, count,
4408 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004409 }
4410 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {
4411 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004412 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004413 }
4414 #endif
4415#endif
4416
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004417/*
4418 * Polyfills for deprecated syscalls.
4419 */
4420
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004421#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004422 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
4423 return LSS_NAME(dup3)(s, d, 0);
4424 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004425#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004426
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004427#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004428 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
4429 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
4430 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004431#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004432
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004433#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004434 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
4435 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
4436 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004437#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004438
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004439#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004440 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
4441 size_t size) {
4442 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
4443 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004444#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004445
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004446#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05004447 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004448 return LSS_NAME(pipe2)(pipefd, 0);
4449 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004450#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004451
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004452#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004453 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
4454 int timeout) {
4455 struct kernel_timespec timeout_ts;
4456 struct kernel_timespec *timeout_ts_p = NULL;
4457
4458 if (timeout >= 0) {
4459 timeout_ts.tv_sec = timeout / 1000;
4460 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
4461 timeout_ts_p = &timeout_ts;
4462 }
4463 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
4464 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004465#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004466
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004467#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004468 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
4469 struct kernel_stat *buf) {
4470 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 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_waitpid)
4475 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
4476 return LSS_NAME(wait4)(pid, status, options, 0);
4477 }
4478#endif
4479
4480#if !defined(__NR_fork)
4481// TODO: define this in an arch-independant way instead of inlining the clone
4482// syscall body.
4483
4484# if defined(__aarch64__)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004485 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4486 // No fork syscall on aarch64 - implement by means of the clone syscall.
4487 // Note that this does not reset glibc's cached view of the PID/TID, so
4488 // some glibc interfaces might go wrong in the forked subprocess.
4489 int flags = SIGCHLD;
4490 void *child_stack = NULL;
4491 void *parent_tidptr = NULL;
4492 void *newtls = NULL;
4493 void *child_tidptr = NULL;
4494
4495 LSS_REG(0, flags);
4496 LSS_REG(1, child_stack);
4497 LSS_REG(2, parent_tidptr);
4498 LSS_REG(3, newtls);
4499 LSS_REG(4, child_tidptr);
4500 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
4501 "r"(__r4));
4502 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004503# elif defined(__x86_64__)
4504 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4505 // Android disallows the fork syscall on x86_64 - implement by means of the
4506 // clone syscall as above for aarch64.
4507 int flags = SIGCHLD;
4508 void *child_stack = NULL;
4509 void *parent_tidptr = NULL;
4510 void *newtls = NULL;
4511 void *child_tidptr = NULL;
4512
4513 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
4514 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
4515 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
4516 }
4517# else
4518# error missing fork polyfill for this architecture
4519# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004520#endif
4521
Michael Forneyf70e2f12020-01-22 19:19:38 -08004522/* These restore the original values of these macros saved by the
4523 * corresponding #pragma push_macro near the top of this file. */
4524#pragma pop_macro("stat64")
4525#pragma pop_macro("fstat64")
4526#pragma pop_macro("lstat64")
4527#pragma pop_macro("pread64")
4528#pragma pop_macro("pwrite64")
Michael Forneyfd00dbb2020-03-10 14:12:52 -07004529#pragma pop_macro("getdents64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00004530
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004531#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
4532}
4533#endif
4534
4535#endif
4536#endif