blob: d2baee9d2430bfe55b0573f9c8e3446b2fc26ea6 [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")
145#undef stat64
146#undef fstat64
147#undef lstat64
148#undef pread64
149#undef pwrite64
mseaborn@chromium.orgca749372012-09-05 18:26:20 +0000150
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400151#if defined(__ANDROID__) && defined(__x86_64__)
152// A number of x86_64 syscalls are blocked by seccomp on recent Android;
153// undefine them so that modern alternatives will be used instead where
154// possible.
155// The alternative syscalls have been sanity checked against linux-3.4+;
156// older versions might not work.
157# undef __NR_getdents
158# undef __NR_dup2
159# undef __NR_fork
160# undef __NR_getpgrp
161# undef __NR_open
162# undef __NR_poll
163# undef __NR_readlink
164# undef __NR_stat
165# undef __NR_unlink
166# undef __NR_pipe
167#endif
168
169#if defined(__ANDROID__)
170// waitpid is blocked by seccomp on all architectures on recent Android.
171# undef __NR_waitpid
172#endif
173
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000174/* As glibc often provides subtly incompatible data structures (and implicit
175 * wrapper functions that convert them), we provide our own kernel data
176 * structures for use by the system calls.
177 * These structures have been developed by using Linux 2.6.23 headers for
178 * reference. Note though, we do not care about exact API compatibility
179 * with the kernel, and in fact the kernel often does not have a single
180 * API that works across architectures. Instead, we try to mimic the glibc
181 * API where reasonable, and only guarantee ABI compatibility with the
182 * kernel headers.
183 * Most notably, here are a few changes that were made to the structures
184 * defined by kernel headers:
185 *
186 * - we only define structures, but not symbolic names for kernel data
187 * types. For the latter, we directly use the native C datatype
188 * (i.e. "unsigned" instead of "mode_t").
189 * - in a few cases, it is possible to define identical structures for
190 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
191 * standardizing on the 64bit version of the data types. In particular,
192 * this means that we use "unsigned" where the 32bit headers say
193 * "unsigned long".
194 * - overall, we try to minimize the number of cases where we need to
195 * conditionally define different structures.
196 * - the "struct kernel_sigaction" class of structures have been
197 * modified to more closely mimic glibc's API by introducing an
198 * anonymous union for the function pointer.
199 * - a small number of field names had to have an underscore appended to
200 * them, because glibc defines a global macro by the same name.
201 */
202
203/* include/linux/dirent.h */
204struct kernel_dirent64 {
205 unsigned long long d_ino;
206 long long d_off;
207 unsigned short d_reclen;
208 unsigned char d_type;
209 char d_name[256];
210};
211
212/* include/linux/dirent.h */
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -0400213#if !defined(__NR_getdents)
214// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000215#define kernel_dirent kernel_dirent64
216#else
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000217struct kernel_dirent {
218 long d_ino;
219 long d_off;
220 unsigned short d_reclen;
221 char d_name[256];
222};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000223#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000224
225/* include/linux/uio.h */
226struct kernel_iovec {
227 void *iov_base;
228 unsigned long iov_len;
229};
230
231/* include/linux/socket.h */
232struct kernel_msghdr {
233 void *msg_name;
234 int msg_namelen;
235 struct kernel_iovec*msg_iov;
236 unsigned long msg_iovlen;
237 void *msg_control;
238 unsigned long msg_controllen;
239 unsigned msg_flags;
240};
241
242/* include/asm-generic/poll.h */
243struct kernel_pollfd {
244 int fd;
245 short events;
246 short revents;
247};
248
249/* include/linux/resource.h */
250struct kernel_rlimit {
251 unsigned long rlim_cur;
252 unsigned long rlim_max;
253};
254
255/* include/linux/time.h */
256struct kernel_timespec {
257 long tv_sec;
258 long tv_nsec;
259};
260
261/* include/linux/time.h */
262struct kernel_timeval {
263 long tv_sec;
264 long tv_usec;
265};
266
267/* include/linux/resource.h */
268struct kernel_rusage {
269 struct kernel_timeval ru_utime;
270 struct kernel_timeval ru_stime;
271 long ru_maxrss;
272 long ru_ixrss;
273 long ru_idrss;
274 long ru_isrss;
275 long ru_minflt;
276 long ru_majflt;
277 long ru_nswap;
278 long ru_inblock;
279 long ru_oublock;
280 long ru_msgsnd;
281 long ru_msgrcv;
282 long ru_nsignals;
283 long ru_nvcsw;
284 long ru_nivcsw;
285};
286
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000287#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
Bryan Chan3f6478a2016-06-14 08:38:17 -0400288 || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000289
290/* include/asm-{arm,i386,mips,ppc}/signal.h */
291struct kernel_old_sigaction {
292 union {
293 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000294 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000295 };
296 unsigned long sa_mask;
297 unsigned long sa_flags;
298 void (*sa_restorer)(void);
299} __attribute__((packed,aligned(4)));
300#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
301 #define kernel_old_sigaction kernel_sigaction
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000302#elif defined(__aarch64__)
303 // No kernel_old_sigaction defined for arm64.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000304#endif
305
306/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
307 * exactly match the size of the signal set, even though the API was
308 * intended to be extensible. We define our own KERNEL_NSIG to deal with
309 * this.
310 * Please note that glibc provides signals [1.._NSIG-1], whereas the
311 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
312 * actual number of signals is obviously the same, but the constants
313 * differ by one.
314 */
315#ifdef __mips__
316#define KERNEL_NSIG 128
317#else
318#define KERNEL_NSIG 64
319#endif
320
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000321/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000322struct kernel_sigset_t {
323 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
324 (8*sizeof(unsigned long))];
325};
326
327/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
328struct kernel_sigaction {
329#ifdef __mips__
330 unsigned long sa_flags;
331 union {
332 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000333 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000334 };
335 struct kernel_sigset_t sa_mask;
336#else
337 union {
338 void (*sa_handler_)(int);
vapier@chromium.orgcdda4342013-03-06 04:26:28 +0000339 void (*sa_sigaction_)(int, siginfo_t *, void *);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000340 };
341 unsigned long sa_flags;
342 void (*sa_restorer)(void);
343 struct kernel_sigset_t sa_mask;
344#endif
345};
346
347/* include/linux/socket.h */
348struct kernel_sockaddr {
349 unsigned short sa_family;
350 char sa_data[14];
351};
352
Bryan Chan3f6478a2016-06-14 08:38:17 -0400353/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000354#ifdef __mips__
355#if _MIPS_SIM == _MIPS_SIM_ABI64
356struct kernel_stat {
357#else
358struct kernel_stat64 {
359#endif
360 unsigned st_dev;
361 unsigned __pad0[3];
362 unsigned long long st_ino;
363 unsigned st_mode;
364 unsigned st_nlink;
365 unsigned st_uid;
366 unsigned st_gid;
367 unsigned st_rdev;
368 unsigned __pad1[3];
369 long long st_size;
370 unsigned st_atime_;
371 unsigned st_atime_nsec_;
372 unsigned st_mtime_;
373 unsigned st_mtime_nsec_;
374 unsigned st_ctime_;
375 unsigned st_ctime_nsec_;
376 unsigned st_blksize;
377 unsigned __pad2;
378 unsigned long long st_blocks;
379};
380#elif defined __PPC__
381struct kernel_stat64 {
382 unsigned long long st_dev;
383 unsigned long long st_ino;
384 unsigned st_mode;
385 unsigned st_nlink;
386 unsigned st_uid;
387 unsigned st_gid;
388 unsigned long long st_rdev;
389 unsigned short int __pad2;
390 long long st_size;
391 long st_blksize;
392 long long st_blocks;
393 long st_atime_;
394 unsigned long st_atime_nsec_;
395 long st_mtime_;
396 unsigned long st_mtime_nsec_;
397 long st_ctime_;
398 unsigned long st_ctime_nsec_;
399 unsigned long __unused4;
400 unsigned long __unused5;
401};
402#else
403struct kernel_stat64 {
404 unsigned long long st_dev;
405 unsigned char __pad0[4];
406 unsigned __st_ino;
407 unsigned st_mode;
408 unsigned st_nlink;
409 unsigned st_uid;
410 unsigned st_gid;
411 unsigned long long st_rdev;
412 unsigned char __pad3[4];
413 long long st_size;
414 unsigned st_blksize;
415 unsigned long long st_blocks;
416 unsigned st_atime_;
417 unsigned st_atime_nsec_;
418 unsigned st_mtime_;
419 unsigned st_mtime_nsec_;
420 unsigned st_ctime_;
421 unsigned st_ctime_nsec_;
422 unsigned long long st_ino;
423};
424#endif
425
Bryan Chan3f6478a2016-06-14 08:38:17 -0400426/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000427#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
428struct kernel_stat {
429 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
430 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
431 * format. In reality, we do not see useful data in the top bits. So,
432 * we'll leave the padding in here, until we find a better solution.
433 */
434 unsigned short st_dev;
435 short pad1;
436 unsigned st_ino;
437 unsigned short st_mode;
438 unsigned short st_nlink;
439 unsigned short st_uid;
440 unsigned short st_gid;
441 unsigned short st_rdev;
442 short pad2;
443 unsigned st_size;
444 unsigned st_blksize;
445 unsigned st_blocks;
446 unsigned st_atime_;
447 unsigned st_atime_nsec_;
448 unsigned st_mtime_;
449 unsigned st_mtime_nsec_;
450 unsigned st_ctime_;
451 unsigned st_ctime_nsec_;
452 unsigned __unused4;
453 unsigned __unused5;
454};
455#elif defined(__x86_64__)
456struct kernel_stat {
vapier@chromium.org2273e812013-04-01 17:52:44 +0000457 uint64_t st_dev;
458 uint64_t st_ino;
459 uint64_t st_nlink;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000460 unsigned st_mode;
461 unsigned st_uid;
462 unsigned st_gid;
463 unsigned __pad0;
vapier@chromium.org2273e812013-04-01 17:52:44 +0000464 uint64_t st_rdev;
465 int64_t st_size;
466 int64_t st_blksize;
467 int64_t st_blocks;
468 uint64_t st_atime_;
469 uint64_t st_atime_nsec_;
470 uint64_t st_mtime_;
471 uint64_t st_mtime_nsec_;
472 uint64_t st_ctime_;
473 uint64_t st_ctime_nsec_;
anton@chromium.org43de0522014-04-04 11:20:46 +0000474 int64_t __unused4[3];
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000475};
476#elif defined(__PPC__)
477struct kernel_stat {
478 unsigned st_dev;
479 unsigned long st_ino; // ino_t
480 unsigned long st_mode; // mode_t
481 unsigned short st_nlink; // nlink_t
482 unsigned st_uid; // uid_t
483 unsigned st_gid; // gid_t
484 unsigned st_rdev;
485 long st_size; // off_t
486 unsigned long st_blksize;
487 unsigned long st_blocks;
488 unsigned long st_atime_;
489 unsigned long st_atime_nsec_;
490 unsigned long st_mtime_;
491 unsigned long st_mtime_nsec_;
492 unsigned long st_ctime_;
493 unsigned long st_ctime_nsec_;
494 unsigned long __unused4;
495 unsigned long __unused5;
496};
497#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
498struct kernel_stat {
499 unsigned st_dev;
500 int st_pad1[3];
501 unsigned st_ino;
502 unsigned st_mode;
503 unsigned st_nlink;
504 unsigned st_uid;
505 unsigned st_gid;
506 unsigned st_rdev;
507 int st_pad2[2];
508 long st_size;
509 int st_pad3;
510 long st_atime_;
511 long st_atime_nsec_;
512 long st_mtime_;
513 long st_mtime_nsec_;
514 long st_ctime_;
515 long st_ctime_nsec_;
516 int st_blksize;
517 int st_blocks;
518 int st_pad4[14];
519};
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000520#elif defined(__aarch64__)
521struct kernel_stat {
522 unsigned long st_dev;
523 unsigned long st_ino;
524 unsigned int st_mode;
525 unsigned int st_nlink;
526 unsigned int st_uid;
527 unsigned int st_gid;
528 unsigned long st_rdev;
529 unsigned long __pad1;
530 long st_size;
531 int st_blksize;
532 int __pad2;
533 long st_blocks;
534 long st_atime_;
535 unsigned long st_atime_nsec_;
536 long st_mtime_;
537 unsigned long st_mtime_nsec_;
538 long st_ctime_;
539 unsigned long st_ctime_nsec_;
540 unsigned int __unused4;
541 unsigned int __unused5;
542};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400543#elif defined(__s390x__)
544struct kernel_stat {
545 unsigned long st_dev;
546 unsigned long st_ino;
547 unsigned long st_nlink;
548 unsigned int st_mode;
549 unsigned int st_uid;
550 unsigned int st_gid;
551 unsigned int __pad1;
552 unsigned long st_rdev;
553 unsigned long st_size;
554 unsigned long st_atime_;
555 unsigned long st_atime_nsec_;
556 unsigned long st_mtime_;
557 unsigned long st_mtime_nsec_;
558 unsigned long st_ctime_;
559 unsigned long st_ctime_nsec_;
560 unsigned long st_blksize;
561 long st_blocks;
562 unsigned long __unused[3];
563};
564#elif defined(__s390__)
565struct kernel_stat {
566 unsigned short st_dev;
567 unsigned short __pad1;
568 unsigned long st_ino;
569 unsigned short st_mode;
570 unsigned short st_nlink;
571 unsigned short st_uid;
572 unsigned short st_gid;
573 unsigned short st_rdev;
574 unsigned short __pad2;
575 unsigned long st_size;
576 unsigned long st_blksize;
577 unsigned long st_blocks;
578 unsigned long st_atime_;
579 unsigned long st_atime_nsec_;
580 unsigned long st_mtime_;
581 unsigned long st_mtime_nsec_;
582 unsigned long st_ctime_;
583 unsigned long st_ctime_nsec_;
584 unsigned long __unused4;
585 unsigned long __unused5;
586};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000587#endif
588
Bryan Chan3f6478a2016-06-14 08:38:17 -0400589/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000590#ifdef __mips__
591#if _MIPS_SIM != _MIPS_SIM_ABI64
592struct kernel_statfs64 {
593 unsigned long f_type;
594 unsigned long f_bsize;
595 unsigned long f_frsize;
596 unsigned long __pad;
597 unsigned long long f_blocks;
598 unsigned long long f_bfree;
599 unsigned long long f_files;
600 unsigned long long f_ffree;
601 unsigned long long f_bavail;
602 struct { int val[2]; } f_fsid;
603 unsigned long f_namelen;
604 unsigned long f_spare[6];
605};
606#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -0400607#elif defined(__s390__)
608/* See also arch/s390/include/asm/compat.h */
609struct kernel_statfs64 {
610 unsigned int f_type;
611 unsigned int f_bsize;
612 unsigned long long f_blocks;
613 unsigned long long f_bfree;
614 unsigned long long f_bavail;
615 unsigned long long f_files;
616 unsigned long long f_ffree;
617 struct { int val[2]; } f_fsid;
618 unsigned int f_namelen;
619 unsigned int f_frsize;
620 unsigned int f_flags;
621 unsigned int f_spare[4];
622};
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000623#elif !defined(__x86_64__)
624struct kernel_statfs64 {
625 unsigned long f_type;
626 unsigned long f_bsize;
627 unsigned long long f_blocks;
628 unsigned long long f_bfree;
629 unsigned long long f_bavail;
630 unsigned long long f_files;
631 unsigned long long f_ffree;
632 struct { int val[2]; } f_fsid;
633 unsigned long f_namelen;
634 unsigned long f_frsize;
635 unsigned long f_spare[5];
636};
637#endif
638
Bryan Chan3f6478a2016-06-14 08:38:17 -0400639/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000640#ifdef __mips__
641struct kernel_statfs {
642 long f_type;
643 long f_bsize;
644 long f_frsize;
645 long f_blocks;
646 long f_bfree;
647 long f_files;
648 long f_ffree;
649 long f_bavail;
650 struct { int val[2]; } f_fsid;
651 long f_namelen;
652 long f_spare[6];
653};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000654#elif defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000655struct kernel_statfs {
656 /* x86_64 actually defines all these fields as signed, whereas all other */
657 /* platforms define them as unsigned. Leaving them at unsigned should not */
vapier@chromium.org2273e812013-04-01 17:52:44 +0000658 /* cause any problems. Make sure these are 64-bit even on x32. */
659 uint64_t f_type;
660 uint64_t f_bsize;
661 uint64_t f_blocks;
662 uint64_t f_bfree;
663 uint64_t f_bavail;
664 uint64_t f_files;
665 uint64_t f_ffree;
666 struct { int val[2]; } f_fsid;
667 uint64_t f_namelen;
668 uint64_t f_frsize;
669 uint64_t f_spare[5];
670};
Bryan Chan3f6478a2016-06-14 08:38:17 -0400671#elif defined(__s390__)
672struct kernel_statfs {
673 unsigned int f_type;
674 unsigned int f_bsize;
675 unsigned long f_blocks;
676 unsigned long f_bfree;
677 unsigned long f_bavail;
678 unsigned long f_files;
679 unsigned long f_ffree;
680 struct { int val[2]; } f_fsid;
681 unsigned int f_namelen;
682 unsigned int f_frsize;
683 unsigned int f_flags;
684 unsigned int f_spare[4];
685};
vapier@chromium.org2273e812013-04-01 17:52:44 +0000686#else
687struct kernel_statfs {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000688 unsigned long f_type;
689 unsigned long f_bsize;
690 unsigned long f_blocks;
691 unsigned long f_bfree;
692 unsigned long f_bavail;
693 unsigned long f_files;
694 unsigned long f_ffree;
695 struct { int val[2]; } f_fsid;
696 unsigned long f_namelen;
697 unsigned long f_frsize;
698 unsigned long f_spare[5];
699};
700#endif
701
702
703/* Definitions missing from the standard header files */
704#ifndef O_DIRECTORY
anton@chromium.org2f724fc2014-04-15 13:05:20 +0000705#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000706#define O_DIRECTORY 0040000
707#else
708#define O_DIRECTORY 0200000
709#endif
710#endif
711#ifndef NT_PRXFPREG
712#define NT_PRXFPREG 0x46e62b7f
713#endif
714#ifndef PTRACE_GETFPXREGS
715#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
716#endif
717#ifndef PR_GET_DUMPABLE
718#define PR_GET_DUMPABLE 3
719#endif
720#ifndef PR_SET_DUMPABLE
721#define PR_SET_DUMPABLE 4
722#endif
723#ifndef PR_GET_SECCOMP
724#define PR_GET_SECCOMP 21
725#endif
726#ifndef PR_SET_SECCOMP
727#define PR_SET_SECCOMP 22
728#endif
729#ifndef AT_FDCWD
730#define AT_FDCWD (-100)
731#endif
732#ifndef AT_SYMLINK_NOFOLLOW
733#define AT_SYMLINK_NOFOLLOW 0x100
734#endif
735#ifndef AT_REMOVEDIR
736#define AT_REMOVEDIR 0x200
737#endif
738#ifndef MREMAP_FIXED
739#define MREMAP_FIXED 2
740#endif
741#ifndef SA_RESTORER
742#define SA_RESTORER 0x04000000
743#endif
744#ifndef CPUCLOCK_PROF
745#define CPUCLOCK_PROF 0
746#endif
747#ifndef CPUCLOCK_VIRT
748#define CPUCLOCK_VIRT 1
749#endif
750#ifndef CPUCLOCK_SCHED
751#define CPUCLOCK_SCHED 2
752#endif
753#ifndef CPUCLOCK_PERTHREAD_MASK
754#define CPUCLOCK_PERTHREAD_MASK 4
755#endif
756#ifndef MAKE_PROCESS_CPUCLOCK
757#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400758 ((int)(~(unsigned)(pid) << 3) | (int)(clock))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000759#endif
760#ifndef MAKE_THREAD_CPUCLOCK
761#define MAKE_THREAD_CPUCLOCK(tid, clock) \
Nico Webera2b70922017-03-30 11:03:37 -0400762 ((int)(~(unsigned)(tid) << 3) | \
763 (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +0000764#endif
765
766#ifndef FUTEX_WAIT
767#define FUTEX_WAIT 0
768#endif
769#ifndef FUTEX_WAKE
770#define FUTEX_WAKE 1
771#endif
772#ifndef FUTEX_FD
773#define FUTEX_FD 2
774#endif
775#ifndef FUTEX_REQUEUE
776#define FUTEX_REQUEUE 3
777#endif
778#ifndef FUTEX_CMP_REQUEUE
779#define FUTEX_CMP_REQUEUE 4
780#endif
781#ifndef FUTEX_WAKE_OP
782#define FUTEX_WAKE_OP 5
783#endif
784#ifndef FUTEX_LOCK_PI
785#define FUTEX_LOCK_PI 6
786#endif
787#ifndef FUTEX_UNLOCK_PI
788#define FUTEX_UNLOCK_PI 7
789#endif
790#ifndef FUTEX_TRYLOCK_PI
791#define FUTEX_TRYLOCK_PI 8
792#endif
793#ifndef FUTEX_PRIVATE_FLAG
794#define FUTEX_PRIVATE_FLAG 128
795#endif
796#ifndef FUTEX_CMD_MASK
797#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
798#endif
799#ifndef FUTEX_WAIT_PRIVATE
800#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
801#endif
802#ifndef FUTEX_WAKE_PRIVATE
803#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
804#endif
805#ifndef FUTEX_REQUEUE_PRIVATE
806#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
807#endif
808#ifndef FUTEX_CMP_REQUEUE_PRIVATE
809#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
810#endif
811#ifndef FUTEX_WAKE_OP_PRIVATE
812#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
813#endif
814#ifndef FUTEX_LOCK_PI_PRIVATE
815#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
816#endif
817#ifndef FUTEX_UNLOCK_PI_PRIVATE
818#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
819#endif
820#ifndef FUTEX_TRYLOCK_PI_PRIVATE
821#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
822#endif
823
824
825#if defined(__x86_64__)
826#ifndef ARCH_SET_GS
827#define ARCH_SET_GS 0x1001
828#endif
829#ifndef ARCH_GET_GS
830#define ARCH_GET_GS 0x1004
831#endif
832#endif
833
834#if defined(__i386__)
835#ifndef __NR_quotactl
836#define __NR_quotactl 131
837#endif
838#ifndef __NR_setresuid
839#define __NR_setresuid 164
840#define __NR_getresuid 165
841#define __NR_setresgid 170
842#define __NR_getresgid 171
843#endif
844#ifndef __NR_rt_sigaction
845#define __NR_rt_sigreturn 173
846#define __NR_rt_sigaction 174
847#define __NR_rt_sigprocmask 175
848#define __NR_rt_sigpending 176
849#define __NR_rt_sigsuspend 179
850#endif
851#ifndef __NR_pread64
852#define __NR_pread64 180
853#endif
854#ifndef __NR_pwrite64
855#define __NR_pwrite64 181
856#endif
857#ifndef __NR_ugetrlimit
858#define __NR_ugetrlimit 191
859#endif
860#ifndef __NR_stat64
861#define __NR_stat64 195
862#endif
863#ifndef __NR_fstat64
864#define __NR_fstat64 197
865#endif
866#ifndef __NR_setresuid32
867#define __NR_setresuid32 208
868#define __NR_getresuid32 209
869#define __NR_setresgid32 210
870#define __NR_getresgid32 211
871#endif
872#ifndef __NR_setfsuid32
873#define __NR_setfsuid32 215
874#define __NR_setfsgid32 216
875#endif
876#ifndef __NR_getdents64
877#define __NR_getdents64 220
878#endif
879#ifndef __NR_gettid
880#define __NR_gettid 224
881#endif
882#ifndef __NR_readahead
883#define __NR_readahead 225
884#endif
885#ifndef __NR_setxattr
886#define __NR_setxattr 226
887#endif
888#ifndef __NR_lsetxattr
889#define __NR_lsetxattr 227
890#endif
891#ifndef __NR_getxattr
892#define __NR_getxattr 229
893#endif
894#ifndef __NR_lgetxattr
895#define __NR_lgetxattr 230
896#endif
897#ifndef __NR_listxattr
898#define __NR_listxattr 232
899#endif
900#ifndef __NR_llistxattr
901#define __NR_llistxattr 233
902#endif
903#ifndef __NR_tkill
904#define __NR_tkill 238
905#endif
906#ifndef __NR_futex
907#define __NR_futex 240
908#endif
909#ifndef __NR_sched_setaffinity
910#define __NR_sched_setaffinity 241
911#define __NR_sched_getaffinity 242
912#endif
913#ifndef __NR_set_tid_address
914#define __NR_set_tid_address 258
915#endif
916#ifndef __NR_clock_gettime
917#define __NR_clock_gettime 265
918#endif
919#ifndef __NR_clock_getres
920#define __NR_clock_getres 266
921#endif
922#ifndef __NR_statfs64
923#define __NR_statfs64 268
924#endif
925#ifndef __NR_fstatfs64
926#define __NR_fstatfs64 269
927#endif
928#ifndef __NR_fadvise64_64
929#define __NR_fadvise64_64 272
930#endif
931#ifndef __NR_ioprio_set
932#define __NR_ioprio_set 289
933#endif
934#ifndef __NR_ioprio_get
935#define __NR_ioprio_get 290
936#endif
937#ifndef __NR_openat
938#define __NR_openat 295
939#endif
940#ifndef __NR_fstatat64
941#define __NR_fstatat64 300
942#endif
943#ifndef __NR_unlinkat
944#define __NR_unlinkat 301
945#endif
946#ifndef __NR_move_pages
947#define __NR_move_pages 317
948#endif
949#ifndef __NR_getcpu
950#define __NR_getcpu 318
951#endif
952#ifndef __NR_fallocate
953#define __NR_fallocate 324
954#endif
955/* End of i386 definitions */
956#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
957#ifndef __NR_setresuid
958#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
959#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
960#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
961#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
962#endif
963#ifndef __NR_rt_sigaction
964#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
965#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
966#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
967#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
968#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
969#endif
970#ifndef __NR_pread64
971#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
972#endif
973#ifndef __NR_pwrite64
974#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
975#endif
976#ifndef __NR_ugetrlimit
977#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
978#endif
979#ifndef __NR_stat64
980#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
981#endif
982#ifndef __NR_fstat64
983#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
984#endif
985#ifndef __NR_setresuid32
986#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
987#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
988#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
989#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
990#endif
991#ifndef __NR_setfsuid32
992#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
993#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
994#endif
995#ifndef __NR_getdents64
996#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
997#endif
998#ifndef __NR_gettid
999#define __NR_gettid (__NR_SYSCALL_BASE + 224)
1000#endif
1001#ifndef __NR_readahead
1002#define __NR_readahead (__NR_SYSCALL_BASE + 225)
1003#endif
1004#ifndef __NR_setxattr
1005#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
1006#endif
1007#ifndef __NR_lsetxattr
1008#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
1009#endif
1010#ifndef __NR_getxattr
1011#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
1012#endif
1013#ifndef __NR_lgetxattr
1014#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
1015#endif
1016#ifndef __NR_listxattr
1017#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
1018#endif
1019#ifndef __NR_llistxattr
1020#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
1021#endif
1022#ifndef __NR_tkill
1023#define __NR_tkill (__NR_SYSCALL_BASE + 238)
1024#endif
1025#ifndef __NR_futex
1026#define __NR_futex (__NR_SYSCALL_BASE + 240)
1027#endif
1028#ifndef __NR_sched_setaffinity
1029#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
1030#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
1031#endif
1032#ifndef __NR_set_tid_address
1033#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
1034#endif
1035#ifndef __NR_clock_gettime
1036#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
1037#endif
1038#ifndef __NR_clock_getres
1039#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
1040#endif
1041#ifndef __NR_statfs64
1042#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
1043#endif
1044#ifndef __NR_fstatfs64
1045#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
1046#endif
1047#ifndef __NR_ioprio_set
1048#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
1049#endif
1050#ifndef __NR_ioprio_get
1051#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
1052#endif
1053#ifndef __NR_move_pages
1054#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
1055#endif
1056#ifndef __NR_getcpu
1057#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
1058#endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04001059/* End of ARM 3/EABI definitions */
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001060#elif defined(__aarch64__)
1061#ifndef __NR_setxattr
1062#define __NR_setxattr 5
1063#endif
1064#ifndef __NR_lsetxattr
1065#define __NR_lsetxattr 6
1066#endif
1067#ifndef __NR_getxattr
1068#define __NR_getxattr 8
1069#endif
1070#ifndef __NR_lgetxattr
1071#define __NR_lgetxattr 9
1072#endif
1073#ifndef __NR_listxattr
1074#define __NR_listxattr 11
1075#endif
1076#ifndef __NR_llistxattr
1077#define __NR_llistxattr 12
1078#endif
1079#ifndef __NR_ioprio_set
1080#define __NR_ioprio_set 30
1081#endif
1082#ifndef __NR_ioprio_get
1083#define __NR_ioprio_get 31
1084#endif
1085#ifndef __NR_unlinkat
1086#define __NR_unlinkat 35
1087#endif
1088#ifndef __NR_fallocate
1089#define __NR_fallocate 47
1090#endif
1091#ifndef __NR_openat
1092#define __NR_openat 56
1093#endif
1094#ifndef __NR_quotactl
1095#define __NR_quotactl 60
1096#endif
1097#ifndef __NR_getdents64
1098#define __NR_getdents64 61
1099#endif
1100#ifndef __NR_getdents
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001101// when getdents is not available, getdents64 is used for both.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00001102#define __NR_getdents __NR_getdents64
1103#endif
1104#ifndef __NR_pread64
1105#define __NR_pread64 67
1106#endif
1107#ifndef __NR_pwrite64
1108#define __NR_pwrite64 68
1109#endif
1110#ifndef __NR_ppoll
1111#define __NR_ppoll 73
1112#endif
1113#ifndef __NR_readlinkat
1114#define __NR_readlinkat 78
1115#endif
1116#ifndef __NR_newfstatat
1117#define __NR_newfstatat 79
1118#endif
1119#ifndef __NR_set_tid_address
1120#define __NR_set_tid_address 96
1121#endif
1122#ifndef __NR_futex
1123#define __NR_futex 98
1124#endif
1125#ifndef __NR_clock_gettime
1126#define __NR_clock_gettime 113
1127#endif
1128#ifndef __NR_clock_getres
1129#define __NR_clock_getres 114
1130#endif
1131#ifndef __NR_sched_setaffinity
1132#define __NR_sched_setaffinity 122
1133#define __NR_sched_getaffinity 123
1134#endif
1135#ifndef __NR_tkill
1136#define __NR_tkill 130
1137#endif
1138#ifndef __NR_setresuid
1139#define __NR_setresuid 147
1140#define __NR_getresuid 148
1141#define __NR_setresgid 149
1142#define __NR_getresgid 150
1143#endif
1144#ifndef __NR_gettid
1145#define __NR_gettid 178
1146#endif
1147#ifndef __NR_readahead
1148#define __NR_readahead 213
1149#endif
1150#ifndef __NR_fadvise64
1151#define __NR_fadvise64 223
1152#endif
1153#ifndef __NR_move_pages
1154#define __NR_move_pages 239
1155#endif
1156/* End of aarch64 definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001157#elif defined(__x86_64__)
1158#ifndef __NR_pread64
1159#define __NR_pread64 17
1160#endif
1161#ifndef __NR_pwrite64
1162#define __NR_pwrite64 18
1163#endif
1164#ifndef __NR_setresuid
1165#define __NR_setresuid 117
1166#define __NR_getresuid 118
1167#define __NR_setresgid 119
1168#define __NR_getresgid 120
1169#endif
1170#ifndef __NR_quotactl
1171#define __NR_quotactl 179
1172#endif
1173#ifndef __NR_gettid
1174#define __NR_gettid 186
1175#endif
1176#ifndef __NR_readahead
1177#define __NR_readahead 187
1178#endif
1179#ifndef __NR_setxattr
1180#define __NR_setxattr 188
1181#endif
1182#ifndef __NR_lsetxattr
1183#define __NR_lsetxattr 189
1184#endif
1185#ifndef __NR_getxattr
1186#define __NR_getxattr 191
1187#endif
1188#ifndef __NR_lgetxattr
1189#define __NR_lgetxattr 192
1190#endif
1191#ifndef __NR_listxattr
1192#define __NR_listxattr 194
1193#endif
1194#ifndef __NR_llistxattr
1195#define __NR_llistxattr 195
1196#endif
1197#ifndef __NR_tkill
1198#define __NR_tkill 200
1199#endif
1200#ifndef __NR_futex
1201#define __NR_futex 202
1202#endif
1203#ifndef __NR_sched_setaffinity
1204#define __NR_sched_setaffinity 203
1205#define __NR_sched_getaffinity 204
1206#endif
1207#ifndef __NR_getdents64
1208#define __NR_getdents64 217
1209#endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04001210#ifndef __NR_getdents
1211// when getdents is not available, getdents64 is used for both.
1212#define __NR_getdents __NR_getdents64
1213#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001214#ifndef __NR_set_tid_address
1215#define __NR_set_tid_address 218
1216#endif
1217#ifndef __NR_fadvise64
1218#define __NR_fadvise64 221
1219#endif
1220#ifndef __NR_clock_gettime
1221#define __NR_clock_gettime 228
1222#endif
1223#ifndef __NR_clock_getres
1224#define __NR_clock_getres 229
1225#endif
1226#ifndef __NR_ioprio_set
1227#define __NR_ioprio_set 251
1228#endif
1229#ifndef __NR_ioprio_get
1230#define __NR_ioprio_get 252
1231#endif
1232#ifndef __NR_openat
1233#define __NR_openat 257
1234#endif
1235#ifndef __NR_newfstatat
1236#define __NR_newfstatat 262
1237#endif
1238#ifndef __NR_unlinkat
1239#define __NR_unlinkat 263
1240#endif
1241#ifndef __NR_move_pages
1242#define __NR_move_pages 279
1243#endif
1244#ifndef __NR_fallocate
1245#define __NR_fallocate 285
1246#endif
1247/* End of x86-64 definitions */
1248#elif defined(__mips__)
1249#if _MIPS_SIM == _MIPS_SIM_ABI32
1250#ifndef __NR_setresuid
1251#define __NR_setresuid (__NR_Linux + 185)
1252#define __NR_getresuid (__NR_Linux + 186)
1253#define __NR_setresgid (__NR_Linux + 190)
1254#define __NR_getresgid (__NR_Linux + 191)
1255#endif
1256#ifndef __NR_rt_sigaction
1257#define __NR_rt_sigreturn (__NR_Linux + 193)
1258#define __NR_rt_sigaction (__NR_Linux + 194)
1259#define __NR_rt_sigprocmask (__NR_Linux + 195)
1260#define __NR_rt_sigpending (__NR_Linux + 196)
1261#define __NR_rt_sigsuspend (__NR_Linux + 199)
1262#endif
1263#ifndef __NR_pread64
1264#define __NR_pread64 (__NR_Linux + 200)
1265#endif
1266#ifndef __NR_pwrite64
1267#define __NR_pwrite64 (__NR_Linux + 201)
1268#endif
1269#ifndef __NR_stat64
1270#define __NR_stat64 (__NR_Linux + 213)
1271#endif
1272#ifndef __NR_fstat64
1273#define __NR_fstat64 (__NR_Linux + 215)
1274#endif
1275#ifndef __NR_getdents64
1276#define __NR_getdents64 (__NR_Linux + 219)
1277#endif
1278#ifndef __NR_gettid
1279#define __NR_gettid (__NR_Linux + 222)
1280#endif
1281#ifndef __NR_readahead
1282#define __NR_readahead (__NR_Linux + 223)
1283#endif
1284#ifndef __NR_setxattr
1285#define __NR_setxattr (__NR_Linux + 224)
1286#endif
1287#ifndef __NR_lsetxattr
1288#define __NR_lsetxattr (__NR_Linux + 225)
1289#endif
1290#ifndef __NR_getxattr
1291#define __NR_getxattr (__NR_Linux + 227)
1292#endif
1293#ifndef __NR_lgetxattr
1294#define __NR_lgetxattr (__NR_Linux + 228)
1295#endif
1296#ifndef __NR_listxattr
1297#define __NR_listxattr (__NR_Linux + 230)
1298#endif
1299#ifndef __NR_llistxattr
1300#define __NR_llistxattr (__NR_Linux + 231)
1301#endif
1302#ifndef __NR_tkill
1303#define __NR_tkill (__NR_Linux + 236)
1304#endif
1305#ifndef __NR_futex
1306#define __NR_futex (__NR_Linux + 238)
1307#endif
1308#ifndef __NR_sched_setaffinity
1309#define __NR_sched_setaffinity (__NR_Linux + 239)
1310#define __NR_sched_getaffinity (__NR_Linux + 240)
1311#endif
1312#ifndef __NR_set_tid_address
1313#define __NR_set_tid_address (__NR_Linux + 252)
1314#endif
1315#ifndef __NR_statfs64
1316#define __NR_statfs64 (__NR_Linux + 255)
1317#endif
1318#ifndef __NR_fstatfs64
1319#define __NR_fstatfs64 (__NR_Linux + 256)
1320#endif
1321#ifndef __NR_clock_gettime
1322#define __NR_clock_gettime (__NR_Linux + 263)
1323#endif
1324#ifndef __NR_clock_getres
1325#define __NR_clock_getres (__NR_Linux + 264)
1326#endif
1327#ifndef __NR_openat
1328#define __NR_openat (__NR_Linux + 288)
1329#endif
1330#ifndef __NR_fstatat
1331#define __NR_fstatat (__NR_Linux + 293)
1332#endif
1333#ifndef __NR_unlinkat
1334#define __NR_unlinkat (__NR_Linux + 294)
1335#endif
1336#ifndef __NR_move_pages
1337#define __NR_move_pages (__NR_Linux + 308)
1338#endif
1339#ifndef __NR_getcpu
1340#define __NR_getcpu (__NR_Linux + 312)
1341#endif
1342#ifndef __NR_ioprio_set
1343#define __NR_ioprio_set (__NR_Linux + 314)
1344#endif
1345#ifndef __NR_ioprio_get
1346#define __NR_ioprio_get (__NR_Linux + 315)
1347#endif
1348/* End of MIPS (old 32bit API) definitions */
1349#elif _MIPS_SIM == _MIPS_SIM_ABI64
1350#ifndef __NR_pread64
1351#define __NR_pread64 (__NR_Linux + 16)
1352#endif
1353#ifndef __NR_pwrite64
1354#define __NR_pwrite64 (__NR_Linux + 17)
1355#endif
1356#ifndef __NR_setresuid
1357#define __NR_setresuid (__NR_Linux + 115)
1358#define __NR_getresuid (__NR_Linux + 116)
1359#define __NR_setresgid (__NR_Linux + 117)
1360#define __NR_getresgid (__NR_Linux + 118)
1361#endif
1362#ifndef __NR_gettid
1363#define __NR_gettid (__NR_Linux + 178)
1364#endif
1365#ifndef __NR_readahead
1366#define __NR_readahead (__NR_Linux + 179)
1367#endif
1368#ifndef __NR_setxattr
1369#define __NR_setxattr (__NR_Linux + 180)
1370#endif
1371#ifndef __NR_lsetxattr
1372#define __NR_lsetxattr (__NR_Linux + 181)
1373#endif
1374#ifndef __NR_getxattr
1375#define __NR_getxattr (__NR_Linux + 183)
1376#endif
1377#ifndef __NR_lgetxattr
1378#define __NR_lgetxattr (__NR_Linux + 184)
1379#endif
1380#ifndef __NR_listxattr
1381#define __NR_listxattr (__NR_Linux + 186)
1382#endif
1383#ifndef __NR_llistxattr
1384#define __NR_llistxattr (__NR_Linux + 187)
1385#endif
1386#ifndef __NR_tkill
1387#define __NR_tkill (__NR_Linux + 192)
1388#endif
1389#ifndef __NR_futex
1390#define __NR_futex (__NR_Linux + 194)
1391#endif
1392#ifndef __NR_sched_setaffinity
1393#define __NR_sched_setaffinity (__NR_Linux + 195)
1394#define __NR_sched_getaffinity (__NR_Linux + 196)
1395#endif
1396#ifndef __NR_set_tid_address
1397#define __NR_set_tid_address (__NR_Linux + 212)
1398#endif
1399#ifndef __NR_clock_gettime
1400#define __NR_clock_gettime (__NR_Linux + 222)
1401#endif
1402#ifndef __NR_clock_getres
1403#define __NR_clock_getres (__NR_Linux + 223)
1404#endif
1405#ifndef __NR_openat
1406#define __NR_openat (__NR_Linux + 247)
1407#endif
1408#ifndef __NR_fstatat
1409#define __NR_fstatat (__NR_Linux + 252)
1410#endif
1411#ifndef __NR_unlinkat
1412#define __NR_unlinkat (__NR_Linux + 253)
1413#endif
1414#ifndef __NR_move_pages
1415#define __NR_move_pages (__NR_Linux + 267)
1416#endif
1417#ifndef __NR_getcpu
1418#define __NR_getcpu (__NR_Linux + 271)
1419#endif
1420#ifndef __NR_ioprio_set
1421#define __NR_ioprio_set (__NR_Linux + 273)
1422#endif
1423#ifndef __NR_ioprio_get
1424#define __NR_ioprio_get (__NR_Linux + 274)
1425#endif
1426/* End of MIPS (64bit API) definitions */
1427#else
1428#ifndef __NR_setresuid
1429#define __NR_setresuid (__NR_Linux + 115)
1430#define __NR_getresuid (__NR_Linux + 116)
1431#define __NR_setresgid (__NR_Linux + 117)
1432#define __NR_getresgid (__NR_Linux + 118)
1433#endif
1434#ifndef __NR_gettid
1435#define __NR_gettid (__NR_Linux + 178)
1436#endif
1437#ifndef __NR_readahead
1438#define __NR_readahead (__NR_Linux + 179)
1439#endif
1440#ifndef __NR_setxattr
1441#define __NR_setxattr (__NR_Linux + 180)
1442#endif
1443#ifndef __NR_lsetxattr
1444#define __NR_lsetxattr (__NR_Linux + 181)
1445#endif
1446#ifndef __NR_getxattr
1447#define __NR_getxattr (__NR_Linux + 183)
1448#endif
1449#ifndef __NR_lgetxattr
1450#define __NR_lgetxattr (__NR_Linux + 184)
1451#endif
1452#ifndef __NR_listxattr
1453#define __NR_listxattr (__NR_Linux + 186)
1454#endif
1455#ifndef __NR_llistxattr
1456#define __NR_llistxattr (__NR_Linux + 187)
1457#endif
1458#ifndef __NR_tkill
1459#define __NR_tkill (__NR_Linux + 192)
1460#endif
1461#ifndef __NR_futex
1462#define __NR_futex (__NR_Linux + 194)
1463#endif
1464#ifndef __NR_sched_setaffinity
1465#define __NR_sched_setaffinity (__NR_Linux + 195)
1466#define __NR_sched_getaffinity (__NR_Linux + 196)
1467#endif
1468#ifndef __NR_set_tid_address
1469#define __NR_set_tid_address (__NR_Linux + 213)
1470#endif
1471#ifndef __NR_statfs64
1472#define __NR_statfs64 (__NR_Linux + 217)
1473#endif
1474#ifndef __NR_fstatfs64
1475#define __NR_fstatfs64 (__NR_Linux + 218)
1476#endif
1477#ifndef __NR_clock_gettime
1478#define __NR_clock_gettime (__NR_Linux + 226)
1479#endif
1480#ifndef __NR_clock_getres
1481#define __NR_clock_getres (__NR_Linux + 227)
1482#endif
1483#ifndef __NR_openat
1484#define __NR_openat (__NR_Linux + 251)
1485#endif
1486#ifndef __NR_fstatat
1487#define __NR_fstatat (__NR_Linux + 256)
1488#endif
1489#ifndef __NR_unlinkat
1490#define __NR_unlinkat (__NR_Linux + 257)
1491#endif
1492#ifndef __NR_move_pages
1493#define __NR_move_pages (__NR_Linux + 271)
1494#endif
1495#ifndef __NR_getcpu
1496#define __NR_getcpu (__NR_Linux + 275)
1497#endif
1498#ifndef __NR_ioprio_set
1499#define __NR_ioprio_set (__NR_Linux + 277)
1500#endif
1501#ifndef __NR_ioprio_get
1502#define __NR_ioprio_get (__NR_Linux + 278)
1503#endif
1504/* End of MIPS (new 32bit API) definitions */
1505#endif
1506/* End of MIPS definitions */
1507#elif defined(__PPC__)
1508#ifndef __NR_setfsuid
1509#define __NR_setfsuid 138
1510#define __NR_setfsgid 139
1511#endif
1512#ifndef __NR_setresuid
1513#define __NR_setresuid 164
1514#define __NR_getresuid 165
1515#define __NR_setresgid 169
1516#define __NR_getresgid 170
1517#endif
1518#ifndef __NR_rt_sigaction
1519#define __NR_rt_sigreturn 172
1520#define __NR_rt_sigaction 173
1521#define __NR_rt_sigprocmask 174
1522#define __NR_rt_sigpending 175
1523#define __NR_rt_sigsuspend 178
1524#endif
1525#ifndef __NR_pread64
1526#define __NR_pread64 179
1527#endif
1528#ifndef __NR_pwrite64
1529#define __NR_pwrite64 180
1530#endif
1531#ifndef __NR_ugetrlimit
1532#define __NR_ugetrlimit 190
1533#endif
1534#ifndef __NR_readahead
1535#define __NR_readahead 191
1536#endif
1537#ifndef __NR_stat64
1538#define __NR_stat64 195
1539#endif
1540#ifndef __NR_fstat64
1541#define __NR_fstat64 197
1542#endif
1543#ifndef __NR_getdents64
1544#define __NR_getdents64 202
1545#endif
1546#ifndef __NR_gettid
1547#define __NR_gettid 207
1548#endif
1549#ifndef __NR_tkill
1550#define __NR_tkill 208
1551#endif
1552#ifndef __NR_setxattr
1553#define __NR_setxattr 209
1554#endif
1555#ifndef __NR_lsetxattr
1556#define __NR_lsetxattr 210
1557#endif
1558#ifndef __NR_getxattr
1559#define __NR_getxattr 212
1560#endif
1561#ifndef __NR_lgetxattr
1562#define __NR_lgetxattr 213
1563#endif
1564#ifndef __NR_listxattr
1565#define __NR_listxattr 215
1566#endif
1567#ifndef __NR_llistxattr
1568#define __NR_llistxattr 216
1569#endif
1570#ifndef __NR_futex
1571#define __NR_futex 221
1572#endif
1573#ifndef __NR_sched_setaffinity
1574#define __NR_sched_setaffinity 222
1575#define __NR_sched_getaffinity 223
1576#endif
1577#ifndef __NR_set_tid_address
1578#define __NR_set_tid_address 232
1579#endif
1580#ifndef __NR_clock_gettime
1581#define __NR_clock_gettime 246
1582#endif
1583#ifndef __NR_clock_getres
1584#define __NR_clock_getres 247
1585#endif
1586#ifndef __NR_statfs64
1587#define __NR_statfs64 252
1588#endif
1589#ifndef __NR_fstatfs64
1590#define __NR_fstatfs64 253
1591#endif
1592#ifndef __NR_fadvise64_64
1593#define __NR_fadvise64_64 254
1594#endif
1595#ifndef __NR_ioprio_set
1596#define __NR_ioprio_set 273
1597#endif
1598#ifndef __NR_ioprio_get
1599#define __NR_ioprio_get 274
1600#endif
1601#ifndef __NR_openat
1602#define __NR_openat 286
1603#endif
1604#ifndef __NR_fstatat64
1605#define __NR_fstatat64 291
1606#endif
1607#ifndef __NR_unlinkat
1608#define __NR_unlinkat 292
1609#endif
1610#ifndef __NR_move_pages
1611#define __NR_move_pages 301
1612#endif
1613#ifndef __NR_getcpu
1614#define __NR_getcpu 302
1615#endif
1616/* End of powerpc defininitions */
Bryan Chan3f6478a2016-06-14 08:38:17 -04001617#elif defined(__s390__)
1618#ifndef __NR_quotactl
1619#define __NR_quotactl 131
1620#endif
1621#ifndef __NR_rt_sigreturn
1622#define __NR_rt_sigreturn 173
1623#endif
1624#ifndef __NR_rt_sigaction
1625#define __NR_rt_sigaction 174
1626#endif
1627#ifndef __NR_rt_sigprocmask
1628#define __NR_rt_sigprocmask 175
1629#endif
1630#ifndef __NR_rt_sigpending
1631#define __NR_rt_sigpending 176
1632#endif
1633#ifndef __NR_rt_sigsuspend
1634#define __NR_rt_sigsuspend 179
1635#endif
1636#ifndef __NR_pread64
1637#define __NR_pread64 180
1638#endif
1639#ifndef __NR_pwrite64
1640#define __NR_pwrite64 181
1641#endif
1642#ifndef __NR_getdents64
1643#define __NR_getdents64 220
1644#endif
1645#ifndef __NR_readahead
1646#define __NR_readahead 222
1647#endif
1648#ifndef __NR_setxattr
1649#define __NR_setxattr 224
1650#endif
1651#ifndef __NR_lsetxattr
1652#define __NR_lsetxattr 225
1653#endif
1654#ifndef __NR_getxattr
1655#define __NR_getxattr 227
1656#endif
1657#ifndef __NR_lgetxattr
1658#define __NR_lgetxattr 228
1659#endif
1660#ifndef __NR_listxattr
1661#define __NR_listxattr 230
1662#endif
1663#ifndef __NR_llistxattr
1664#define __NR_llistxattr 231
1665#endif
1666#ifndef __NR_gettid
1667#define __NR_gettid 236
1668#endif
1669#ifndef __NR_tkill
1670#define __NR_tkill 237
1671#endif
1672#ifndef __NR_futex
1673#define __NR_futex 238
1674#endif
1675#ifndef __NR_sched_setaffinity
1676#define __NR_sched_setaffinity 239
1677#endif
1678#ifndef __NR_sched_getaffinity
1679#define __NR_sched_getaffinity 240
1680#endif
1681#ifndef __NR_set_tid_address
1682#define __NR_set_tid_address 252
1683#endif
1684#ifndef __NR_clock_gettime
1685#define __NR_clock_gettime 260
1686#endif
1687#ifndef __NR_clock_getres
1688#define __NR_clock_getres 261
1689#endif
1690#ifndef __NR_statfs64
1691#define __NR_statfs64 265
1692#endif
1693#ifndef __NR_fstatfs64
1694#define __NR_fstatfs64 266
1695#endif
1696#ifndef __NR_ioprio_set
1697#define __NR_ioprio_set 282
1698#endif
1699#ifndef __NR_ioprio_get
1700#define __NR_ioprio_get 283
1701#endif
1702#ifndef __NR_openat
1703#define __NR_openat 288
1704#endif
1705#ifndef __NR_unlinkat
1706#define __NR_unlinkat 294
1707#endif
1708#ifndef __NR_move_pages
1709#define __NR_move_pages 310
1710#endif
1711#ifndef __NR_getcpu
1712#define __NR_getcpu 311
1713#endif
1714#ifndef __NR_fallocate
1715#define __NR_fallocate 314
1716#endif
1717/* Some syscalls are named/numbered differently between s390 and s390x. */
1718#ifdef __s390x__
1719# ifndef __NR_getrlimit
1720# define __NR_getrlimit 191
1721# endif
1722# ifndef __NR_setresuid
1723# define __NR_setresuid 208
1724# endif
1725# ifndef __NR_getresuid
1726# define __NR_getresuid 209
1727# endif
1728# ifndef __NR_setresgid
1729# define __NR_setresgid 210
1730# endif
1731# ifndef __NR_getresgid
1732# define __NR_getresgid 211
1733# endif
1734# ifndef __NR_setfsuid
1735# define __NR_setfsuid 215
1736# endif
1737# ifndef __NR_setfsgid
1738# define __NR_setfsgid 216
1739# endif
1740# ifndef __NR_fadvise64
1741# define __NR_fadvise64 253
1742# endif
1743# ifndef __NR_newfstatat
1744# define __NR_newfstatat 293
1745# endif
1746#else /* __s390x__ */
1747# ifndef __NR_getrlimit
1748# define __NR_getrlimit 76
1749# endif
1750# ifndef __NR_setfsuid
1751# define __NR_setfsuid 138
1752# endif
1753# ifndef __NR_setfsgid
1754# define __NR_setfsgid 139
1755# endif
1756# ifndef __NR_setresuid
1757# define __NR_setresuid 164
1758# endif
1759# ifndef __NR_getresuid
1760# define __NR_getresuid 165
1761# endif
1762# ifndef __NR_setresgid
1763# define __NR_setresgid 170
1764# endif
1765# ifndef __NR_getresgid
1766# define __NR_getresgid 171
1767# endif
1768# ifndef __NR_ugetrlimit
1769# define __NR_ugetrlimit 191
1770# endif
1771# ifndef __NR_mmap2
1772# define __NR_mmap2 192
1773# endif
1774# ifndef __NR_setresuid32
1775# define __NR_setresuid32 208
1776# endif
1777# ifndef __NR_getresuid32
1778# define __NR_getresuid32 209
1779# endif
1780# ifndef __NR_setresgid32
1781# define __NR_setresgid32 210
1782# endif
1783# ifndef __NR_getresgid32
1784# define __NR_getresgid32 211
1785# endif
1786# ifndef __NR_setfsuid32
1787# define __NR_setfsuid32 215
1788# endif
1789# ifndef __NR_setfsgid32
1790# define __NR_setfsgid32 216
1791# endif
1792# ifndef __NR_fadvise64_64
1793# define __NR_fadvise64_64 264
1794# endif
1795# ifndef __NR_fstatat64
1796# define __NR_fstatat64 293
1797# endif
1798#endif /* __s390__ */
1799/* End of s390/s390x definitions */
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001800#endif
1801
1802
1803/* After forking, we must make sure to only call system calls. */
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001804#if defined(__BOUNDED_POINTERS__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001805 #error "Need to port invocations of syscalls for bounded ptrs"
1806#else
1807 /* The core dumper and the thread lister get executed after threads
1808 * have been suspended. As a consequence, we cannot call any functions
1809 * that acquire locks. Unfortunately, libc wraps most system calls
1810 * (e.g. in order to implement pthread_atfork, and to make calls
1811 * cancellable), which means we cannot call these functions. Instead,
1812 * we have to call syscall() directly.
1813 */
1814 #undef LSS_ERRNO
1815 #ifdef SYS_ERRNO
1816 /* Allow the including file to override the location of errno. This can
1817 * be useful when using clone() with the CLONE_VM option.
1818 */
1819 #define LSS_ERRNO SYS_ERRNO
1820 #else
1821 #define LSS_ERRNO errno
1822 #endif
1823
1824 #undef LSS_INLINE
1825 #ifdef SYS_INLINE
1826 #define LSS_INLINE SYS_INLINE
1827 #else
1828 #define LSS_INLINE static inline
1829 #endif
1830
1831 /* Allow the including file to override the prefix used for all new
1832 * system calls. By default, it will be set to "sys_".
1833 */
1834 #undef LSS_NAME
1835 #ifndef SYS_PREFIX
1836 #define LSS_NAME(name) sys_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001837 #elif defined(SYS_PREFIX) && SYS_PREFIX < 0
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001838 #define LSS_NAME(name) 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) sys0_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001841 #elif defined(SYS_PREFIX) && SYS_PREFIX == 1
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001842 #define LSS_NAME(name) sys1_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001843 #elif defined(SYS_PREFIX) && SYS_PREFIX == 2
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001844 #define LSS_NAME(name) sys2_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001845 #elif defined(SYS_PREFIX) && SYS_PREFIX == 3
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001846 #define LSS_NAME(name) sys3_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001847 #elif defined(SYS_PREFIX) && SYS_PREFIX == 4
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001848 #define LSS_NAME(name) sys4_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001849 #elif defined(SYS_PREFIX) && SYS_PREFIX == 5
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001850 #define LSS_NAME(name) sys5_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001851 #elif defined(SYS_PREFIX) && SYS_PREFIX == 6
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001852 #define LSS_NAME(name) sys6_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001853 #elif defined(SYS_PREFIX) && SYS_PREFIX == 7
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001854 #define LSS_NAME(name) sys7_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001855 #elif defined(SYS_PREFIX) && SYS_PREFIX == 8
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001856 #define LSS_NAME(name) sys8_##name
mseaborn@chromium.org88a55e02012-06-14 19:43:32 +00001857 #elif defined(SYS_PREFIX) && SYS_PREFIX == 9
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001858 #define LSS_NAME(name) sys9_##name
1859 #endif
1860
1861 #undef LSS_RETURN
1862 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
Bryan Chan3f6478a2016-06-14 08:38:17 -04001863 || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001864 /* Failing system calls return a negative result in the range of
1865 * -1..-4095. These are "errno" values with the sign inverted.
1866 */
1867 #define LSS_RETURN(type, res) \
1868 do { \
1869 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
1870 LSS_ERRNO = -(res); \
1871 res = -1; \
1872 } \
1873 return (type) (res); \
1874 } while (0)
1875 #elif defined(__mips__)
1876 /* On MIPS, failing system calls return -1, and set errno in a
1877 * separate CPU register.
1878 */
1879 #define LSS_RETURN(type, res, err) \
1880 do { \
1881 if (err) { \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00001882 unsigned long __errnovalue = (res); \
1883 LSS_ERRNO = __errnovalue; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001884 res = -1; \
1885 } \
1886 return (type) (res); \
1887 } while (0)
1888 #elif defined(__PPC__)
1889 /* On PPC, failing system calls return -1, and set errno in a
1890 * separate CPU register. See linux/unistd.h.
1891 */
1892 #define LSS_RETURN(type, res, err) \
1893 do { \
1894 if (err & 0x10000000 ) { \
1895 LSS_ERRNO = (res); \
1896 res = -1; \
1897 } \
1898 return (type) (res); \
1899 } while (0)
1900 #endif
1901 #if defined(__i386__)
1902 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1903 * reserves ebx. Unfortunately, most distribution ship with implementations
1904 * of _syscallX() which clobber ebx.
1905 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1906 * clobbered. This causes problems with compilers, that do a better job
1907 * at optimizing across __asm__ calls.
1908 * So, we just have to redefine all of the _syscallX() macros.
1909 */
1910 #undef LSS_ENTRYPOINT
1911 #ifdef SYS_SYSCALL_ENTRYPOINT
1912 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
1913 void (**entrypoint)(void);
1914 asm volatile(".bss\n"
1915 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001916 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
1917 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001918 ".previous\n"
1919 /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
1920 "call 0f\n"
1921 "0:pop %0\n"
1922 "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001923 "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001924 : "=r"(entrypoint));
1925 return entrypoint;
1926 }
1927
1928 #define LSS_ENTRYPOINT ".bss\n" \
1929 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001930 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
1931 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001932 ".previous\n" \
1933 /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
1934 "push %%eax\n" \
1935 "call 10000f\n" \
1936 "10000:pop %%eax\n" \
1937 "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00001938 "mov " SYS_SYSCALL_ENTRYPOINT \
1939 "@GOT(%%eax), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001940 "mov 0(%%eax), %%eax\n" \
1941 "test %%eax, %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001942 "jz 10002f\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001943 "push %%eax\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001944 "call 10001f\n" \
1945 "10001:pop %%eax\n" \
1946 "add $(10003f-10001b), %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001947 "xchg 4(%%esp), %%eax\n" \
1948 "ret\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001949 "10002:pop %%eax\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001950 "int $0x80\n" \
agl@chromium.org92bafa42011-10-12 14:43:04 +00001951 "10003:\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001952 #else
1953 #define LSS_ENTRYPOINT "int $0x80\n"
1954 #endif
1955 #undef LSS_BODY
1956 #define LSS_BODY(type,args...) \
1957 long __res; \
1958 __asm__ __volatile__("push %%ebx\n" \
1959 "movl %2,%%ebx\n" \
1960 LSS_ENTRYPOINT \
1961 "pop %%ebx" \
1962 args \
1963 : "esp", "memory"); \
1964 LSS_RETURN(type,__res)
1965 #undef _syscall0
1966 #define _syscall0(type,name) \
1967 type LSS_NAME(name)(void) { \
1968 long __res; \
1969 __asm__ volatile(LSS_ENTRYPOINT \
1970 : "=a" (__res) \
1971 : "0" (__NR_##name) \
Khem Raj8048ece2018-12-22 16:07:39 -08001972 : "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00001973 LSS_RETURN(type,__res); \
1974 }
1975 #undef _syscall1
1976 #define _syscall1(type,name,type1,arg1) \
1977 type LSS_NAME(name)(type1 arg1) { \
1978 LSS_BODY(type, \
1979 : "=a" (__res) \
1980 : "0" (__NR_##name), "ri" ((long)(arg1))); \
1981 }
1982 #undef _syscall2
1983 #define _syscall2(type,name,type1,arg1,type2,arg2) \
1984 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
1985 LSS_BODY(type, \
1986 : "=a" (__res) \
1987 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
1988 }
1989 #undef _syscall3
1990 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
1991 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
1992 LSS_BODY(type, \
1993 : "=a" (__res) \
1994 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
1995 "d" ((long)(arg3))); \
1996 }
1997 #undef _syscall4
1998 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1999 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2000 LSS_BODY(type, \
2001 : "=a" (__res) \
2002 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
2003 "d" ((long)(arg3)),"S" ((long)(arg4))); \
2004 }
2005 #undef _syscall5
2006 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2007 type5,arg5) \
2008 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2009 type5 arg5) { \
2010 long __res; \
2011 __asm__ __volatile__("push %%ebx\n" \
2012 "movl %2,%%ebx\n" \
2013 "movl %1,%%eax\n" \
2014 LSS_ENTRYPOINT \
2015 "pop %%ebx" \
2016 : "=a" (__res) \
2017 : "i" (__NR_##name), "ri" ((long)(arg1)), \
2018 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2019 "S" ((long)(arg4)), "D" ((long)(arg5)) \
2020 : "esp", "memory"); \
2021 LSS_RETURN(type,__res); \
2022 }
2023 #undef _syscall6
2024 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2025 type5,arg5,type6,arg6) \
2026 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2027 type5 arg5, type6 arg6) { \
2028 long __res; \
2029 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
2030 __asm__ __volatile__("push %%ebp\n" \
2031 "push %%ebx\n" \
mseaborn@chromium.orge96ade32012-10-27 17:47:38 +00002032 "movl 4(%2),%%ebp\n" \
2033 "movl 0(%2), %%ebx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002034 "movl %1,%%eax\n" \
2035 LSS_ENTRYPOINT \
2036 "pop %%ebx\n" \
2037 "pop %%ebp" \
2038 : "=a" (__res) \
2039 : "i" (__NR_##name), "0" ((long)(&__s)), \
2040 "c" ((long)(arg2)), "d" ((long)(arg3)), \
2041 "S" ((long)(arg4)), "D" ((long)(arg5)) \
2042 : "esp", "memory"); \
2043 LSS_RETURN(type,__res); \
2044 }
2045 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2046 int flags, void *arg, int *parent_tidptr,
2047 void *newtls, int *child_tidptr) {
2048 long __res;
2049 __asm__ __volatile__(/* if (fn == NULL)
2050 * return -EINVAL;
2051 */
2052 "movl %3,%%ecx\n"
2053 "jecxz 1f\n"
2054
2055 /* if (child_stack == NULL)
2056 * return -EINVAL;
2057 */
2058 "movl %4,%%ecx\n"
2059 "jecxz 1f\n"
2060
2061 /* Set up alignment of the child stack:
2062 * child_stack = (child_stack & ~0xF) - 20;
2063 */
2064 "andl $-16,%%ecx\n"
2065 "subl $20,%%ecx\n"
2066
2067 /* Push "arg" and "fn" onto the stack that will be
2068 * used by the child.
2069 */
2070 "movl %6,%%eax\n"
2071 "movl %%eax,4(%%ecx)\n"
2072 "movl %3,%%eax\n"
2073 "movl %%eax,(%%ecx)\n"
2074
2075 /* %eax = syscall(%eax = __NR_clone,
2076 * %ebx = flags,
2077 * %ecx = child_stack,
2078 * %edx = parent_tidptr,
2079 * %esi = newtls,
2080 * %edi = child_tidptr)
2081 * Also, make sure that %ebx gets preserved as it is
2082 * used in PIC mode.
2083 */
2084 "movl %8,%%esi\n"
2085 "movl %7,%%edx\n"
2086 "movl %5,%%eax\n"
2087 "movl %9,%%edi\n"
2088 "pushl %%ebx\n"
2089 "movl %%eax,%%ebx\n"
2090 "movl %2,%%eax\n"
2091 LSS_ENTRYPOINT
2092
2093 /* In the parent: restore %ebx
2094 * In the child: move "fn" into %ebx
2095 */
2096 "popl %%ebx\n"
2097
2098 /* if (%eax != 0)
2099 * return %eax;
2100 */
2101 "test %%eax,%%eax\n"
2102 "jnz 1f\n"
2103
2104 /* In the child, now. Terminate frame pointer chain.
2105 */
2106 "movl $0,%%ebp\n"
2107
2108 /* Call "fn". "arg" is already on the stack.
2109 */
2110 "call *%%ebx\n"
2111
2112 /* Call _exit(%ebx). Unfortunately older versions
2113 * of gcc restrict the number of arguments that can
2114 * be passed to asm(). So, we need to hard-code the
2115 * system call number.
2116 */
2117 "movl %%eax,%%ebx\n"
2118 "movl $1,%%eax\n"
2119 LSS_ENTRYPOINT
2120
2121 /* Return to parent.
2122 */
2123 "1:\n"
2124 : "=a" (__res)
2125 : "0"(-EINVAL), "i"(__NR_clone),
2126 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
2127 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
2128 : "esp", "memory", "ecx", "edx", "esi", "edi");
2129 LSS_RETURN(int, __res);
2130 }
2131
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002132 LSS_INLINE _syscall1(int, set_thread_area, void *, u)
2133 LSS_INLINE _syscall1(int, get_thread_area, void *, u)
2134
2135 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2136 /* On i386, the kernel does not know how to return from a signal
2137 * handler. Instead, it relies on user space to provide a
2138 * restorer function that calls the {rt_,}sigreturn() system call.
2139 * Unfortunately, we cannot just reference the glibc version of this
2140 * function, as glibc goes out of its way to make it inaccessible.
2141 */
2142 void (*res)(void);
2143 __asm__ __volatile__("call 2f\n"
2144 "0:.align 16\n"
2145 "1:movl %1,%%eax\n"
2146 LSS_ENTRYPOINT
2147 "2:popl %0\n"
2148 "addl $(1b-0b),%0\n"
2149 : "=a" (res)
2150 : "i" (__NR_rt_sigreturn));
2151 return res;
2152 }
2153 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
2154 /* On i386, the kernel does not know how to return from a signal
2155 * handler. Instead, it relies on user space to provide a
2156 * restorer function that calls the {rt_,}sigreturn() system call.
2157 * Unfortunately, we cannot just reference the glibc version of this
2158 * function, as glibc goes out of its way to make it inaccessible.
2159 */
2160 void (*res)(void);
2161 __asm__ __volatile__("call 2f\n"
2162 "0:.align 16\n"
2163 "1:pop %%eax\n"
2164 "movl %1,%%eax\n"
2165 LSS_ENTRYPOINT
2166 "2:popl %0\n"
2167 "addl $(1b-0b),%0\n"
2168 : "=a" (res)
2169 : "i" (__NR_sigreturn));
2170 return res;
2171 }
2172 #elif defined(__x86_64__)
2173 /* There are no known problems with any of the _syscallX() macros
2174 * currently shipping for x86_64, but we still need to be able to define
2175 * our own version so that we can override the location of the errno
2176 * location (e.g. when using the clone() system call with the CLONE_VM
2177 * option).
2178 */
2179 #undef LSS_ENTRYPOINT
2180 #ifdef SYS_SYSCALL_ENTRYPOINT
2181 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
2182 void (**entrypoint)(void);
2183 asm volatile(".bss\n"
2184 ".align 8\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002185 ".globl " SYS_SYSCALL_ENTRYPOINT "\n"
2186 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002187 ".previous\n"
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002188 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002189 : "=r"(entrypoint));
2190 return entrypoint;
2191 }
2192
2193 #define LSS_ENTRYPOINT \
2194 ".bss\n" \
2195 ".align 8\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002196 ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \
2197 ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002198 ".previous\n" \
mseaborn@chromium.orgc0e5b382014-05-28 17:59:51 +00002199 "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002200 "mov 0(%%rcx), %%rcx\n" \
2201 "test %%rcx, %%rcx\n" \
2202 "jz 10001f\n" \
2203 "call *%%rcx\n" \
2204 "jmp 10002f\n" \
2205 "10001:syscall\n" \
2206 "10002:\n"
2207
2208 #else
2209 #define LSS_ENTRYPOINT "syscall\n"
2210 #endif
vapier@chromium.org2273e812013-04-01 17:52:44 +00002211
2212 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
2213 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
2214 * sign extension. We can't cast pointers directly because those are
2215 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
2216 * to an integer of a different size.
2217 */
2218 #undef LSS_SYSCALL_ARG
2219 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
2220 #undef _LSS_RETURN
2221 #define _LSS_RETURN(type, res, cast) \
2222 do { \
2223 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
2224 LSS_ERRNO = -(res); \
2225 res = -1; \
2226 } \
2227 return (type)(cast)(res); \
2228 } while (0)
2229 #undef LSS_RETURN
2230 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
2231
2232 #undef _LSS_BODY
2233 #define _LSS_BODY(nr, type, name, cast, ...) \
2234 long long __res; \
2235 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
2236 : "=a" (__res) \
2237 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
2238 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
2239 _LSS_RETURN(type, __res, cast)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002240 #undef LSS_BODY
vapier@chromium.org2273e812013-04-01 17:52:44 +00002241 #define LSS_BODY(nr, type, name, args...) \
2242 _LSS_BODY(nr, type, name, uintptr_t, ## args)
2243
2244 #undef LSS_BODY_ASM0
2245 #undef LSS_BODY_ASM1
2246 #undef LSS_BODY_ASM2
2247 #undef LSS_BODY_ASM3
2248 #undef LSS_BODY_ASM4
2249 #undef LSS_BODY_ASM5
2250 #undef LSS_BODY_ASM6
2251 #define LSS_BODY_ASM0
2252 #define LSS_BODY_ASM1 LSS_BODY_ASM0
2253 #define LSS_BODY_ASM2 LSS_BODY_ASM1
2254 #define LSS_BODY_ASM3 LSS_BODY_ASM2
2255 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
2256 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
2257 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
2258
2259 #undef LSS_BODY_CLOBBER0
2260 #undef LSS_BODY_CLOBBER1
2261 #undef LSS_BODY_CLOBBER2
2262 #undef LSS_BODY_CLOBBER3
2263 #undef LSS_BODY_CLOBBER4
2264 #undef LSS_BODY_CLOBBER5
2265 #undef LSS_BODY_CLOBBER6
2266 #define LSS_BODY_CLOBBER0
2267 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
2268 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
2269 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
2270 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
2271 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
2272 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
2273
2274 #undef LSS_BODY_ARG0
2275 #undef LSS_BODY_ARG1
2276 #undef LSS_BODY_ARG2
2277 #undef LSS_BODY_ARG3
2278 #undef LSS_BODY_ARG4
2279 #undef LSS_BODY_ARG5
2280 #undef LSS_BODY_ARG6
2281 #define LSS_BODY_ARG0()
2282 #define LSS_BODY_ARG1(arg1) \
2283 LSS_BODY_ARG0(), "D" (arg1)
2284 #define LSS_BODY_ARG2(arg1, arg2) \
2285 LSS_BODY_ARG1(arg1), "S" (arg2)
2286 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
2287 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
2288 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
2289 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
2290 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
2291 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
2292 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
2293 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
2294
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002295 #undef _syscall0
2296 #define _syscall0(type,name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002297 type LSS_NAME(name)(void) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002298 LSS_BODY(0, type, name); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002299 }
2300 #undef _syscall1
2301 #define _syscall1(type,name,type1,arg1) \
2302 type LSS_NAME(name)(type1 arg1) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002303 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002304 }
2305 #undef _syscall2
2306 #define _syscall2(type,name,type1,arg1,type2,arg2) \
2307 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002308 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002309 }
2310 #undef _syscall3
2311 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
2312 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002313 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2314 LSS_SYSCALL_ARG(arg3)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002315 }
2316 #undef _syscall4
2317 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2318 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002319 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2320 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002321 }
2322 #undef _syscall5
2323 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2324 type5,arg5) \
2325 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2326 type5 arg5) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002327 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2328 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2329 LSS_SYSCALL_ARG(arg5)); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002330 }
2331 #undef _syscall6
2332 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2333 type5,arg5,type6,arg6) \
2334 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2335 type5 arg5, type6 arg6) { \
vapier@chromium.org2273e812013-04-01 17:52:44 +00002336 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
2337 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
2338 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002339 }
2340 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2341 int flags, void *arg, int *parent_tidptr,
2342 void *newtls, int *child_tidptr) {
vapier@chromium.org2273e812013-04-01 17:52:44 +00002343 long long __res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002344 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002345 __asm__ __volatile__(/* if (fn == NULL)
2346 * return -EINVAL;
2347 */
2348 "testq %4,%4\n"
2349 "jz 1f\n"
2350
2351 /* if (child_stack == NULL)
2352 * return -EINVAL;
2353 */
2354 "testq %5,%5\n"
2355 "jz 1f\n"
2356
2357 /* childstack -= 2*sizeof(void *);
2358 */
2359 "subq $16,%5\n"
2360
2361 /* Push "arg" and "fn" onto the stack that will be
2362 * used by the child.
2363 */
2364 "movq %7,8(%5)\n"
2365 "movq %4,0(%5)\n"
2366
2367 /* %rax = syscall(%rax = __NR_clone,
2368 * %rdi = flags,
2369 * %rsi = child_stack,
2370 * %rdx = parent_tidptr,
2371 * %r8 = new_tls,
2372 * %r10 = child_tidptr)
2373 */
2374 "movq %2,%%rax\n"
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00002375 "movq %9,%%r8\n"
2376 "movq %10,%%r10\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002377 LSS_ENTRYPOINT
2378
2379 /* if (%rax != 0)
2380 * return;
2381 */
2382 "testq %%rax,%%rax\n"
2383 "jnz 1f\n"
2384
2385 /* In the child. Terminate frame pointer chain.
2386 */
2387 "xorq %%rbp,%%rbp\n"
2388
2389 /* Call "fn(arg)".
2390 */
2391 "popq %%rax\n"
2392 "popq %%rdi\n"
2393 "call *%%rax\n"
2394
2395 /* Call _exit(%ebx).
2396 */
2397 "movq %%rax,%%rdi\n"
2398 "movq %3,%%rax\n"
2399 LSS_ENTRYPOINT
2400
2401 /* Return to parent.
2402 */
2403 "1:\n"
2404 : "=a" (__res)
2405 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
vapier@chromium.org2273e812013-04-01 17:52:44 +00002406 "r"(LSS_SYSCALL_ARG(fn)),
2407 "S"(LSS_SYSCALL_ARG(child_stack)),
2408 "D"(LSS_SYSCALL_ARG(flags)),
2409 "r"(LSS_SYSCALL_ARG(arg)),
2410 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
2411 "r"(LSS_SYSCALL_ARG(newtls)),
2412 "r"(LSS_SYSCALL_ARG(child_tidptr))
Khem Raj8048ece2018-12-22 16:07:39 -08002413 : "memory", "r8", "r10", "r11", "rcx");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002414 }
2415 LSS_RETURN(int, __res);
2416 }
2417 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a)
vapier@chromium.org2273e812013-04-01 17:52:44 +00002418
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002419 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
2420 /* On x86-64, the kernel does not know how to return from
2421 * a signal handler. Instead, it relies on user space to provide a
2422 * restorer function that calls the rt_sigreturn() system call.
2423 * Unfortunately, we cannot just reference the glibc version of this
2424 * function, as glibc goes out of its way to make it inaccessible.
2425 */
vapier@chromium.org2273e812013-04-01 17:52:44 +00002426 long long res;
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002427 __asm__ __volatile__("jmp 2f\n"
2428 ".align 16\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002429 "1:movq %1,%%rax\n"
2430 LSS_ENTRYPOINT
mseaborn@chromium.org798c2f72013-08-31 00:04:49 +00002431 "2:leaq 1b(%%rip),%0\n"
2432 : "=r" (res)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002433 : "i" (__NR_rt_sigreturn));
vapier@chromium.org833a10e2013-04-02 19:34:26 +00002434 return (void (*)(void))(uintptr_t)res;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002435 }
2436 #elif defined(__ARM_ARCH_3__)
2437 /* Most definitions of _syscallX() neglect to mark "memory" as being
2438 * clobbered. This causes problems with compilers, that do a better job
2439 * at optimizing across __asm__ calls.
2440 * So, we just have to redefine all of the _syscallX() macros.
2441 */
2442 #undef LSS_REG
2443 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2444 #undef LSS_BODY
2445 #define LSS_BODY(type,name,args...) \
2446 register long __res_r0 __asm__("r0"); \
2447 long __res; \
2448 __asm__ __volatile__ (__syscall(name) \
2449 : "=r"(__res_r0) : args : "lr", "memory"); \
2450 __res = __res_r0; \
2451 LSS_RETURN(type, __res)
2452 #undef _syscall0
2453 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002454 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002455 LSS_BODY(type, name); \
2456 }
2457 #undef _syscall1
2458 #define _syscall1(type, name, type1, arg1) \
2459 type LSS_NAME(name)(type1 arg1) { \
2460 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2461 }
2462 #undef _syscall2
2463 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2464 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2465 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2466 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2467 }
2468 #undef _syscall3
2469 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2470 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2471 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2472 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2473 }
2474 #undef _syscall4
2475 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2476 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2477 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2478 LSS_REG(3, arg4); \
2479 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2480 }
2481 #undef _syscall5
2482 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2483 type5,arg5) \
2484 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2485 type5 arg5) { \
2486 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2487 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2488 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2489 "r"(__r4)); \
2490 }
2491 #undef _syscall6
2492 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2493 type5,arg5,type6,arg6) \
2494 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2495 type5 arg5, type6 arg6) { \
2496 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2497 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2498 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2499 "r"(__r4), "r"(__r5)); \
2500 }
2501 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2502 int flags, void *arg, int *parent_tidptr,
2503 void *newtls, int *child_tidptr) {
2504 long __res;
2505 {
2506 register int __flags __asm__("r0") = flags;
2507 register void *__stack __asm__("r1") = child_stack;
2508 register void *__ptid __asm__("r2") = parent_tidptr;
2509 register void *__tls __asm__("r3") = newtls;
2510 register int *__ctid __asm__("r4") = child_tidptr;
2511 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2512 * return -EINVAL;
2513 */
2514 "cmp %2,#0\n"
2515 "cmpne %3,#0\n"
2516 "moveq %0,%1\n"
2517 "beq 1f\n"
2518
2519 /* Push "arg" and "fn" onto the stack that will be
2520 * used by the child.
2521 */
2522 "str %5,[%3,#-4]!\n"
2523 "str %2,[%3,#-4]!\n"
2524
2525 /* %r0 = syscall(%r0 = flags,
2526 * %r1 = child_stack,
2527 * %r2 = parent_tidptr,
2528 * %r3 = newtls,
2529 * %r4 = child_tidptr)
2530 */
2531 __syscall(clone)"\n"
2532
2533 /* if (%r0 != 0)
2534 * return %r0;
2535 */
2536 "movs %0,r0\n"
2537 "bne 1f\n"
2538
2539 /* In the child, now. Call "fn(arg)".
2540 */
2541 "ldr r0,[sp, #4]\n"
2542 "mov lr,pc\n"
2543 "ldr pc,[sp]\n"
2544
2545 /* Call _exit(%r0).
2546 */
2547 __syscall(exit)"\n"
2548 "1:\n"
2549 : "=r" (__res)
2550 : "i"(-EINVAL),
2551 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2552 "r"(__ptid), "r"(__tls), "r"(__ctid)
2553 : "cc", "lr", "memory");
2554 }
2555 LSS_RETURN(int, __res);
2556 }
2557 #elif defined(__ARM_EABI__)
2558 /* Most definitions of _syscallX() neglect to mark "memory" as being
2559 * clobbered. This causes problems with compilers, that do a better job
2560 * at optimizing across __asm__ calls.
2561 * So, we just have to redefine all fo the _syscallX() macros.
2562 */
2563 #undef LSS_REG
2564 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
2565 #undef LSS_BODY
2566 #define LSS_BODY(type,name,args...) \
2567 register long __res_r0 __asm__("r0"); \
2568 long __res; \
2569 __asm__ __volatile__ ("push {r7}\n" \
2570 "mov r7, %1\n" \
2571 "swi 0x0\n" \
2572 "pop {r7}\n" \
2573 : "=r"(__res_r0) \
2574 : "i"(__NR_##name) , ## args \
2575 : "lr", "memory"); \
2576 __res = __res_r0; \
2577 LSS_RETURN(type, __res)
2578 #undef _syscall0
2579 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002580 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002581 LSS_BODY(type, name); \
2582 }
2583 #undef _syscall1
2584 #define _syscall1(type, name, type1, arg1) \
2585 type LSS_NAME(name)(type1 arg1) { \
2586 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2587 }
2588 #undef _syscall2
2589 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2590 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2591 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2592 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2593 }
2594 #undef _syscall3
2595 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2596 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2597 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2598 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2599 }
2600 #undef _syscall4
2601 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2602 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2603 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2604 LSS_REG(3, arg4); \
2605 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2606 }
2607 #undef _syscall5
2608 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2609 type5,arg5) \
2610 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2611 type5 arg5) { \
2612 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2613 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2614 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2615 "r"(__r4)); \
2616 }
2617 #undef _syscall6
2618 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2619 type5,arg5,type6,arg6) \
2620 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2621 type5 arg5, type6 arg6) { \
2622 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2623 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2624 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2625 "r"(__r4), "r"(__r5)); \
2626 }
2627 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2628 int flags, void *arg, int *parent_tidptr,
2629 void *newtls, int *child_tidptr) {
2630 long __res;
Amaury Le Leyzourc555f532017-02-23 12:33:02 -08002631 if (fn == NULL || child_stack == NULL) {
2632 __res = -EINVAL;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002633 LSS_RETURN(int, __res);
2634 }
2635
2636 /* Push "arg" and "fn" onto the stack that will be
2637 * used by the child.
2638 */
2639 {
2640 uintptr_t* cstack = (uintptr_t*)child_stack - 2;
2641 cstack[0] = (uintptr_t)fn;
2642 cstack[1] = (uintptr_t)arg;
2643 child_stack = cstack;
2644 }
2645 {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002646 register int __flags __asm__("r0") = flags;
2647 register void *__stack __asm__("r1") = child_stack;
2648 register void *__ptid __asm__("r2") = parent_tidptr;
2649 register void *__tls __asm__("r3") = newtls;
2650 register int *__ctid __asm__("r4") = child_tidptr;
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002651 __asm__ __volatile__(
Nico Weber63f24c82017-03-30 13:37:06 -04002652#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002653 "push {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002654#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002655 /* %r0 = syscall(%r0 = flags,
2656 * %r1 = child_stack,
2657 * %r2 = parent_tidptr,
2658 * %r3 = newtls,
2659 * %r4 = child_tidptr)
2660 */
2661 "mov r7, %6\n"
2662 "swi 0x0\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002663
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002664 /* if (%r0 != 0)
2665 * return %r0;
2666 */
2667 "cmp r0, #0\n"
2668 "bne 1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002669
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002670 /* In the child, now. Call "fn(arg)".
2671 */
2672 "ldr r0,[sp, #4]\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002673
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002674 "ldr lr,[sp]\n"
2675 "blx lr\n"
zodiac@gmail.com68c659b2011-10-06 05:34:19 +00002676
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002677 /* Call _exit(%r0).
2678 */
2679 "mov r7, %7\n"
2680 "swi 0x0\n"
2681 /* Unreachable */
2682 "bkpt #0\n"
2683 "1:\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002684#ifdef __thumb2__
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002685 "pop {r7}\n"
Nico Weber63f24c82017-03-30 13:37:06 -04002686#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002687 "movs %0,r0\n"
2688 : "=r"(__res)
2689 : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid),
2690 "i"(__NR_clone), "i"(__NR_exit)
2691 : "cc", "lr", "memory"
2692#ifndef __thumb2__
2693 , "r7"
Nico Weber63f24c82017-03-30 13:37:06 -04002694#endif
Amaury Le Leyzoura91633d2017-06-01 10:44:09 -07002695 );
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002696 }
2697 LSS_RETURN(int, __res);
2698 }
anton@chromium.org2f724fc2014-04-15 13:05:20 +00002699 #elif defined(__aarch64__)
2700 /* Most definitions of _syscallX() neglect to mark "memory" as being
2701 * clobbered. This causes problems with compilers, that do a better job
2702 * at optimizing across __asm__ calls.
2703 * So, we just have to redefine all of the _syscallX() macros.
2704 */
2705 #undef LSS_REG
2706 #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
2707 #undef LSS_BODY
2708 #define LSS_BODY(type,name,args...) \
2709 register int64_t __res_x0 __asm__("x0"); \
2710 int64_t __res; \
2711 __asm__ __volatile__ ("mov x8, %1\n" \
2712 "svc 0x0\n" \
2713 : "=r"(__res_x0) \
2714 : "i"(__NR_##name) , ## args \
2715 : "x8", "memory"); \
2716 __res = __res_x0; \
2717 LSS_RETURN(type, __res)
2718 #undef _syscall0
2719 #define _syscall0(type, name) \
2720 type LSS_NAME(name)(void) { \
2721 LSS_BODY(type, name); \
2722 }
2723 #undef _syscall1
2724 #define _syscall1(type, name, type1, arg1) \
2725 type LSS_NAME(name)(type1 arg1) { \
2726 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
2727 }
2728 #undef _syscall2
2729 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2730 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2731 LSS_REG(0, arg1); LSS_REG(1, arg2); \
2732 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
2733 }
2734 #undef _syscall3
2735 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2736 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2737 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2738 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
2739 }
2740 #undef _syscall4
2741 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2742 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2743 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2744 LSS_REG(3, arg4); \
2745 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
2746 }
2747 #undef _syscall5
2748 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2749 type5,arg5) \
2750 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2751 type5 arg5) { \
2752 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2753 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2754 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2755 "r"(__r4)); \
2756 }
2757 #undef _syscall6
2758 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2759 type5,arg5,type6,arg6) \
2760 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2761 type5 arg5, type6 arg6) { \
2762 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2763 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2764 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
2765 "r"(__r4), "r"(__r5)); \
2766 }
2767
2768 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2769 int flags, void *arg, int *parent_tidptr,
2770 void *newtls, int *child_tidptr) {
2771 int64_t __res;
2772 {
2773 register uint64_t __flags __asm__("x0") = flags;
2774 register void *__stack __asm__("x1") = child_stack;
2775 register void *__ptid __asm__("x2") = parent_tidptr;
2776 register void *__tls __asm__("x3") = newtls;
2777 register int *__ctid __asm__("x4") = child_tidptr;
2778 __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
2779 * used by the child.
2780 */
2781 "stp %1, %4, [%2, #-16]!\n"
2782
2783 /* %x0 = syscall(%x0 = flags,
2784 * %x1 = child_stack,
2785 * %x2 = parent_tidptr,
2786 * %x3 = newtls,
2787 * %x4 = child_tidptr)
2788 */
2789 "mov x8, %8\n"
2790 "svc 0x0\n"
2791
2792 /* if (%r0 != 0)
2793 * return %r0;
2794 */
2795 "mov %0, x0\n"
2796 "cbnz x0, 1f\n"
2797
2798 /* In the child, now. Call "fn(arg)".
2799 */
2800 "ldp x1, x0, [sp], #16\n"
2801 "blr x1\n"
2802
2803 /* Call _exit(%r0).
2804 */
2805 "mov x8, %9\n"
2806 "svc 0x0\n"
2807 "1:\n"
2808 : "=r" (__res)
2809 : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
2810 "r"(__ptid), "r"(__tls), "r"(__ctid),
2811 "i"(__NR_clone), "i"(__NR_exit)
2812 : "cc", "x8", "memory");
2813 }
2814 LSS_RETURN(int, __res);
2815 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002816 #elif defined(__mips__)
2817 #undef LSS_REG
2818 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
2819 (unsigned long)(a)
2820 #undef LSS_BODY
thestig@chromium.org952107f2014-08-01 02:22:56 +00002821 #undef LSS_SYSCALL_CLOBBERS
2822 #if _MIPS_SIM == _MIPS_SIM_ABI32
2823 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \
2824 "$11", "$12", "$13", "$14", "$15", \
2825 "$24", "$25", "hi", "lo", "memory"
2826 #else
2827 #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \
2828 "$13", "$14", "$15", "$24", "$25", \
2829 "hi", "lo", "memory"
2830 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002831 #define LSS_BODY(type,name,r7,...) \
2832 register unsigned long __v0 __asm__("$2") = __NR_##name; \
2833 __asm__ __volatile__ ("syscall\n" \
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00002834 : "=r"(__v0), r7 (__r7) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002835 : "0"(__v0), ##__VA_ARGS__ \
thestig@chromium.org952107f2014-08-01 02:22:56 +00002836 : LSS_SYSCALL_CLOBBERS); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002837 LSS_RETURN(type, __v0, __r7)
2838 #undef _syscall0
2839 #define _syscall0(type, name) \
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00002840 type LSS_NAME(name)(void) { \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002841 register unsigned long __r7 __asm__("$7"); \
2842 LSS_BODY(type, name, "=r"); \
2843 }
2844 #undef _syscall1
2845 #define _syscall1(type, name, type1, arg1) \
2846 type LSS_NAME(name)(type1 arg1) { \
2847 register unsigned long __r7 __asm__("$7"); \
2848 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
2849 }
2850 #undef _syscall2
2851 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2852 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2853 register unsigned long __r7 __asm__("$7"); \
2854 LSS_REG(4, arg1); LSS_REG(5, arg2); \
2855 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
2856 }
2857 #undef _syscall3
2858 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2859 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2860 register unsigned long __r7 __asm__("$7"); \
2861 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2862 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2863 }
2864 #undef _syscall4
2865 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2866 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2867 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2868 LSS_REG(7, arg4); \
2869 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
2870 }
2871 #undef _syscall5
2872 #if _MIPS_SIM == _MIPS_SIM_ABI32
2873 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2874 * on the stack, whereas the new APIs use registers "r8" and "r9".
2875 */
2876 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2877 type5,arg5) \
2878 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2879 type5 arg5) { \
2880 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2881 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002882 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002883 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002884 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002885 "sw %5, 16($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002886 "syscall\n" \
2887 "addiu $29, 32\n" \
2888 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002889 : "+r"(__v0), "+r" (__r7) \
2890 : "r"(__r4), "r"(__r5), \
2891 "r"(__r6), "r" ((unsigned long)arg5) \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002892 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002893 "$13", "$14", "$15", "$24", "$25", \
2894 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002895 LSS_RETURN(type, __v0, __r7); \
2896 }
2897 #else
2898 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2899 type5,arg5) \
2900 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2901 type5 arg5) { \
2902 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2903 LSS_REG(7, arg4); LSS_REG(8, arg5); \
2904 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2905 "r"(__r8)); \
2906 }
2907 #endif
2908 #undef _syscall6
2909 #if _MIPS_SIM == _MIPS_SIM_ABI32
2910 /* The old 32bit MIPS system call API passes the fifth and sixth argument
2911 * on the stack, whereas the new APIs use registers "r8" and "r9".
2912 */
2913 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2914 type5,arg5,type6,arg6) \
2915 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2916 type5 arg5, type6 arg6) { \
2917 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2918 LSS_REG(7, arg4); \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002919 register unsigned long __v0 __asm__("$2") = __NR_##name; \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002920 __asm__ __volatile__ (".set noreorder\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002921 "subu $29, 32\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002922 "sw %5, 16($29)\n" \
2923 "sw %6, 20($29)\n" \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002924 "syscall\n" \
2925 "addiu $29, 32\n" \
2926 ".set reorder\n" \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002927 : "+r"(__v0), "+r" (__r7) \
2928 : "r"(__r4), "r"(__r5), \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002929 "r"(__r6), "r" ((unsigned long)arg5), \
2930 "r" ((unsigned long)arg6) \
2931 : "$8", "$9", "$10", "$11", "$12", \
zodiac@gmail.coma6591482012-04-13 01:29:30 +00002932 "$13", "$14", "$15", "$24", "$25", \
2933 "memory"); \
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002934 LSS_RETURN(type, __v0, __r7); \
2935 }
2936 #else
2937 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2938 type5,arg5,type6,arg6) \
2939 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2940 type5 arg5,type6 arg6) { \
2941 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
2942 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
2943 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
2944 "r"(__r8), "r"(__r9)); \
2945 }
2946 #endif
2947 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2948 int flags, void *arg, int *parent_tidptr,
2949 void *newtls, int *child_tidptr) {
vapier@chromium.orge0797682015-02-20 20:45:56 +00002950 register unsigned long __v0 __asm__("$2") = -EINVAL;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002951 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
2952 {
2953 register int __flags __asm__("$4") = flags;
2954 register void *__stack __asm__("$5") = child_stack;
2955 register void *__ptid __asm__("$6") = parent_tidptr;
2956 register int *__ctid __asm__("$8") = child_tidptr;
2957 __asm__ __volatile__(
2958 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
2959 "subu $29,24\n"
2960 #elif _MIPS_SIM == _MIPS_SIM_NABI32
2961 "sub $29,16\n"
2962 #else
2963 "dsubu $29,16\n"
2964 #endif
2965
2966 /* if (fn == NULL || child_stack == NULL)
2967 * return -EINVAL;
2968 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002969 "beqz %4,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002970 "beqz %5,1f\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002971
2972 /* Push "arg" and "fn" onto the stack that will be
2973 * used by the child.
2974 */
2975 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002976 "subu %5,32\n"
2977 "sw %4,0(%5)\n"
2978 "sw %7,4(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002979 #elif _MIPS_SIM == _MIPS_SIM_NABI32
vapier@chromium.orge0797682015-02-20 20:45:56 +00002980 "sub %5,32\n"
2981 "sw %4,0(%5)\n"
2982 "sw %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002983 #else
vapier@chromium.orge0797682015-02-20 20:45:56 +00002984 "dsubu %5,32\n"
2985 "sd %4,0(%5)\n"
2986 "sd %7,8(%5)\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002987 #endif
2988
2989 /* $7 = syscall($4 = flags,
2990 * $5 = child_stack,
2991 * $6 = parent_tidptr,
2992 * $7 = newtls,
2993 * $8 = child_tidptr)
2994 */
vapier@chromium.orge0797682015-02-20 20:45:56 +00002995 "li $2,%2\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00002996 "syscall\n"
2997
2998 /* if ($7 != 0)
2999 * return $2;
3000 */
3001 "bnez $7,1f\n"
3002 "bnez $2,1f\n"
3003
3004 /* In the child, now. Call "fn(arg)".
3005 */
3006 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3007 "lw $25,0($29)\n"
3008 "lw $4,4($29)\n"
3009 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3010 "lw $25,0($29)\n"
3011 "lw $4,8($29)\n"
3012 #else
3013 "ld $25,0($29)\n"
3014 "ld $4,8($29)\n"
3015 #endif
3016 "jalr $25\n"
3017
3018 /* Call _exit($2)
3019 */
3020 "move $4,$2\n"
vapier@chromium.orge0797682015-02-20 20:45:56 +00003021 "li $2,%3\n"
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003022 "syscall\n"
3023
3024 "1:\n"
3025 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
3026 "addu $29, 24\n"
3027 #elif _MIPS_SIM == _MIPS_SIM_NABI32
3028 "add $29, 16\n"
3029 #else
3030 "daddu $29,16\n"
3031 #endif
petarj@mips.com0ece1c62013-04-10 00:28:04 +00003032 : "+r" (__v0), "+r" (__r7)
vapier@chromium.orge0797682015-02-20 20:45:56 +00003033 : "i"(__NR_clone), "i"(__NR_exit), "r"(fn),
3034 "r"(__stack), "r"(__flags), "r"(arg),
3035 "r"(__ptid), "r"(__ctid)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003036 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00003037 "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003038 }
3039 LSS_RETURN(int, __v0, __r7);
3040 }
3041 #elif defined (__PPC__)
3042 #undef LSS_LOADARGS_0
3043 #define LSS_LOADARGS_0(name, dummy...) \
3044 __sc_0 = __NR_##name
3045 #undef LSS_LOADARGS_1
3046 #define LSS_LOADARGS_1(name, arg1) \
3047 LSS_LOADARGS_0(name); \
3048 __sc_3 = (unsigned long) (arg1)
3049 #undef LSS_LOADARGS_2
3050 #define LSS_LOADARGS_2(name, arg1, arg2) \
3051 LSS_LOADARGS_1(name, arg1); \
3052 __sc_4 = (unsigned long) (arg2)
3053 #undef LSS_LOADARGS_3
3054 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
3055 LSS_LOADARGS_2(name, arg1, arg2); \
3056 __sc_5 = (unsigned long) (arg3)
3057 #undef LSS_LOADARGS_4
3058 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
3059 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
3060 __sc_6 = (unsigned long) (arg4)
3061 #undef LSS_LOADARGS_5
3062 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
3063 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
3064 __sc_7 = (unsigned long) (arg5)
3065 #undef LSS_LOADARGS_6
3066 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
3067 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
3068 __sc_8 = (unsigned long) (arg6)
3069 #undef LSS_ASMINPUT_0
3070 #define LSS_ASMINPUT_0 "0" (__sc_0)
3071 #undef LSS_ASMINPUT_1
3072 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
3073 #undef LSS_ASMINPUT_2
3074 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
3075 #undef LSS_ASMINPUT_3
3076 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
3077 #undef LSS_ASMINPUT_4
3078 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
3079 #undef LSS_ASMINPUT_5
3080 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
3081 #undef LSS_ASMINPUT_6
3082 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
3083 #undef LSS_BODY
3084 #define LSS_BODY(nr, type, name, args...) \
3085 long __sc_ret, __sc_err; \
3086 { \
3087 register unsigned long __sc_0 __asm__ ("r0"); \
3088 register unsigned long __sc_3 __asm__ ("r3"); \
3089 register unsigned long __sc_4 __asm__ ("r4"); \
3090 register unsigned long __sc_5 __asm__ ("r5"); \
3091 register unsigned long __sc_6 __asm__ ("r6"); \
3092 register unsigned long __sc_7 __asm__ ("r7"); \
3093 register unsigned long __sc_8 __asm__ ("r8"); \
3094 \
3095 LSS_LOADARGS_##nr(name, args); \
3096 __asm__ __volatile__ \
3097 ("sc\n\t" \
3098 "mfcr %0" \
3099 : "=&r" (__sc_0), \
3100 "=&r" (__sc_3), "=&r" (__sc_4), \
3101 "=&r" (__sc_5), "=&r" (__sc_6), \
3102 "=&r" (__sc_7), "=&r" (__sc_8) \
3103 : LSS_ASMINPUT_##nr \
3104 : "cr0", "ctr", "memory", \
3105 "r9", "r10", "r11", "r12"); \
3106 __sc_ret = __sc_3; \
3107 __sc_err = __sc_0; \
3108 } \
3109 LSS_RETURN(type, __sc_ret, __sc_err)
3110 #undef _syscall0
3111 #define _syscall0(type, name) \
3112 type LSS_NAME(name)(void) { \
3113 LSS_BODY(0, type, name); \
3114 }
3115 #undef _syscall1
3116 #define _syscall1(type, name, type1, arg1) \
3117 type LSS_NAME(name)(type1 arg1) { \
3118 LSS_BODY(1, type, name, arg1); \
3119 }
3120 #undef _syscall2
3121 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3122 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3123 LSS_BODY(2, type, name, arg1, arg2); \
3124 }
3125 #undef _syscall3
3126 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3127 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3128 LSS_BODY(3, type, name, arg1, arg2, arg3); \
3129 }
3130 #undef _syscall4
3131 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3132 type4, arg4) \
3133 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
3134 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
3135 }
3136 #undef _syscall5
3137 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3138 type4, arg4, type5, arg5) \
3139 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3140 type5 arg5) { \
3141 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
3142 }
3143 #undef _syscall6
3144 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3145 type4, arg4, type5, arg5, type6, arg6) \
3146 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
3147 type5 arg5, type6 arg6) { \
3148 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
3149 }
3150 /* clone function adapted from glibc 2.3.6 clone.S */
3151 /* TODO(csilvers): consider wrapping some args up in a struct, like we
3152 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
3153 */
3154 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3155 int flags, void *arg, int *parent_tidptr,
3156 void *newtls, int *child_tidptr) {
3157 long __ret, __err;
3158 {
3159 register int (*__fn)(void *) __asm__ ("r8") = fn;
3160 register void *__cstack __asm__ ("r4") = child_stack;
3161 register int __flags __asm__ ("r3") = flags;
3162 register void * __arg __asm__ ("r9") = arg;
3163 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
3164 register void * __newtls __asm__ ("r6") = newtls;
3165 register int * __ctidptr __asm__ ("r7") = child_tidptr;
3166 __asm__ __volatile__(
3167 /* check for fn == NULL
3168 * and child_stack == NULL
3169 */
3170 "cmpwi cr0, %6, 0\n\t"
3171 "cmpwi cr1, %7, 0\n\t"
3172 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
3173 "beq- cr0, 1f\n\t"
3174
3175 /* set up stack frame for child */
3176 "clrrwi %7, %7, 4\n\t"
3177 "li 0, 0\n\t"
3178 "stwu 0, -16(%7)\n\t"
3179
3180 /* fn, arg, child_stack are saved across the syscall: r28-30 */
3181 "mr 28, %6\n\t"
3182 "mr 29, %7\n\t"
3183 "mr 27, %9\n\t"
3184
3185 /* syscall */
3186 "li 0, %4\n\t"
3187 /* flags already in r3
3188 * child_stack already in r4
3189 * ptidptr already in r5
3190 * newtls already in r6
3191 * ctidptr already in r7
3192 */
3193 "sc\n\t"
3194
3195 /* Test if syscall was successful */
3196 "cmpwi cr1, 3, 0\n\t"
3197 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
3198 "bne- cr1, 1f\n\t"
3199
3200 /* Do the function call */
3201 "mtctr 28\n\t"
3202 "mr 3, 27\n\t"
3203 "bctrl\n\t"
3204
3205 /* Call _exit(r3) */
3206 "li 0, %5\n\t"
3207 "sc\n\t"
3208
3209 /* Return to parent */
3210 "1:\n"
3211 "mfcr %1\n\t"
3212 "mr %0, 3\n\t"
3213 : "=r" (__ret), "=r" (__err)
3214 : "0" (-1), "1" (EINVAL),
3215 "i" (__NR_clone), "i" (__NR_exit),
3216 "r" (__fn), "r" (__cstack), "r" (__flags),
3217 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
3218 "r" (__ctidptr)
3219 : "cr0", "cr1", "memory", "ctr",
3220 "r0", "r29", "r27", "r28");
3221 }
3222 LSS_RETURN(int, __ret, __err);
3223 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003224 #elif defined(__s390__)
3225 #undef LSS_REG
3226 #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
3227 #undef LSS_BODY
3228 #define LSS_BODY(type, name, args...) \
3229 register unsigned long __nr __asm__("r1") \
3230 = (unsigned long)(__NR_##name); \
3231 register long __res_r2 __asm__("r2"); \
3232 long __res; \
3233 __asm__ __volatile__ \
3234 ("svc 0\n\t" \
3235 : "=d"(__res_r2) \
3236 : "d"(__nr), ## args \
3237 : "memory"); \
3238 __res = __res_r2; \
3239 LSS_RETURN(type, __res)
3240 #undef _syscall0
3241 #define _syscall0(type, name) \
3242 type LSS_NAME(name)(void) { \
3243 LSS_BODY(type, name); \
3244 }
3245 #undef _syscall1
3246 #define _syscall1(type, name, type1, arg1) \
3247 type LSS_NAME(name)(type1 arg1) { \
3248 LSS_REG(2, arg1); \
3249 LSS_BODY(type, name, "0"(__r2)); \
3250 }
3251 #undef _syscall2
3252 #define _syscall2(type, name, type1, arg1, type2, arg2) \
3253 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
3254 LSS_REG(2, arg1); LSS_REG(3, arg2); \
3255 LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \
3256 }
3257 #undef _syscall3
3258 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
3259 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
3260 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3261 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \
3262 }
3263 #undef _syscall4
3264 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
3265 type4, arg4) \
3266 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3267 type4 arg4) { \
3268 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3269 LSS_REG(5, arg4); \
3270 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3271 "d"(__r5)); \
3272 }
3273 #undef _syscall5
3274 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
3275 type4, arg4, type5, arg5) \
3276 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3277 type4 arg4, type5 arg5) { \
3278 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3279 LSS_REG(5, arg4); LSS_REG(6, arg5); \
3280 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3281 "d"(__r5), "d"(__r6)); \
3282 }
3283 #undef _syscall6
3284 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
3285 type4, arg4, type5, arg5, type6, arg6) \
3286 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \
3287 type4 arg4, type5 arg5, type6 arg6) { \
3288 LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \
3289 LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \
3290 LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \
3291 "d"(__r5), "d"(__r6), "d"(__r7)); \
3292 }
3293 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
3294 int flags, void *arg, int *parent_tidptr,
3295 void *newtls, int *child_tidptr) {
3296 long __ret;
3297 {
3298 register int (*__fn)(void *) __asm__ ("r1") = fn;
3299 register void *__cstack __asm__ ("r2") = child_stack;
3300 register int __flags __asm__ ("r3") = flags;
3301 register void *__arg __asm__ ("r0") = arg;
3302 register int *__ptidptr __asm__ ("r4") = parent_tidptr;
3303 register void *__newtls __asm__ ("r6") = newtls;
3304 register int *__ctidptr __asm__ ("r5") = child_tidptr;
3305 __asm__ __volatile__ (
3306 #ifndef __s390x__
3307 /* arg already in r0 */
3308 "ltr %4, %4\n\t" /* check fn, which is already in r1 */
3309 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3310 "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */
3311 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3312 /* flags already in r3 */
3313 /* parent_tidptr already in r4 */
3314 /* child_tidptr already in r5 */
3315 /* newtls already in r6 */
3316 "svc %2\n\t" /* invoke clone syscall */
3317 "ltr %0,%%r2\n\t" /* load return code into __ret and test */
3318 "jnz 1f\n\t" /* return to parent if non-zero */
3319 /* start child thread */
3320 "lr %%r2, %7\n\t" /* set first parameter to void *arg */
3321 "ahi %%r15, -96\n\t" /* make room on the stack for the save area */
3322 "xc 0(4,%%r15), 0(%%r15)\n\t"
3323 "basr %%r14, %4\n\t" /* jump to fn */
3324 "svc %3\n" /* invoke exit syscall */
3325 "1:\n"
3326 #else
3327 /* arg already in r0 */
3328 "ltgr %4, %4\n\t" /* check fn, which is already in r1 */
3329 "jz 1f\n\t" /* NULL function pointer, return -EINVAL */
3330 "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */
3331 "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */
3332 /* flags already in r3 */
3333 /* parent_tidptr already in r4 */
3334 /* child_tidptr already in r5 */
3335 /* newtls already in r6 */
3336 "svc %2\n\t" /* invoke clone syscall */
3337 "ltgr %0, %%r2\n\t" /* load return code into __ret and test */
3338 "jnz 1f\n\t" /* return to parent if non-zero */
3339 /* start child thread */
3340 "lgr %%r2, %7\n\t" /* set first parameter to void *arg */
3341 "aghi %%r15, -160\n\t" /* make room on the stack for the save area */
3342 "xc 0(8,%%r15), 0(%%r15)\n\t"
3343 "basr %%r14, %4\n\t" /* jump to fn */
3344 "svc %3\n" /* invoke exit syscall */
3345 "1:\n"
3346 #endif
3347 : "=r" (__ret)
3348 : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
3349 "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
3350 "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
3351 : "cc", "r14", "memory"
3352 );
3353 }
3354 LSS_RETURN(int, __ret);
3355 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003356 #endif
3357 #define __NR__exit __NR_exit
3358 #define __NR__gettid __NR_gettid
3359 #define __NR__mremap __NR_mremap
phosek@chromium.orga9c02722013-08-16 17:31:42 +00003360 LSS_INLINE _syscall1(void *, brk, void *, e)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003361 LSS_INLINE _syscall1(int, chdir, const char *,p)
3362 LSS_INLINE _syscall1(int, close, int, f)
3363 LSS_INLINE _syscall2(int, clock_getres, int, c,
3364 struct kernel_timespec*, t)
3365 LSS_INLINE _syscall2(int, clock_gettime, int, c,
3366 struct kernel_timespec*, t)
3367 LSS_INLINE _syscall1(int, dup, int, f)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003368 #if defined(__NR_dup2)
3369 // dup2 is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003370 LSS_INLINE _syscall2(int, dup2, int, s,
3371 int, d)
3372 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003373 #if defined(__NR_dup3)
3374 LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
3375 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003376 LSS_INLINE _syscall3(int, execve, const char*, f,
3377 const char*const*,a,const char*const*, e)
3378 LSS_INLINE _syscall1(int, _exit, int, e)
3379 LSS_INLINE _syscall1(int, exit_group, int, e)
3380 LSS_INLINE _syscall3(int, fcntl, int, f,
3381 int, c, long, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003382 #if defined(__NR_fork)
3383 // fork is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003384 LSS_INLINE _syscall0(pid_t, fork)
3385 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003386 LSS_INLINE _syscall2(int, fstat, int, f,
3387 struct kernel_stat*, b)
3388 LSS_INLINE _syscall2(int, fstatfs, int, f,
3389 struct kernel_statfs*, b)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003390 #if defined(__x86_64__)
3391 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3392 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) {
3393 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l));
3394 }
3395 #else
3396 LSS_INLINE _syscall2(int, ftruncate, int, f,
3397 off_t, l)
3398 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003399 LSS_INLINE _syscall4(int, futex, int*, a,
3400 int, o, int, v,
3401 struct kernel_timespec*, t)
3402 LSS_INLINE _syscall3(int, getdents, int, f,
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003403 struct kernel_dirent*, d, int, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003404 LSS_INLINE _syscall3(int, getdents64, int, f,
3405 struct kernel_dirent64*, d, int, c)
3406 LSS_INLINE _syscall0(gid_t, getegid)
3407 LSS_INLINE _syscall0(uid_t, geteuid)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003408 #if defined(__NR_getpgrp)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003409 LSS_INLINE _syscall0(pid_t, getpgrp)
3410 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003411 LSS_INLINE _syscall0(pid_t, getpid)
3412 LSS_INLINE _syscall0(pid_t, getppid)
3413 LSS_INLINE _syscall2(int, getpriority, int, a,
3414 int, b)
3415 LSS_INLINE _syscall3(int, getresgid, gid_t *, r,
3416 gid_t *, e, gid_t *, s)
3417 LSS_INLINE _syscall3(int, getresuid, uid_t *, r,
3418 uid_t *, e, uid_t *, s)
3419#if !defined(__ARM_EABI__)
3420 LSS_INLINE _syscall2(int, getrlimit, int, r,
3421 struct kernel_rlimit*, l)
3422#endif
3423 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
3424 LSS_INLINE _syscall0(pid_t, _gettid)
3425 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
3426 void*, tz)
3427 LSS_INLINE _syscall5(int, setxattr, const char *,p,
3428 const char *, n, const void *,v,
3429 size_t, s, int, f)
3430 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
3431 const char *, n, const void *,v,
3432 size_t, s, int, f)
3433 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
3434 const char *, n, void *, v, size_t, s)
3435 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
3436 const char *, n, void *, v, size_t, s)
3437 LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p,
3438 char *, l, size_t, s)
3439 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p,
3440 char *, l, size_t, s)
3441 LSS_INLINE _syscall3(int, ioctl, int, d,
3442 int, r, void *, a)
3443 LSS_INLINE _syscall2(int, ioprio_get, int, which,
3444 int, who)
3445 LSS_INLINE _syscall3(int, ioprio_set, int, which,
3446 int, who, int, ioprio)
3447 LSS_INLINE _syscall2(int, kill, pid_t, p,
3448 int, s)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003449 #if defined(__x86_64__)
3450 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
3451 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
3452 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
3453 LSS_SYSCALL_ARG(w));
3454 }
3455 #else
3456 LSS_INLINE _syscall3(off_t, lseek, int, f,
3457 off_t, o, int, w)
3458 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003459 LSS_INLINE _syscall2(int, munmap, void*, s,
3460 size_t, l)
3461 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
3462 unsigned long, n, void **,g, int *, d,
3463 int *, s, int, f)
3464 LSS_INLINE _syscall3(int, mprotect, const void *,a,
3465 size_t, l, int, p)
3466 LSS_INLINE _syscall5(void*, _mremap, void*, o,
3467 size_t, os, size_t, ns,
3468 unsigned long, f, void *, a)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003469 #if defined(__NR_open)
3470 // open is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003471 LSS_INLINE _syscall3(int, open, const char*, p,
3472 int, f, int, m)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003473 #endif
3474 #if defined(__NR_poll)
3475 // poll is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003476 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
3477 unsigned int, n, int, t)
3478 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003479 #if defined(__NR_ppoll)
3480 LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
3481 unsigned int, n, const struct kernel_timespec *, t,
3482 const struct kernel_sigset_t *, sigmask, size_t, s)
3483 #endif
mseaborn@chromium.orge6c76822013-08-31 00:08:44 +00003484 LSS_INLINE _syscall5(int, prctl, int, option,
3485 unsigned long, arg2,
3486 unsigned long, arg3,
3487 unsigned long, arg4,
3488 unsigned long, arg5)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003489 LSS_INLINE _syscall4(long, ptrace, int, r,
3490 pid_t, p, void *, a, void *, d)
3491 #if defined(__NR_quotactl)
3492 // Defined on x86_64 / i386 only
3493 LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special,
3494 int, id, caddr_t, addr)
3495 #endif
3496 LSS_INLINE _syscall3(ssize_t, read, int, f,
3497 void *, b, size_t, c)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003498 #if defined(__NR_readlink)
3499 // readlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003500 LSS_INLINE _syscall3(int, readlink, const char*, p,
3501 char*, b, size_t, s)
3502 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003503 #if defined(__NR_readlinkat)
3504 LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
3505 size_t, s)
3506 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003507 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
3508 const struct kernel_sigaction*, a,
3509 struct kernel_sigaction*, o, size_t, c)
3510 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
3511 size_t, c)
3512 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
3513 const struct kernel_sigset_t*, s,
3514 struct kernel_sigset_t*, o, size_t, c)
3515 LSS_INLINE _syscall2(int, rt_sigsuspend,
3516 const struct kernel_sigset_t*, s, size_t, c)
Joshua Peraza726d71e2019-11-13 12:21:13 -08003517 LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s,
3518 siginfo_t*, i, const struct timespec*, t, size_t, c)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003519 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
3520 unsigned int, l, unsigned long *, m)
3521 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
3522 unsigned int, l, unsigned long *, m)
3523 LSS_INLINE _syscall0(int, sched_yield)
3524 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
3525 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
3526 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
3527 LSS_INLINE _syscall1(int, setuid, uid_t, u)
3528 LSS_INLINE _syscall1(int, setgid, gid_t, g)
3529 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
3530 pid_t, g)
3531 LSS_INLINE _syscall3(int, setpriority, int, a,
3532 int, b, int, p)
3533 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
3534 gid_t, e, gid_t, s)
3535 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
3536 uid_t, e, uid_t, s)
3537 LSS_INLINE _syscall2(int, setrlimit, int, r,
3538 const struct kernel_rlimit*, l)
3539 LSS_INLINE _syscall0(pid_t, setsid)
3540 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
3541 const stack_t*, o)
3542 #if defined(__NR_sigreturn)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003543 LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003544 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003545 #if defined(__NR_stat)
3546 // stat is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003547 LSS_INLINE _syscall2(int, stat, const char*, f,
3548 struct kernel_stat*, b)
3549 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003550 LSS_INLINE _syscall2(int, statfs, const char*, f,
3551 struct kernel_statfs*, b)
3552 LSS_INLINE _syscall3(int, tgkill, pid_t, p,
3553 pid_t, t, int, s)
3554 LSS_INLINE _syscall2(int, tkill, pid_t, p,
3555 int, s)
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003556 #if defined(__NR_unlink)
3557 // unlink is polyfilled below when not available.
anton@chromium.org2f724fc2014-04-15 13:05:20 +00003558 LSS_INLINE _syscall1(int, unlink, const char*, f)
3559 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003560 LSS_INLINE _syscall3(ssize_t, write, int, f,
3561 const void *, b, size_t, c)
3562 LSS_INLINE _syscall3(ssize_t, writev, int, f,
3563 const struct kernel_iovec*, v, size_t, c)
3564 #if defined(__NR_getcpu)
3565 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
zodiac@gmail.comdb39de92010-12-10 00:22:03 +00003566 unsigned *, node, void *, unused)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003567 #endif
3568 #if defined(__x86_64__) || \
3569 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
3570 LSS_INLINE _syscall3(int, recvmsg, int, s,
3571 struct kernel_msghdr*, m, int, f)
3572 LSS_INLINE _syscall3(int, sendmsg, int, s,
3573 const struct kernel_msghdr*, m, int, f)
3574 LSS_INLINE _syscall6(int, sendto, int, s,
3575 const void*, m, size_t, l,
3576 int, f,
3577 const struct kernel_sockaddr*, a, int, t)
3578 LSS_INLINE _syscall2(int, shutdown, int, s,
3579 int, h)
3580 LSS_INLINE _syscall3(int, socket, int, d,
3581 int, t, int, p)
3582 LSS_INLINE _syscall4(int, socketpair, int, d,
3583 int, t, int, p, int*, s)
3584 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003585 #if defined(__NR_fadvise64)
3586 #if defined(__x86_64__)
3587 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3588 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len,
3589 int advice) {
3590 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset),
3591 (uint64_t)(len), LSS_SYSCALL_ARG(advice));
3592 }
3593 #else
3594 LSS_INLINE _syscall4(int, fadvise64,
3595 int, fd, loff_t, offset, loff_t, len, int, advice)
3596 #endif
3597 #elif defined(__i386__)
3598 #define __NR__fadvise64_64 __NR_fadvise64_64
3599 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
3600 unsigned, offset_lo, unsigned, offset_hi,
3601 unsigned, len_lo, unsigned, len_hi,
3602 int, advice)
3603
3604 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
3605 loff_t len, int advice) {
3606 return LSS_NAME(_fadvise64_64)(fd,
3607 (unsigned)offset, (unsigned)(offset >>32),
3608 (unsigned)len, (unsigned)(len >> 32),
3609 advice);
3610 }
3611
3612 #elif defined(__s390__) && !defined(__s390x__)
3613 #define __NR__fadvise64_64 __NR_fadvise64_64
3614 struct kernel_fadvise64_64_args {
3615 int fd;
3616 long long offset;
3617 long long len;
3618 int advice;
3619 };
3620
3621 LSS_INLINE _syscall1(int, _fadvise64_64,
3622 struct kernel_fadvise64_64_args *args)
3623
3624 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
3625 loff_t len, int advice) {
3626 struct kernel_fadvise64_64_args args = { fd, offset, len, advice };
3627 return LSS_NAME(_fadvise64_64)(&args);
3628 }
3629 #endif
3630 #if defined(__NR_fallocate)
3631 #if defined(__x86_64__)
vapier@chromium.org2273e812013-04-01 17:52:44 +00003632 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
3633 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset,
3634 loff_t len) {
3635 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode),
3636 (uint64_t)(offset), (uint64_t)(len));
3637 }
Joshua Peraza7bde79c2019-12-05 11:36:48 -08003638 #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \
3639 || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \
3640 || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \
3641 || defined(__PPC__))
Bryan Chan3f6478a2016-06-14 08:38:17 -04003642 #define __NR__fallocate __NR_fallocate
3643 LSS_INLINE _syscall6(int, _fallocate, int, fd,
3644 int, mode,
3645 unsigned, offset_lo, unsigned, offset_hi,
3646 unsigned, len_lo, unsigned, len_hi)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003647
Bryan Chan3f6478a2016-06-14 08:38:17 -04003648 LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
3649 loff_t offset, loff_t len) {
3650 union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
3651 return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
3652 }
3653 #else
3654 LSS_INLINE _syscall4(int, fallocate,
3655 int, f, int, mode, loff_t, offset, loff_t, len)
3656 #endif
3657 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003658 #if defined(__NR_newfstatat)
3659 LSS_INLINE _syscall4(int, newfstatat, int, d,
3660 const char *, p,
3661 struct kernel_stat*, b, int, f)
3662 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003663 #if defined(__x86_64__) || defined(__s390x__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003664 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3665 gid_t *egid,
3666 gid_t *sgid) {
3667 return LSS_NAME(getresgid)(rgid, egid, sgid);
3668 }
3669
3670 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3671 uid_t *euid,
3672 uid_t *suid) {
3673 return LSS_NAME(getresuid)(ruid, euid, suid);
3674 }
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003675
3676 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3677 return LSS_NAME(setfsgid)(gid);
3678 }
3679
3680 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3681 return LSS_NAME(setfsuid)(uid);
3682 }
3683
3684 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3685 return LSS_NAME(setresgid)(rgid, egid, sgid);
3686 }
3687
3688 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3689 return LSS_NAME(setresuid)(ruid, euid, suid);
3690 }
3691
3692 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3693 const struct kernel_sigaction *act,
3694 struct kernel_sigaction *oldact) {
Bryan Chan3f6478a2016-06-14 08:38:17 -04003695 #if defined(__x86_64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003696 /* On x86_64, the kernel requires us to always set our own
3697 * SA_RESTORER in order to be able to return from a signal handler.
3698 * This function must have a "magic" signature that the "gdb"
3699 * (and maybe the kernel?) can recognize.
3700 */
3701 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
3702 struct kernel_sigaction a = *act;
3703 a.sa_flags |= SA_RESTORER;
3704 a.sa_restorer = LSS_NAME(restore_rt)();
3705 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
3706 (KERNEL_NSIG+7)/8);
Bryan Chan3f6478a2016-06-14 08:38:17 -04003707 } else
3708 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003709 return LSS_NAME(rt_sigaction)(signum, act, oldact,
3710 (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003711 }
3712
3713 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
3714 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
3715 }
3716
Joshua Peraza726d71e2019-11-13 12:21:13 -08003717 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
3718 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
3719 }
3720 #endif
3721 #if defined(__NR_rt_sigprocmask)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003722 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
3723 const struct kernel_sigset_t *set,
3724 struct kernel_sigset_t *oldset) {
3725 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
3726 }
Joshua Peraza726d71e2019-11-13 12:21:13 -08003727 #endif
3728 #if defined(__NR_rt_sigtimedwait)
3729 LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set,
3730 siginfo_t *info,
3731 const struct timespec *timeout) {
3732 return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003733 }
3734 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04003735 #if defined(__NR_wait4)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003736 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
3737 int*, s, int, o,
3738 struct kernel_rusage*, r)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003739 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003740 #if defined(__NR_openat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003741 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
Bryan Chan3f6478a2016-06-14 08:38:17 -04003742 #endif
3743 #if defined(__NR_unlinkat)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003744 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
3745 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04003746 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
3747 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003748 #define __NR__getresgid32 __NR_getresgid32
3749 #define __NR__getresuid32 __NR_getresuid32
3750 #define __NR__setfsgid32 __NR_setfsgid32
3751 #define __NR__setfsuid32 __NR_setfsuid32
3752 #define __NR__setresgid32 __NR_setresgid32
3753 #define __NR__setresuid32 __NR_setresuid32
3754#if defined(__ARM_EABI__)
3755 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
3756 struct kernel_rlimit*, l)
3757#endif
3758 LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r,
3759 gid_t *, e, gid_t *, s)
3760 LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r,
3761 uid_t *, e, uid_t *, s)
3762 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
3763 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
3764 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
3765 gid_t, e, gid_t, s)
3766 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
3767 uid_t, e, uid_t, s)
3768
3769 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid,
3770 gid_t *egid,
3771 gid_t *sgid) {
3772 int rc;
3773 if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 &&
3774 LSS_ERRNO == ENOSYS) {
3775 if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) {
3776 return EFAULT;
3777 }
3778 // Clear the high bits first, since getresgid only sets 16 bits
3779 *rgid = *egid = *sgid = 0;
3780 rc = LSS_NAME(getresgid)(rgid, egid, sgid);
3781 }
3782 return rc;
3783 }
3784
3785 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid,
3786 uid_t *euid,
3787 uid_t *suid) {
3788 int rc;
3789 if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 &&
3790 LSS_ERRNO == ENOSYS) {
3791 if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) {
3792 return EFAULT;
3793 }
3794 // Clear the high bits first, since getresuid only sets 16 bits
3795 *ruid = *euid = *suid = 0;
3796 rc = LSS_NAME(getresuid)(ruid, euid, suid);
3797 }
3798 return rc;
3799 }
3800
3801 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
3802 int rc;
3803 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
3804 LSS_ERRNO == ENOSYS) {
3805 if ((unsigned int)gid & ~0xFFFFu) {
3806 rc = EINVAL;
3807 } else {
3808 rc = LSS_NAME(setfsgid)(gid);
3809 }
3810 }
3811 return rc;
3812 }
3813
3814 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
3815 int rc;
3816 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
3817 LSS_ERRNO == ENOSYS) {
3818 if ((unsigned int)uid & ~0xFFFFu) {
3819 rc = EINVAL;
3820 } else {
3821 rc = LSS_NAME(setfsuid)(uid);
3822 }
3823 }
3824 return rc;
3825 }
3826
3827 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
3828 int rc;
3829 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
3830 LSS_ERRNO == ENOSYS) {
3831 if ((unsigned int)rgid & ~0xFFFFu ||
3832 (unsigned int)egid & ~0xFFFFu ||
3833 (unsigned int)sgid & ~0xFFFFu) {
3834 rc = EINVAL;
3835 } else {
3836 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
3837 }
3838 }
3839 return rc;
3840 }
3841
3842 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
3843 int rc;
3844 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
3845 LSS_ERRNO == ENOSYS) {
3846 if ((unsigned int)ruid & ~0xFFFFu ||
3847 (unsigned int)euid & ~0xFFFFu ||
3848 (unsigned int)suid & ~0xFFFFu) {
3849 rc = EINVAL;
3850 } else {
3851 rc = LSS_NAME(setresuid)(ruid, euid, suid);
3852 }
3853 }
3854 return rc;
3855 }
3856 #endif
3857 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
3858 memset(&set->sig, 0, sizeof(set->sig));
3859 return 0;
3860 }
3861
3862 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
3863 memset(&set->sig, -1, sizeof(set->sig));
3864 return 0;
3865 }
3866
3867 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
3868 int signum) {
3869 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3870 LSS_ERRNO = EINVAL;
3871 return -1;
3872 } else {
3873 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3874 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
3875 return 0;
3876 }
3877 }
3878
3879 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
3880 int signum) {
3881 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3882 LSS_ERRNO = EINVAL;
3883 return -1;
3884 } else {
3885 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
3886 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
3887 return 0;
3888 }
3889 }
mcgrathr@google.coma7999932011-11-21 22:26:20 +00003890
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003891 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
3892 int signum) {
3893 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
3894 LSS_ERRNO = EINVAL;
3895 return -1;
3896 } else {
3897 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] &
3898 (1UL << ((signum - 1) % (8*sizeof(set->sig[0])))));
3899 }
3900 }
Bryan Chan3f6478a2016-06-14 08:38:17 -04003901 #if defined(__i386__) || \
3902 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
3903 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
3904 defined(__PPC__) || \
3905 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003906 #define __NR__sigaction __NR_sigaction
3907 #define __NR__sigpending __NR_sigpending
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003908 #define __NR__sigsuspend __NR_sigsuspend
3909 #define __NR__socketcall __NR_socketcall
3910 LSS_INLINE _syscall2(int, fstat64, int, f,
3911 struct kernel_stat64 *, b)
zodiac@gmail.com4f470182010-10-13 03:47:54 +00003912 LSS_INLINE _syscall5(int, _llseek, uint, fd,
3913 unsigned long, hi, unsigned long, lo,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003914 loff_t *, res, uint, wh)
Bryan Chan3f6478a2016-06-14 08:38:17 -04003915#if defined(__s390__) && !defined(__s390x__)
3916 /* On s390, mmap2() arguments are passed in memory. */
3917 LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
3918 off_t o) {
3919 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
3920 (unsigned long) p, (unsigned long) f,
3921 (unsigned long) d, (unsigned long) o };
3922 LSS_REG(2, buf);
3923 LSS_BODY(void*, mmap2, "0"(__r2));
3924 }
3925#else
3926 #define __NR__mmap2 __NR_mmap2
3927 LSS_INLINE _syscall6(void*, _mmap2, void*, s,
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003928 size_t, l, int, p,
3929 int, f, int, d,
Bryan Chan3f6478a2016-06-14 08:38:17 -04003930 off_t, o)
3931#endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003932 LSS_INLINE _syscall3(int, _sigaction, int, s,
3933 const struct kernel_old_sigaction*, a,
3934 struct kernel_old_sigaction*, o)
3935 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00003936 #ifdef __PPC__
3937 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
3938 #else
3939 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
3940 int, b,
3941 unsigned long, s)
3942 #endif
3943 LSS_INLINE _syscall2(int, stat64, const char *, p,
3944 struct kernel_stat64 *, b)
3945
3946 LSS_INLINE int LSS_NAME(sigaction)(int signum,
3947 const struct kernel_sigaction *act,
3948 struct kernel_sigaction *oldact) {
3949 int old_errno = LSS_ERRNO;
3950 int rc;
3951 struct kernel_sigaction a;
3952 if (act != NULL) {
3953 a = *act;
3954 #ifdef __i386__
3955 /* On i386, the kernel requires us to always set our own
3956 * SA_RESTORER when using realtime signals. Otherwise, it does not
3957 * know how to return from a signal handler. This function must have
3958 * a "magic" signature that the "gdb" (and maybe the kernel?) can
3959 * recognize.
3960 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
3961 * using non-realtime signals.
3962 *
3963 * TODO: Test whether ARM needs a restorer
3964 */
3965 if (!(a.sa_flags & SA_RESTORER)) {
3966 a.sa_flags |= SA_RESTORER;
3967 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
3968 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
3969 }
3970 #endif
3971 }
3972 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
3973 (KERNEL_NSIG+7)/8);
3974 if (rc < 0 && LSS_ERRNO == ENOSYS) {
3975 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
3976 if (!act) {
3977 ptr_a = NULL;
3978 } else {
3979 oa.sa_handler_ = act->sa_handler_;
3980 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
3981 #ifndef __mips__
3982 oa.sa_restorer = act->sa_restorer;
3983 #endif
3984 oa.sa_flags = act->sa_flags;
3985 }
3986 if (!oldact) {
3987 ptr_oa = NULL;
3988 }
3989 LSS_ERRNO = old_errno;
3990 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
3991 if (rc == 0 && oldact) {
3992 if (act) {
3993 memcpy(oldact, act, sizeof(*act));
3994 } else {
3995 memset(oldact, 0, sizeof(*oldact));
3996 }
3997 oldact->sa_handler_ = ptr_oa->sa_handler_;
3998 oldact->sa_flags = ptr_oa->sa_flags;
3999 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
4000 #ifndef __mips__
4001 oldact->sa_restorer = ptr_oa->sa_restorer;
4002 #endif
4003 }
4004 }
4005 return rc;
4006 }
4007
4008 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
4009 int old_errno = LSS_ERRNO;
4010 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
4011 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4012 LSS_ERRNO = old_errno;
4013 LSS_NAME(sigemptyset)(set);
4014 rc = LSS_NAME(_sigpending)(&set->sig[0]);
4015 }
4016 return rc;
4017 }
4018
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004019 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
4020 int olderrno = LSS_ERRNO;
4021 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
4022 if (rc < 0 && LSS_ERRNO == ENOSYS) {
4023 LSS_ERRNO = olderrno;
4024 rc = LSS_NAME(_sigsuspend)(
4025 #ifndef __PPC__
4026 set, 0,
4027 #endif
4028 set->sig[0]);
4029 }
4030 return rc;
4031 }
4032 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004033 #if defined(__i386__) || \
4034 defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
4035 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4036 defined(__PPC__) || \
4037 (defined(__s390__) && !defined(__s390x__))
4038 /* On these architectures, implement mmap() with mmap2(). */
4039 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4040 int64_t o) {
4041 if (o % 4096) {
4042 LSS_ERRNO = EINVAL;
4043 return (void *) -1;
4044 }
4045 return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
4046 }
4047 #elif defined(__s390x__)
4048 /* On s390x, mmap() arguments are passed in memory. */
4049 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4050 int64_t o) {
4051 unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
4052 (unsigned long) p, (unsigned long) f,
4053 (unsigned long) d, (unsigned long) o };
4054 LSS_REG(2, buf);
4055 LSS_BODY(void*, mmap, "0"(__r2));
4056 }
4057 #elif defined(__x86_64__)
4058 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
4059 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
4060 int64_t o) {
4061 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
4062 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
4063 LSS_SYSCALL_ARG(d), (uint64_t)(o));
4064 }
4065 #else
4066 /* Remaining 64-bit architectures. */
4067 LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
4068 int, flags, int, fd, int64_t, offset)
4069 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004070 #if defined(__PPC__)
4071 #undef LSS_SC_LOADARGS_0
4072 #define LSS_SC_LOADARGS_0(dummy...)
4073 #undef LSS_SC_LOADARGS_1
4074 #define LSS_SC_LOADARGS_1(arg1) \
4075 __sc_4 = (unsigned long) (arg1)
4076 #undef LSS_SC_LOADARGS_2
4077 #define LSS_SC_LOADARGS_2(arg1, arg2) \
4078 LSS_SC_LOADARGS_1(arg1); \
4079 __sc_5 = (unsigned long) (arg2)
4080 #undef LSS_SC_LOADARGS_3
4081 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
4082 LSS_SC_LOADARGS_2(arg1, arg2); \
4083 __sc_6 = (unsigned long) (arg3)
4084 #undef LSS_SC_LOADARGS_4
4085 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
4086 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
4087 __sc_7 = (unsigned long) (arg4)
4088 #undef LSS_SC_LOADARGS_5
4089 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
4090 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
4091 __sc_8 = (unsigned long) (arg5)
4092 #undef LSS_SC_BODY
4093 #define LSS_SC_BODY(nr, type, opt, args...) \
4094 long __sc_ret, __sc_err; \
4095 { \
4096 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
4097 register unsigned long __sc_3 __asm__ ("r3") = opt; \
4098 register unsigned long __sc_4 __asm__ ("r4"); \
4099 register unsigned long __sc_5 __asm__ ("r5"); \
4100 register unsigned long __sc_6 __asm__ ("r6"); \
4101 register unsigned long __sc_7 __asm__ ("r7"); \
4102 register unsigned long __sc_8 __asm__ ("r8"); \
4103 LSS_SC_LOADARGS_##nr(args); \
4104 __asm__ __volatile__ \
4105 ("stwu 1, -48(1)\n\t" \
4106 "stw 4, 20(1)\n\t" \
4107 "stw 5, 24(1)\n\t" \
4108 "stw 6, 28(1)\n\t" \
4109 "stw 7, 32(1)\n\t" \
4110 "stw 8, 36(1)\n\t" \
4111 "addi 4, 1, 20\n\t" \
4112 "sc\n\t" \
4113 "mfcr %0" \
4114 : "=&r" (__sc_0), \
4115 "=&r" (__sc_3), "=&r" (__sc_4), \
4116 "=&r" (__sc_5), "=&r" (__sc_6), \
4117 "=&r" (__sc_7), "=&r" (__sc_8) \
4118 : LSS_ASMINPUT_##nr \
4119 : "cr0", "ctr", "memory"); \
4120 __sc_ret = __sc_3; \
4121 __sc_err = __sc_0; \
4122 } \
4123 LSS_RETURN(type, __sc_ret, __sc_err)
4124
4125 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4126 int flags){
4127 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
4128 }
4129
4130 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4131 const struct kernel_msghdr *msg,
4132 int flags) {
4133 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
4134 }
4135
4136 // TODO(csilvers): why is this ifdef'ed out?
4137#if 0
4138 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4139 int flags,
4140 const struct kernel_sockaddr *to,
4141 unsigned int tolen) {
4142 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
4143 }
4144#endif
4145
4146 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4147 LSS_SC_BODY(2, int, 13, s, how);
4148 }
4149
4150 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4151 LSS_SC_BODY(3, int, 1, domain, type, protocol);
4152 }
4153
4154 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4155 int sv[2]) {
4156 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
4157 }
4158 #endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004159 #if defined(__ARM_EABI__) || defined (__aarch64__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004160 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
4161 int, flags)
4162 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
4163 msg, int, flags)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004164 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len,
4165 int, flags, const struct kernel_sockaddr*, to,
4166 unsigned int, tolen)
4167 LSS_INLINE _syscall2(int, shutdown, int, s, int, how)
4168 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol)
4169 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
4170 int*, sv)
4171 #endif
4172 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004173 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
4174 defined(__s390__)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004175 #define __NR__socketcall __NR_socketcall
4176 LSS_INLINE _syscall2(int, _socketcall, int, c,
4177 va_list, a)
4178 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
4179 int rc;
4180 va_list ap;
4181 va_start(ap, op);
4182 rc = LSS_NAME(_socketcall)(op, ap);
4183 va_end(ap);
4184 return rc;
4185 }
4186
4187 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
4188 int flags){
4189 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
4190 }
4191
4192 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
4193 const struct kernel_msghdr *msg,
4194 int flags) {
4195 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
4196 }
4197
4198 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
4199 int flags,
4200 const struct kernel_sockaddr *to,
4201 unsigned int tolen) {
4202 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
4203 }
4204
4205 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
4206 return LSS_NAME(socketcall)(13, s, how);
4207 }
4208
4209 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
4210 return LSS_NAME(socketcall)(1, domain, type, protocol);
4211 }
4212
4213 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
4214 int sv[2]) {
4215 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
4216 }
4217 #endif
Bryan Chan3f6478a2016-06-14 08:38:17 -04004218 #if defined(__NR_fstatat64)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004219 LSS_INLINE _syscall4(int, fstatat64, int, d,
4220 const char *, p,
4221 struct kernel_stat64 *, b, int, f)
4222 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004223 #if defined(__NR_waitpid)
4224 // waitpid is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004225 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
4226 int*, s, int, o)
4227 #endif
4228 #if defined(__mips__)
4229 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
4230 * both file handles through CPU registers.
4231 */
4232 LSS_INLINE int LSS_NAME(pipe)(int *p) {
4233 register unsigned long __v0 __asm__("$2") = __NR_pipe;
4234 register unsigned long __v1 __asm__("$3");
4235 register unsigned long __r7 __asm__("$7");
4236 __asm__ __volatile__ ("syscall\n"
vapier@chromium.orgda4a4892015-01-22 16:46:39 +00004237 : "=r"(__v0), "=r"(__v1), "=r" (__r7)
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004238 : "0"(__v0)
4239 : "$8", "$9", "$10", "$11", "$12",
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004240 "$13", "$14", "$15", "$24", "$25", "memory");
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004241 if (__r7) {
zodiac@gmail.coma6591482012-04-13 01:29:30 +00004242 unsigned long __errnovalue = __v0;
4243 LSS_ERRNO = __errnovalue;
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004244 return -1;
4245 } else {
4246 p[0] = __v0;
4247 p[1] = __v1;
4248 return 0;
4249 }
4250 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004251 #elif defined(__NR_pipe)
4252 // pipe is polyfilled below when not available.
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004253 LSS_INLINE _syscall1(int, pipe, int *, p)
4254 #endif
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004255 #if defined(__NR_pipe2)
4256 LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
4257 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004258 /* TODO(csilvers): see if ppc can/should support this as well */
4259 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
Bryan Chan3f6478a2016-06-14 08:38:17 -04004260 defined(__ARM_EABI__) || \
4261 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \
4262 (defined(__s390__) && !defined(__s390x__))
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004263 #define __NR__statfs64 __NR_statfs64
4264 #define __NR__fstatfs64 __NR_fstatfs64
4265 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
4266 size_t, s,struct kernel_statfs64*, b)
4267 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
4268 size_t, s,struct kernel_statfs64*, b)
4269 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
4270 struct kernel_statfs64 *b) {
4271 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
4272 }
4273 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
4274 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
4275 }
4276 #endif
4277
4278 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
4279 extern char **environ;
4280 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
4281 }
4282
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004283 LSS_INLINE pid_t LSS_NAME(gettid)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004284 pid_t tid = LSS_NAME(_gettid)();
4285 if (tid != -1) {
4286 return tid;
4287 }
4288 return LSS_NAME(getpid)();
4289 }
4290
4291 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
4292 size_t new_size, int flags, ...) {
4293 va_list ap;
4294 void *new_address, *rc;
4295 va_start(ap, flags);
4296 new_address = va_arg(ap, void *);
4297 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
4298 flags, new_address);
4299 va_end(ap);
4300 return rc;
4301 }
4302
4303 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
4304 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
4305 * then sends job control signals to the real parent, rather than to
4306 * the tracer. We reduce the risk of this happening by starting a
4307 * whole new time slice, and then quickly sending a SIGCONT signal
4308 * right after detaching from the tracee.
4309 *
4310 * We use tkill to ensure that we only issue a wakeup for the thread being
4311 * detached. Large multi threaded apps can take a long time in the kernel
4312 * processing SIGCONT.
4313 */
4314 int rc, err;
4315 LSS_NAME(sched_yield)();
4316 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
4317 err = LSS_ERRNO;
4318 LSS_NAME(tkill)(pid, SIGCONT);
4319 /* Old systems don't have tkill */
4320 if (LSS_ERRNO == ENOSYS)
4321 LSS_NAME(kill)(pid, SIGCONT);
4322 LSS_ERRNO = err;
4323 return rc;
4324 }
4325
4326 LSS_INLINE int LSS_NAME(raise)(int sig) {
4327 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
4328 }
4329
mseaborn@chromium.org8dce3582012-10-30 05:32:46 +00004330 LSS_INLINE int LSS_NAME(setpgrp)(void) {
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004331 return LSS_NAME(setpgid)(0, 0);
4332 }
4333
vapier@chromium.org2273e812013-04-01 17:52:44 +00004334 #if defined(__x86_64__)
4335 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */
4336 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) {
4337 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4338 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4339 }
4340
4341 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c,
4342 loff_t o) {
4343 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b),
4344 LSS_SYSCALL_ARG(c), (uint64_t)(o));
4345 }
4346
4347 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) {
4348 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o),
4349 LSS_SYSCALL_ARG(c));
4350 }
4351 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004352 LSS_INLINE _syscall4(ssize_t, pread64, int, f,
4353 void *, b, size_t, c,
4354 loff_t, o)
4355 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f,
4356 const void *, b, size_t, c,
4357 loff_t, o)
4358 LSS_INLINE _syscall3(int, readahead, int, f,
4359 loff_t, o, unsigned, c)
4360 #else
4361 #define __NR__pread64 __NR_pread64
4362 #define __NR__pwrite64 __NR_pwrite64
4363 #define __NR__readahead __NR_readahead
mseaborn@chromium.org2c73abf2012-09-15 03:46:48 +00004364 #if defined(__ARM_EABI__) || defined(__mips__)
4365 /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register
4366 * pair. Hence these calls ignore their fourth argument (r3) so that their
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004367 * fifth and sixth make such a pair (r4,r5).
4368 */
4369 #define LSS_LLARG_PAD 0,
4370 LSS_INLINE _syscall6(ssize_t, _pread64, int, f,
4371 void *, b, size_t, c,
4372 unsigned, skip, unsigned, o1, unsigned, o2)
4373 LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f,
4374 const void *, b, size_t, c,
4375 unsigned, skip, unsigned, o1, unsigned, o2)
4376 LSS_INLINE _syscall5(int, _readahead, int, f,
4377 unsigned, skip,
4378 unsigned, o1, unsigned, o2, size_t, c)
4379 #else
4380 #define LSS_LLARG_PAD
4381 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
4382 void *, b, size_t, c, unsigned, o1,
4383 unsigned, o2)
4384 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
4385 const void *, b, size_t, c, unsigned, o1,
4386 long, o2)
4387 LSS_INLINE _syscall4(int, _readahead, int, f,
4388 unsigned, o1, unsigned, o2, size_t, c)
4389 #endif
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004390 /* We force 64bit-wide parameters onto the stack, then access each
4391 * 32-bit component individually. This guarantees that we build the
4392 * correct parameters independent of the native byte-order of the
4393 * underlying architecture.
4394 */
4395 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
4396 loff_t off) {
4397 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004398 return LSS_NAME(_pread64)(fd, buf, count,
4399 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004400 }
4401 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
4402 size_t count, loff_t off) {
4403 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004404 return LSS_NAME(_pwrite64)(fd, buf, count,
4405 LSS_LLARG_PAD o.arg[0], o.arg[1]);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004406 }
4407 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {
4408 union { loff_t off; unsigned arg[2]; } o = { off };
mcgrathr@google.coma7999932011-11-21 22:26:20 +00004409 return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len);
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004410 }
4411 #endif
4412#endif
4413
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004414/*
4415 * Polyfills for deprecated syscalls.
4416 */
4417
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004418#if !defined(__NR_dup2)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004419 LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
4420 return LSS_NAME(dup3)(s, d, 0);
4421 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004422#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004423
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004424#if !defined(__NR_open)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004425 LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
4426 return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
4427 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004428#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004429
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004430#if !defined(__NR_unlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004431 LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
4432 return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
4433 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004434#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004435
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004436#if !defined(__NR_readlink)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004437 LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
4438 size_t size) {
4439 return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
4440 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004441#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004442
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004443#if !defined(__NR_pipe)
Mike Frysinger4ce4c482018-01-03 18:31:42 -05004444 LSS_INLINE int LSS_NAME(pipe)(int *pipefd) {
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004445 return LSS_NAME(pipe2)(pipefd, 0);
4446 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004447#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004448
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004449#if !defined(__NR_poll)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004450 LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
4451 int timeout) {
4452 struct kernel_timespec timeout_ts;
4453 struct kernel_timespec *timeout_ts_p = NULL;
4454
4455 if (timeout >= 0) {
4456 timeout_ts.tv_sec = timeout / 1000;
4457 timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
4458 timeout_ts_p = &timeout_ts;
4459 }
4460 return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
4461 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004462#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004463
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004464#if !defined(__NR_stat)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004465 LSS_INLINE int LSS_NAME(stat)(const char *pathname,
4466 struct kernel_stat *buf) {
4467 return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
4468 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004469#endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004470
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004471#if !defined(__NR_waitpid)
4472 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) {
4473 return LSS_NAME(wait4)(pid, status, options, 0);
4474 }
4475#endif
4476
4477#if !defined(__NR_fork)
4478// TODO: define this in an arch-independant way instead of inlining the clone
4479// syscall body.
4480
4481# if defined(__aarch64__)
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004482 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4483 // No fork syscall on aarch64 - implement by means of the clone syscall.
4484 // Note that this does not reset glibc's cached view of the PID/TID, so
4485 // some glibc interfaces might go wrong in the forked subprocess.
4486 int flags = SIGCHLD;
4487 void *child_stack = NULL;
4488 void *parent_tidptr = NULL;
4489 void *newtls = NULL;
4490 void *child_tidptr = NULL;
4491
4492 LSS_REG(0, flags);
4493 LSS_REG(1, child_stack);
4494 LSS_REG(2, parent_tidptr);
4495 LSS_REG(3, newtls);
4496 LSS_REG(4, child_tidptr);
4497 LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
4498 "r"(__r4));
4499 }
Torne (Richard Coles)e6527b02017-10-03 17:38:15 -04004500# elif defined(__x86_64__)
4501 LSS_INLINE pid_t LSS_NAME(fork)(void) {
4502 // Android disallows the fork syscall on x86_64 - implement by means of the
4503 // clone syscall as above for aarch64.
4504 int flags = SIGCHLD;
4505 void *child_stack = NULL;
4506 void *parent_tidptr = NULL;
4507 void *newtls = NULL;
4508 void *child_tidptr = NULL;
4509
4510 LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags),
4511 LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr),
4512 LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr));
4513 }
4514# else
4515# error missing fork polyfill for this architecture
4516# endif
anton@chromium.org2f724fc2014-04-15 13:05:20 +00004517#endif
4518
Michael Forneyf70e2f12020-01-22 19:19:38 -08004519/* These restore the original values of these macros saved by the
4520 * corresponding #pragma push_macro near the top of this file. */
4521#pragma pop_macro("stat64")
4522#pragma pop_macro("fstat64")
4523#pragma pop_macro("lstat64")
4524#pragma pop_macro("pread64")
4525#pragma pop_macro("pwrite64")
mseaborn@chromium.orgca749372012-09-05 18:26:20 +00004526
zodiac@gmail.com71d26df2010-09-15 01:31:22 +00004527#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
4528}
4529#endif
4530
4531#endif
4532#endif