/thirdparty/breakpad/third_party/lss/linux_syscall_support.h
C Header | 1826 lines | 1525 code | 55 blank | 246 comment | 52 complexity | 2d6c0b86fe3575499d978cafe72ba750 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, GPL-3.0, GPL-2.0
- /* Copyright (c) 2005-2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Markus Gutschke
- */
- /* This file includes Linux-specific support functions common to the
- * coredumper and the thread lister; primarily, this is a collection
- * of direct system calls, and a couple of symbols missing from
- * standard header files.
- * There are a few options that the including file can set to control
- * the behavior of this file:
- *
- * SYS_CPLUSPLUS:
- * The entire header file will normally be wrapped in 'extern "C" { }",
- * making it suitable for compilation as both C and C++ source. If you
- * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
- * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
- * system header files, too. It is the caller's responsibility to provide
- * the necessary definitions.
- *
- * SYS_ERRNO:
- * All system calls will update "errno" unless overriden by setting the
- * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
- * an l-value.
- *
- * SYS_INLINE:
- * New symbols will be defined "static inline", unless overridden by
- * the SYS_INLINE macro.
- *
- * SYS_LINUX_SYSCALL_SUPPORT_H
- * This macro is used to avoid multiple inclusions of this header file.
- * If you need to include this file more than once, make sure to
- * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
- *
- * SYS_PREFIX:
- * New system calls will have a prefix of "sys_" unless overridden by
- * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
- * results in prefixes "sys[0..9]_". It is also possible to set this
- * macro to -1, which avoids all prefixes.
- *
- * SYS_SYSCALL_ENTRYPOINT:
- * Some applications (such as sandboxes that filter system calls), need
- * to be able to run custom-code each time a system call is made. If this
- * macro is defined, it expands to the name of a "common" symbol. If
- * this symbol is assigned a non-NULL pointer value, it is used as the
- * address of the system call entrypoint.
- * A pointer to this symbol can be obtained by calling
- * get_syscall_entrypoint()
- *
- * This file defines a few internal symbols that all start with "LSS_".
- * Do not access these symbols from outside this file. They are not part
- * of the supported API.
- */
- #ifndef SYS_LINUX_SYSCALL_SUPPORT_H
- #define SYS_LINUX_SYSCALL_SUPPORT_H
- /* We currently only support x86-32, x86-64, ARM, MIPS, and PPC on Linux.
- * Porting to other related platforms should not be difficult.
- */
- #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
- defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__)) \
- && (defined(__linux) || defined(__ANDROID__))
- #ifndef SYS_CPLUSPLUS
- #ifdef __cplusplus
- /* Some system header files in older versions of gcc neglect to properly
- * handle being included from C++. As it appears to be harmless to have
- * multiple nested 'extern "C"' blocks, just add another one here.
- */
- extern "C" {
- #endif
- #include <errno.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stddef.h>
- #include <string.h>
- #include <sys/ptrace.h>
- #include <sys/resource.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/unistd.h>
- #include <endian.h>
- #ifdef __mips__
- /* Include definitions of the ABI currently in use. */
- #include <sgidefs.h>
- #endif
- #endif
- /* As glibc often provides subtly incompatible data structures (and implicit
- * wrapper functions that convert them), we provide our own kernel data
- * structures for use by the system calls.
- * These structures have been developed by using Linux 2.6.23 headers for
- * reference. Note though, we do not care about exact API compatibility
- * with the kernel, and in fact the kernel often does not have a single
- * API that works across architectures. Instead, we try to mimic the glibc
- * API where reasonable, and only guarantee ABI compatibility with the
- * kernel headers.
- * Most notably, here are a few changes that were made to the structures
- * defined by kernel headers:
- *
- * - we only define structures, but not symbolic names for kernel data
- * types. For the latter, we directly use the native C datatype
- * (i.e. "unsigned" instead of "mode_t").
- * - in a few cases, it is possible to define identical structures for
- * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
- * standardizing on the 64bit version of the data types. In particular,
- * this means that we use "unsigned" where the 32bit headers say
- * "unsigned long".
- * - overall, we try to minimize the number of cases where we need to
- * conditionally define different structures.
- * - the "struct kernel_sigaction" class of structures have been
- * modified to more closely mimic glibc's API by introducing an
- * anonymous union for the function pointer.
- * - a small number of field names had to have an underscore appended to
- * them, because glibc defines a global macro by the same name.
- */
- /* include/linux/dirent.h */
- struct kernel_dirent64 {
- unsigned long long d_ino;
- long long d_off;
- unsigned short d_reclen;
- unsigned char d_type;
- char d_name[256];
- };
- /* include/linux/dirent.h */
- struct kernel_dirent {
- long d_ino;
- long d_off;
- unsigned short d_reclen;
- char d_name[256];
- };
- /* include/linux/uio.h */
- struct kernel_iovec {
- void *iov_base;
- unsigned long iov_len;
- };
- /* include/linux/socket.h */
- struct kernel_msghdr {
- void *msg_name;
- int msg_namelen;
- struct kernel_iovec*msg_iov;
- unsigned long msg_iovlen;
- void *msg_control;
- unsigned long msg_controllen;
- unsigned msg_flags;
- };
- /* include/asm-generic/poll.h */
- struct kernel_pollfd {
- int fd;
- short events;
- short revents;
- };
- /* include/linux/resource.h */
- struct kernel_rlimit {
- unsigned long rlim_cur;
- unsigned long rlim_max;
- };
- /* include/linux/time.h */
- struct kernel_timespec {
- long tv_sec;
- long tv_nsec;
- };
- /* include/linux/time.h */
- struct kernel_timeval {
- long tv_sec;
- long tv_usec;
- };
- /* include/linux/resource.h */
- struct kernel_rusage {
- struct kernel_timeval ru_utime;
- struct kernel_timeval ru_stime;
- long ru_maxrss;
- long ru_ixrss;
- long ru_idrss;
- long ru_isrss;
- long ru_minflt;
- long ru_majflt;
- long ru_nswap;
- long ru_inblock;
- long ru_oublock;
- long ru_msgsnd;
- long ru_msgrcv;
- long ru_nsignals;
- long ru_nvcsw;
- long ru_nivcsw;
- };
- struct siginfo;
- #if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
- || defined(__PPC__)
- /* include/asm-{arm,i386,mips,ppc}/signal.h */
- struct kernel_old_sigaction {
- union {
- void (*sa_handler_)(int);
- void (*sa_sigaction_)(int, struct siginfo *, void *);
- };
- unsigned long sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- } __attribute__((packed,aligned(4)));
- #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
- #define kernel_old_sigaction kernel_sigaction
- #endif
- /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
- * exactly match the size of the signal set, even though the API was
- * intended to be extensible. We define our own KERNEL_NSIG to deal with
- * this.
- * Please note that glibc provides signals [1.._NSIG-1], whereas the
- * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
- * actual number of signals is obviously the same, but the constants
- * differ by one.
- */
- #ifdef __mips__
- #define KERNEL_NSIG 128
- #else
- #define KERNEL_NSIG 64
- #endif
- /* include/asm-{arm,i386,mips,x86_64}/signal.h */
- struct kernel_sigset_t {
- unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
- (8*sizeof(unsigned long))];
- };
- /* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
- struct kernel_sigaction {
- #ifdef __mips__
- unsigned long sa_flags;
- union {
- void (*sa_handler_)(int);
- void (*sa_sigaction_)(int, struct siginfo *, void *);
- };
- struct kernel_sigset_t sa_mask;
- #else
- union {
- void (*sa_handler_)(int);
- void (*sa_sigaction_)(int, struct siginfo *, void *);
- };
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- struct kernel_sigset_t sa_mask;
- #endif
- };
- /* include/linux/socket.h */
- struct kernel_sockaddr {
- unsigned short sa_family;
- char sa_data[14];
- };
- /* include/asm-{arm,i386,mips,ppc}/stat.h */
- #ifdef __mips__
- #if _MIPS_SIM == _MIPS_SIM_ABI64
- struct kernel_stat {
- #else
- struct kernel_stat64 {
- #endif
- unsigned st_dev;
- unsigned __pad0[3];
- unsigned long long st_ino;
- unsigned st_mode;
- unsigned st_nlink;
- unsigned st_uid;
- unsigned st_gid;
- unsigned st_rdev;
- unsigned __pad1[3];
- long long st_size;
- unsigned st_atime_;
- unsigned st_atime_nsec_;
- unsigned st_mtime_;
- unsigned st_mtime_nsec_;
- unsigned st_ctime_;
- unsigned st_ctime_nsec_;
- unsigned st_blksize;
- unsigned __pad2;
- unsigned long long st_blocks;
- };
- #elif defined __PPC__
- struct kernel_stat64 {
- unsigned long long st_dev;
- unsigned long long st_ino;
- unsigned st_mode;
- unsigned st_nlink;
- unsigned st_uid;
- unsigned st_gid;
- unsigned long long st_rdev;
- unsigned short int __pad2;
- long long st_size;
- long st_blksize;
- long long st_blocks;
- long st_atime_;
- unsigned long st_atime_nsec_;
- long st_mtime_;
- unsigned long st_mtime_nsec_;
- long st_ctime_;
- unsigned long st_ctime_nsec_;
- unsigned long __unused4;
- unsigned long __unused5;
- };
- #else
- struct kernel_stat64 {
- unsigned long long st_dev;
- unsigned char __pad0[4];
- unsigned __st_ino;
- unsigned st_mode;
- unsigned st_nlink;
- unsigned st_uid;
- unsigned st_gid;
- unsigned long long st_rdev;
- unsigned char __pad3[4];
- long long st_size;
- unsigned st_blksize;
- unsigned long long st_blocks;
- unsigned st_atime_;
- unsigned st_atime_nsec_;
- unsigned st_mtime_;
- unsigned st_mtime_nsec_;
- unsigned st_ctime_;
- unsigned st_ctime_nsec_;
- unsigned long long st_ino;
- };
- #endif
- /* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */
- #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
- struct kernel_stat {
- /* The kernel headers suggest that st_dev and st_rdev should be 32bit
- * quantities encoding 12bit major and 20bit minor numbers in an interleaved
- * format. In reality, we do not see useful data in the top bits. So,
- * we'll leave the padding in here, until we find a better solution.
- */
- unsigned short st_dev;
- short pad1;
- unsigned st_ino;
- unsigned short st_mode;
- unsigned short st_nlink;
- unsigned short st_uid;
- unsigned short st_gid;
- unsigned short st_rdev;
- short pad2;
- unsigned st_size;
- unsigned st_blksize;
- unsigned st_blocks;
- unsigned st_atime_;
- unsigned st_atime_nsec_;
- unsigned st_mtime_;
- unsigned st_mtime_nsec_;
- unsigned st_ctime_;
- unsigned st_ctime_nsec_;
- unsigned __unused4;
- unsigned __unused5;
- };
- #elif defined(__x86_64__)
- struct kernel_stat {
- unsigned long st_dev;
- unsigned long st_ino;
- unsigned long st_nlink;
- unsigned st_mode;
- unsigned st_uid;
- unsigned st_gid;
- unsigned __pad0;
- unsigned long st_rdev;
- long st_size;
- long st_blksize;
- long st_blocks;
- unsigned long st_atime_;
- unsigned long st_atime_nsec_;
- unsigned long st_mtime_;
- unsigned long st_mtime_nsec_;
- unsigned long st_ctime_;
- unsigned long st_ctime_nsec_;
- long __unused[3];
- };
- #elif defined(__PPC__)
- struct kernel_stat {
- unsigned st_dev;
- unsigned long st_ino; // ino_t
- unsigned long st_mode; // mode_t
- unsigned short st_nlink; // nlink_t
- unsigned st_uid; // uid_t
- unsigned st_gid; // gid_t
- unsigned st_rdev;
- long st_size; // off_t
- unsigned long st_blksize;
- unsigned long st_blocks;
- unsigned long st_atime_;
- unsigned long st_atime_nsec_;
- unsigned long st_mtime_;
- unsigned long st_mtime_nsec_;
- unsigned long st_ctime_;
- unsigned long st_ctime_nsec_;
- unsigned long __unused4;
- unsigned long __unused5;
- };
- #elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
- struct kernel_stat {
- unsigned st_dev;
- int st_pad1[3];
- unsigned st_ino;
- unsigned st_mode;
- unsigned st_nlink;
- unsigned st_uid;
- unsigned st_gid;
- unsigned st_rdev;
- int st_pad2[2];
- long st_size;
- int st_pad3;
- long st_atime_;
- long st_atime_nsec_;
- long st_mtime_;
- long st_mtime_nsec_;
- long st_ctime_;
- long st_ctime_nsec_;
- int st_blksize;
- int st_blocks;
- int st_pad4[14];
- };
- #endif
- /* include/asm-{arm,i386,mips,x86_64,ppc}/statfs.h */
- #ifdef __mips__
- #if _MIPS_SIM != _MIPS_SIM_ABI64
- struct kernel_statfs64 {
- unsigned long f_type;
- unsigned long f_bsize;
- unsigned long f_frsize;
- unsigned long __pad;
- unsigned long long f_blocks;
- unsigned long long f_bfree;
- unsigned long long f_files;
- unsigned long long f_ffree;
- unsigned long long f_bavail;
- struct { int val[2]; } f_fsid;
- unsigned long f_namelen;
- unsigned long f_spare[6];
- };
- #endif
- #elif !defined(__x86_64__)
- struct kernel_statfs64 {
- unsigned long f_type;
- unsigned long f_bsize;
- unsigned long long f_blocks;
- unsigned long long f_bfree;
- unsigned long long f_bavail;
- unsigned long long f_files;
- unsigned long long f_ffree;
- struct { int val[2]; } f_fsid;
- unsigned long f_namelen;
- unsigned long f_frsize;
- unsigned long f_spare[5];
- };
- #endif
- /* include/asm-{arm,i386,mips,x86_64,ppc,generic}/statfs.h */
- #ifdef __mips__
- struct kernel_statfs {
- long f_type;
- long f_bsize;
- long f_frsize;
- long f_blocks;
- long f_bfree;
- long f_files;
- long f_ffree;
- long f_bavail;
- struct { int val[2]; } f_fsid;
- long f_namelen;
- long f_spare[6];
- };
- #else
- struct kernel_statfs {
- /* x86_64 actually defines all these fields as signed, whereas all other */
- /* platforms define them as unsigned. Leaving them at unsigned should not */
- /* cause any problems. */
- unsigned long f_type;
- unsigned long f_bsize;
- unsigned long f_blocks;
- unsigned long f_bfree;
- unsigned long f_bavail;
- unsigned long f_files;
- unsigned long f_ffree;
- struct { int val[2]; } f_fsid;
- unsigned long f_namelen;
- unsigned long f_frsize;
- unsigned long f_spare[5];
- };
- #endif
- /* Definitions missing from the standard header files */
- #ifndef O_DIRECTORY
- #if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
- #define O_DIRECTORY 0040000
- #else
- #define O_DIRECTORY 0200000
- #endif
- #endif
- #ifndef NT_PRXFPREG
- #define NT_PRXFPREG 0x46e62b7f
- #endif
- #ifndef PTRACE_GETFPXREGS
- #define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
- #endif
- #ifndef PR_GET_DUMPABLE
- #define PR_GET_DUMPABLE 3
- #endif
- #ifndef PR_SET_DUMPABLE
- #define PR_SET_DUMPABLE 4
- #endif
- #ifndef PR_GET_SECCOMP
- #define PR_GET_SECCOMP 21
- #endif
- #ifndef PR_SET_SECCOMP
- #define PR_SET_SECCOMP 22
- #endif
- #ifndef AT_FDCWD
- #define AT_FDCWD (-100)
- #endif
- #ifndef AT_SYMLINK_NOFOLLOW
- #define AT_SYMLINK_NOFOLLOW 0x100
- #endif
- #ifndef AT_REMOVEDIR
- #define AT_REMOVEDIR 0x200
- #endif
- #ifndef MREMAP_FIXED
- #define MREMAP_FIXED 2
- #endif
- #ifndef SA_RESTORER
- #define SA_RESTORER 0x04000000
- #endif
- #ifndef CPUCLOCK_PROF
- #define CPUCLOCK_PROF 0
- #endif
- #ifndef CPUCLOCK_VIRT
- #define CPUCLOCK_VIRT 1
- #endif
- #ifndef CPUCLOCK_SCHED
- #define CPUCLOCK_SCHED 2
- #endif
- #ifndef CPUCLOCK_PERTHREAD_MASK
- #define CPUCLOCK_PERTHREAD_MASK 4
- #endif
- #ifndef MAKE_PROCESS_CPUCLOCK
- #define MAKE_PROCESS_CPUCLOCK(pid, clock) \
- ((~(int)(pid) << 3) | (int)(clock))
- #endif
- #ifndef MAKE_THREAD_CPUCLOCK
- #define MAKE_THREAD_CPUCLOCK(tid, clock) \
- ((~(int)(tid) << 3) | (int)((clock) | CPUCLOCK_PERTHREAD_MASK))
- #endif
- #ifndef FUTEX_WAIT
- #define FUTEX_WAIT 0
- #endif
- #ifndef FUTEX_WAKE
- #define FUTEX_WAKE 1
- #endif
- #ifndef FUTEX_FD
- #define FUTEX_FD 2
- #endif
- #ifndef FUTEX_REQUEUE
- #define FUTEX_REQUEUE 3
- #endif
- #ifndef FUTEX_CMP_REQUEUE
- #define FUTEX_CMP_REQUEUE 4
- #endif
- #ifndef FUTEX_WAKE_OP
- #define FUTEX_WAKE_OP 5
- #endif
- #ifndef FUTEX_LOCK_PI
- #define FUTEX_LOCK_PI 6
- #endif
- #ifndef FUTEX_UNLOCK_PI
- #define FUTEX_UNLOCK_PI 7
- #endif
- #ifndef FUTEX_TRYLOCK_PI
- #define FUTEX_TRYLOCK_PI 8
- #endif
- #ifndef FUTEX_PRIVATE_FLAG
- #define FUTEX_PRIVATE_FLAG 128
- #endif
- #ifndef FUTEX_CMD_MASK
- #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
- #endif
- #ifndef FUTEX_WAIT_PRIVATE
- #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_WAKE_PRIVATE
- #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_REQUEUE_PRIVATE
- #define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_CMP_REQUEUE_PRIVATE
- #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_WAKE_OP_PRIVATE
- #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_LOCK_PI_PRIVATE
- #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_UNLOCK_PI_PRIVATE
- #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
- #endif
- #ifndef FUTEX_TRYLOCK_PI_PRIVATE
- #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
- #endif
- #if defined(__x86_64__)
- #ifndef ARCH_SET_GS
- #define ARCH_SET_GS 0x1001
- #endif
- #ifndef ARCH_GET_GS
- #define ARCH_GET_GS 0x1004
- #endif
- #endif
- #if defined(__i386__)
- #ifndef __NR_quotactl
- #define __NR_quotactl 131
- #endif
- #ifndef __NR_setresuid
- #define __NR_setresuid 164
- #define __NR_getresuid 165
- #define __NR_setresgid 170
- #define __NR_getresgid 171
- #endif
- #ifndef __NR_rt_sigaction
- #define __NR_rt_sigreturn 173
- #define __NR_rt_sigaction 174
- #define __NR_rt_sigprocmask 175
- #define __NR_rt_sigpending 176
- #define __NR_rt_sigsuspend 179
- #endif
- #ifndef __NR_pread64
- #define __NR_pread64 180
- #endif
- #ifndef __NR_pwrite64
- #define __NR_pwrite64 181
- #endif
- #ifndef __NR_ugetrlimit
- #define __NR_ugetrlimit 191
- #endif
- #ifndef __NR_stat64
- #define __NR_stat64 195
- #endif
- #ifndef __NR_fstat64
- #define __NR_fstat64 197
- #endif
- #ifndef __NR_setresuid32
- #define __NR_setresuid32 208
- #define __NR_getresuid32 209
- #define __NR_setresgid32 210
- #define __NR_getresgid32 211
- #endif
- #ifndef __NR_setfsuid32
- #define __NR_setfsuid32 215
- #define __NR_setfsgid32 216
- #endif
- #ifndef __NR_getdents64
- #define __NR_getdents64 220
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid 224
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead 225
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr 226
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr 227
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr 229
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr 230
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr 232
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr 233
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill 238
- #endif
- #ifndef __NR_futex
- #define __NR_futex 240
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity 241
- #define __NR_sched_getaffinity 242
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address 258
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime 265
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres 266
- #endif
- #ifndef __NR_statfs64
- #define __NR_statfs64 268
- #endif
- #ifndef __NR_fstatfs64
- #define __NR_fstatfs64 269
- #endif
- #ifndef __NR_fadvise64_64
- #define __NR_fadvise64_64 272
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set 289
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get 290
- #endif
- #ifndef __NR_openat
- #define __NR_openat 295
- #endif
- #ifndef __NR_fstatat64
- #define __NR_fstatat64 300
- #endif
- #ifndef __NR_unlinkat
- #define __NR_unlinkat 301
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages 317
- #endif
- #ifndef __NR_getcpu
- #define __NR_getcpu 318
- #endif
- #ifndef __NR_fallocate
- #define __NR_fallocate 324
- #endif
- /* End of i386 definitions */
- #elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
- #ifndef __NR_setresuid
- #define __NR_setresuid (__NR_SYSCALL_BASE + 164)
- #define __NR_getresuid (__NR_SYSCALL_BASE + 165)
- #define __NR_setresgid (__NR_SYSCALL_BASE + 170)
- #define __NR_getresgid (__NR_SYSCALL_BASE + 171)
- #endif
- #ifndef __NR_rt_sigaction
- #define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
- #define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
- #define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
- #define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
- #define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
- #endif
- #ifndef __NR_pread64
- #define __NR_pread64 (__NR_SYSCALL_BASE + 180)
- #endif
- #ifndef __NR_pwrite64
- #define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
- #endif
- #ifndef __NR_ugetrlimit
- #define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
- #endif
- #ifndef __NR_stat64
- #define __NR_stat64 (__NR_SYSCALL_BASE + 195)
- #endif
- #ifndef __NR_fstat64
- #define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
- #endif
- #ifndef __NR_setresuid32
- #define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
- #define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
- #define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
- #define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
- #endif
- #ifndef __NR_setfsuid32
- #define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
- #define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
- #endif
- #ifndef __NR_getdents64
- #define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid (__NR_SYSCALL_BASE + 224)
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead (__NR_SYSCALL_BASE + 225)
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr (__NR_SYSCALL_BASE + 226)
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr (__NR_SYSCALL_BASE + 229)
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr (__NR_SYSCALL_BASE + 232)
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill (__NR_SYSCALL_BASE + 238)
- #endif
- #ifndef __NR_futex
- #define __NR_futex (__NR_SYSCALL_BASE + 240)
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
- #define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
- #endif
- #ifndef __NR_statfs64
- #define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
- #endif
- #ifndef __NR_fstatfs64
- #define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages (__NR_SYSCALL_BASE + 344)
- #endif
- #ifndef __NR_getcpu
- #define __NR_getcpu (__NR_SYSCALL_BASE + 345)
- #endif
- /* End of ARM 3/EABI definitions */
- #elif defined(__x86_64__)
- #ifndef __NR_pread64
- #define __NR_pread64 17
- #endif
- #ifndef __NR_pwrite64
- #define __NR_pwrite64 18
- #endif
- #ifndef __NR_setresuid
- #define __NR_setresuid 117
- #define __NR_getresuid 118
- #define __NR_setresgid 119
- #define __NR_getresgid 120
- #endif
- #ifndef __NR_quotactl
- #define __NR_quotactl 179
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid 186
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead 187
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr 188
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr 189
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr 191
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr 192
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr 194
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr 195
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill 200
- #endif
- #ifndef __NR_futex
- #define __NR_futex 202
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity 203
- #define __NR_sched_getaffinity 204
- #endif
- #ifndef __NR_getdents64
- #define __NR_getdents64 217
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address 218
- #endif
- #ifndef __NR_fadvise64
- #define __NR_fadvise64 221
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime 228
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres 229
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set 251
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get 252
- #endif
- #ifndef __NR_openat
- #define __NR_openat 257
- #endif
- #ifndef __NR_newfstatat
- #define __NR_newfstatat 262
- #endif
- #ifndef __NR_unlinkat
- #define __NR_unlinkat 263
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages 279
- #endif
- #ifndef __NR_fallocate
- #define __NR_fallocate 285
- #endif
- /* End of x86-64 definitions */
- #elif defined(__mips__)
- #if _MIPS_SIM == _MIPS_SIM_ABI32
- #ifndef __NR_setresuid
- #define __NR_setresuid (__NR_Linux + 185)
- #define __NR_getresuid (__NR_Linux + 186)
- #define __NR_setresgid (__NR_Linux + 190)
- #define __NR_getresgid (__NR_Linux + 191)
- #endif
- #ifndef __NR_rt_sigaction
- #define __NR_rt_sigreturn (__NR_Linux + 193)
- #define __NR_rt_sigaction (__NR_Linux + 194)
- #define __NR_rt_sigprocmask (__NR_Linux + 195)
- #define __NR_rt_sigpending (__NR_Linux + 196)
- #define __NR_rt_sigsuspend (__NR_Linux + 199)
- #endif
- #ifndef __NR_pread64
- #define __NR_pread64 (__NR_Linux + 200)
- #endif
- #ifndef __NR_pwrite64
- #define __NR_pwrite64 (__NR_Linux + 201)
- #endif
- #ifndef __NR_stat64
- #define __NR_stat64 (__NR_Linux + 213)
- #endif
- #ifndef __NR_fstat64
- #define __NR_fstat64 (__NR_Linux + 215)
- #endif
- #ifndef __NR_getdents64
- #define __NR_getdents64 (__NR_Linux + 219)
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid (__NR_Linux + 222)
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead (__NR_Linux + 223)
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr (__NR_Linux + 224)
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr (__NR_Linux + 225)
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr (__NR_Linux + 227)
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr (__NR_Linux + 228)
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr (__NR_Linux + 230)
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr (__NR_Linux + 231)
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill (__NR_Linux + 236)
- #endif
- #ifndef __NR_futex
- #define __NR_futex (__NR_Linux + 238)
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity (__NR_Linux + 239)
- #define __NR_sched_getaffinity (__NR_Linux + 240)
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address (__NR_Linux + 252)
- #endif
- #ifndef __NR_statfs64
- #define __NR_statfs64 (__NR_Linux + 255)
- #endif
- #ifndef __NR_fstatfs64
- #define __NR_fstatfs64 (__NR_Linux + 256)
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime (__NR_Linux + 263)
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres (__NR_Linux + 264)
- #endif
- #ifndef __NR_openat
- #define __NR_openat (__NR_Linux + 288)
- #endif
- #ifndef __NR_fstatat
- #define __NR_fstatat (__NR_Linux + 293)
- #endif
- #ifndef __NR_unlinkat
- #define __NR_unlinkat (__NR_Linux + 294)
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages (__NR_Linux + 308)
- #endif
- #ifndef __NR_getcpu
- #define __NR_getcpu (__NR_Linux + 312)
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set (__NR_Linux + 314)
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get (__NR_Linux + 315)
- #endif
- /* End of MIPS (old 32bit API) definitions */
- #elif _MIPS_SIM == _MIPS_SIM_ABI64
- #ifndef __NR_pread64
- #define __NR_pread64 (__NR_Linux + 16)
- #endif
- #ifndef __NR_pwrite64
- #define __NR_pwrite64 (__NR_Linux + 17)
- #endif
- #ifndef __NR_setresuid
- #define __NR_setresuid (__NR_Linux + 115)
- #define __NR_getresuid (__NR_Linux + 116)
- #define __NR_setresgid (__NR_Linux + 117)
- #define __NR_getresgid (__NR_Linux + 118)
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid (__NR_Linux + 178)
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead (__NR_Linux + 179)
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr (__NR_Linux + 180)
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr (__NR_Linux + 181)
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr (__NR_Linux + 183)
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr (__NR_Linux + 184)
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr (__NR_Linux + 186)
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr (__NR_Linux + 187)
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill (__NR_Linux + 192)
- #endif
- #ifndef __NR_futex
- #define __NR_futex (__NR_Linux + 194)
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity (__NR_Linux + 195)
- #define __NR_sched_getaffinity (__NR_Linux + 196)
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address (__NR_Linux + 212)
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime (__NR_Linux + 222)
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres (__NR_Linux + 223)
- #endif
- #ifndef __NR_openat
- #define __NR_openat (__NR_Linux + 247)
- #endif
- #ifndef __NR_fstatat
- #define __NR_fstatat (__NR_Linux + 252)
- #endif
- #ifndef __NR_unlinkat
- #define __NR_unlinkat (__NR_Linux + 253)
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages (__NR_Linux + 267)
- #endif
- #ifndef __NR_getcpu
- #define __NR_getcpu (__NR_Linux + 271)
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set (__NR_Linux + 273)
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get (__NR_Linux + 274)
- #endif
- /* End of MIPS (64bit API) definitions */
- #else
- #ifndef __NR_setresuid
- #define __NR_setresuid (__NR_Linux + 115)
- #define __NR_getresuid (__NR_Linux + 116)
- #define __NR_setresgid (__NR_Linux + 117)
- #define __NR_getresgid (__NR_Linux + 118)
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid (__NR_Linux + 178)
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead (__NR_Linux + 179)
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr (__NR_Linux + 180)
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr (__NR_Linux + 181)
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr (__NR_Linux + 183)
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr (__NR_Linux + 184)
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr (__NR_Linux + 186)
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr (__NR_Linux + 187)
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill (__NR_Linux + 192)
- #endif
- #ifndef __NR_futex
- #define __NR_futex (__NR_Linux + 194)
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity (__NR_Linux + 195)
- #define __NR_sched_getaffinity (__NR_Linux + 196)
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address (__NR_Linux + 213)
- #endif
- #ifndef __NR_statfs64
- #define __NR_statfs64 (__NR_Linux + 217)
- #endif
- #ifndef __NR_fstatfs64
- #define __NR_fstatfs64 (__NR_Linux + 218)
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime (__NR_Linux + 226)
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres (__NR_Linux + 227)
- #endif
- #ifndef __NR_openat
- #define __NR_openat (__NR_Linux + 251)
- #endif
- #ifndef __NR_fstatat
- #define __NR_fstatat (__NR_Linux + 256)
- #endif
- #ifndef __NR_unlinkat
- #define __NR_unlinkat (__NR_Linux + 257)
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages (__NR_Linux + 271)
- #endif
- #ifndef __NR_getcpu
- #define __NR_getcpu (__NR_Linux + 275)
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set (__NR_Linux + 277)
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get (__NR_Linux + 278)
- #endif
- /* End of MIPS (new 32bit API) definitions */
- #endif
- /* End of MIPS definitions */
- #elif defined(__PPC__)
- #ifndef __NR_setfsuid
- #define __NR_setfsuid 138
- #define __NR_setfsgid 139
- #endif
- #ifndef __NR_setresuid
- #define __NR_setresuid 164
- #define __NR_getresuid 165
- #define __NR_setresgid 169
- #define __NR_getresgid 170
- #endif
- #ifndef __NR_rt_sigaction
- #define __NR_rt_sigreturn 172
- #define __NR_rt_sigaction 173
- #define __NR_rt_sigprocmask 174
- #define __NR_rt_sigpending 175
- #define __NR_rt_sigsuspend 178
- #endif
- #ifndef __NR_pread64
- #define __NR_pread64 179
- #endif
- #ifndef __NR_pwrite64
- #define __NR_pwrite64 180
- #endif
- #ifndef __NR_ugetrlimit
- #define __NR_ugetrlimit 190
- #endif
- #ifndef __NR_readahead
- #define __NR_readahead 191
- #endif
- #ifndef __NR_stat64
- #define __NR_stat64 195
- #endif
- #ifndef __NR_fstat64
- #define __NR_fstat64 197
- #endif
- #ifndef __NR_getdents64
- #define __NR_getdents64 202
- #endif
- #ifndef __NR_gettid
- #define __NR_gettid 207
- #endif
- #ifndef __NR_tkill
- #define __NR_tkill 208
- #endif
- #ifndef __NR_setxattr
- #define __NR_setxattr 209
- #endif
- #ifndef __NR_lsetxattr
- #define __NR_lsetxattr 210
- #endif
- #ifndef __NR_getxattr
- #define __NR_getxattr 212
- #endif
- #ifndef __NR_lgetxattr
- #define __NR_lgetxattr 213
- #endif
- #ifndef __NR_listxattr
- #define __NR_listxattr 215
- #endif
- #ifndef __NR_llistxattr
- #define __NR_llistxattr 216
- #endif
- #ifndef __NR_futex
- #define __NR_futex 221
- #endif
- #ifndef __NR_sched_setaffinity
- #define __NR_sched_setaffinity 222
- #define __NR_sched_getaffinity 223
- #endif
- #ifndef __NR_set_tid_address
- #define __NR_set_tid_address 232
- #endif
- #ifndef __NR_clock_gettime
- #define __NR_clock_gettime 246
- #endif
- #ifndef __NR_clock_getres
- #define __NR_clock_getres 247
- #endif
- #ifndef __NR_statfs64
- #define __NR_statfs64 252
- #endif
- #ifndef __NR_fstatfs64
- #define __NR_fstatfs64 253
- #endif
- #ifndef __NR_fadvise64_64
- #define __NR_fadvise64_64 254
- #endif
- #ifndef __NR_ioprio_set
- #define __NR_ioprio_set 273
- #endif
- #ifndef __NR_ioprio_get
- #define __NR_ioprio_get 274
- #endif
- #ifndef __NR_openat
- #define __NR_openat 286
- #endif
- #ifndef __NR_fstatat64
- #define __NR_fstatat64 291
- #endif
- #ifndef __NR_unlinkat
- #define __NR_unlinkat 292
- #endif
- #ifndef __NR_move_pages
- #define __NR_move_pages 301
- #endif
- #ifndef __NR_getcpu
- #define __NR_getcpu 302
- #endif
- /* End of powerpc defininitions */
- #endif
- /* After forking, we must make sure to only call system calls. */
- #if defined __BOUNDED_POINTERS__
- #error "Need to port invocations of syscalls for bounded ptrs"
- #else
- /* The core dumper and the thread lister get executed after threads
- * have been suspended. As a consequence, we cannot call any functions
- * that acquire locks. Unfortunately, libc wraps most system calls
- * (e.g. in order to implement pthread_atfork, and to make calls
- * cancellable), which means we cannot call these functions. Instead,
- * we have to call syscall() directly.
- */
- #undef LSS_ERRNO
- #ifdef SYS_ERRNO
- /* Allow the including file to override the location of errno. This can
- * be useful when using clone() with the CLONE_VM option.
- */
- #define LSS_ERRNO SYS_ERRNO
- #else
- #define LSS_ERRNO errno
- #endif
- #undef LSS_INLINE
- #ifdef SYS_INLINE
- #define LSS_INLINE SYS_INLINE
- #else
- #define LSS_INLINE static inline
- #endif
- /* Allow the including file to override the prefix used for all new
- * system calls. By default, it will be set to "sys_".
- */
- #undef LSS_NAME
- #ifndef SYS_PREFIX
- #define LSS_NAME(name) sys_##name
- #elif defined SYS_PREFIX && SYS_PREFIX < 0
- #define LSS_NAME(name) name
- #elif defined SYS_PREFIX && SYS_PREFIX == 0
- #define LSS_NAME(name) sys0_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 1
- #define LSS_NAME(name) sys1_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 2
- #define LSS_NAME(name) sys2_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 3
- #define LSS_NAME(name) sys3_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 4
- #define LSS_NAME(name) sys4_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 5
- #define LSS_NAME(name) sys5_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 6
- #define LSS_NAME(name) sys6_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 7
- #define LSS_NAME(name) sys7_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 8
- #define LSS_NAME(name) sys8_##name
- #elif defined SYS_PREFIX && SYS_PREFIX == 9
- #define LSS_NAME(name) sys9_##name
- #endif
- #undef LSS_RETURN
- #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
- || defined(__ARM_EABI__))
- /* Failing system calls return a negative result in the range of
- * -1..-4095. These are "errno" values with the sign inverted.
- */
- #define LSS_RETURN(type, res) \
- do { \
- if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
- LSS_ERRNO = -(res); \
- res = -1; \
- } \
- return (type) (res); \
- } while (0)
- #elif defined(__mips__)
- /* On MIPS, failing system calls return -1, and set errno in a
- * separate CPU register.
- */
- #define LSS_RETURN(type, res, err) \
- do { \
- if (err) { \
- LSS_ERRNO = (res); \
- res = -1; \
- } \
- return (type) (res); \
- } while (0)
- #elif defined(__PPC__)
- /* On PPC, failing system calls return -1, and set errno in a
- * separate CPU register. See linux/unistd.h.
- */
- #define LSS_RETURN(type, res, err) \
- do { \
- if (err & 0x10000000 ) { \
- LSS_ERRNO = (res); \
- res = -1; \
- } \
- return (type) (res); \
- } while (0)
- #endif
- #if defined(__i386__)
- /* In PIC mode (e.g. when building shared libraries), gcc for i386
- * reserves ebx. Unfortunately, most distribution ship with implementations
- * of _syscallX() which clobber ebx.
- * Also, most definitions of _syscallX() neglect to mark "memory" as being
- * clobbered. This causes problems with compilers, that do a better job
- * at optimizing across __asm__ calls.
- * So, we just have to redefine all of the _syscallX() macros.
- */
- #undef LSS_ENTRYPOINT
- #ifdef SYS_SYSCALL_ENTRYPOINT
- static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
- void (**entrypoint)(void);
- asm volatile(".bss\n"
- ".align 8\n"
- ".globl "SYS_SYSCALL_ENTRYPOINT"\n"
- ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n"
- ".previous\n"
- /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */
- "call 0f\n"
- "0:pop %0\n"
- "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n"
- "mov "SYS_SYSCALL_ENTRYPOINT"@GOT(%0), %0\n"
- : "=r"(entrypoint));
- return entrypoint;
- }
- #define LSS_ENTRYPOINT ".bss\n" \
- ".align 8\n" \
- ".globl "SYS_SYSCALL_ENTRYPOINT"\n" \
- ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n" \
- ".previous\n" \
- /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \
- "push %%eax\n" \
- "call 10000f\n" \
- "10000:pop %%eax\n" \
- "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \
- "mov "SYS_SYSCALL_ENTRYPOINT"@GOT(%%eax), %%eax\n"\
- "mov 0(%%eax), %%eax\n" \
- "test %%eax, %%eax\n" \
- "jz 10001f\n" \
- "push %%eax\n" \
- "lea 10002f, %%eax\n" \
- "xchg 4(%%esp), %%eax\n" \
- "ret\n" \
- "10001:pop %%eax\n" \
- "int $0x80\n" \
- "10002:\n"
- #else
- #define LSS_ENTRYPOINT "int $0x80\n"
- #endif
- #undef LSS_BODY
- #define LSS_BODY(type,args...) \
- long __res; \
- __asm__ __volatile__("push %%ebx\n" \
- "movl %2,%%ebx\n" \
- LSS_ENTRYPOINT \
- "pop %%ebx" \
- args \
- : "esp", "memory"); \
- LSS_RETURN(type,__res)
- #undef _syscall0
- #define _syscall0(type,name) \
- type LSS_NAME(name)(void) { \
- long __res; \
- __asm__ volatile(LSS_ENTRYPOINT \
- : "=a" (__res) \
- : "0" (__NR_##name) \
- : "esp", "memory"); \
- LSS_RETURN(type,__res); \
- }
- #undef _syscall1
- #define _syscall1(type,name,type1,arg1) \
- type LSS_NAME(name)(type1 arg1) { \
- LSS_BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name), "ri" ((long)(arg1))); \
- }
- #undef _syscall2
- #define _syscall2(type,name,type1,arg1,type2,arg2) \
- type LSS_NAME(name)(type1 arg1,type2 arg2) { \
- LSS_BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
- }
- #undef _syscall3
- #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
- type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
- LSS_BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
- }
- #undef _syscall4
- #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
- type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
- LSS_BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
- }
- #undef _syscall5
- #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
- type5,arg5) \
- type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
- type5 arg5) { \
- long __res; \
- __asm__ __volatile__("push %%ebx\n" \
- "movl %2,%%ebx\n" \
- "movl %1,%%eax\n" \
- LSS_ENTRYPOINT \
- "pop %%ebx" \
- : "=a" (__res) \
- : "i" (__NR_##name), "ri" ((long)(arg1)), \
- "c" ((long)(arg2)), "d" ((long)(arg3)), \
- "S" ((long)(arg4)), "D" ((long)(arg5)) \
- : "esp", "memory"); \
- LSS_RETURN(type,__res); \
- }
- #undef _syscall6
- #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
- type5,arg5,type6,arg6) \
- type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
- type5 arg5, type6 arg6) { \
- long __res; \
- struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
- __asm__ __volatile__("push %%ebp\n" \
- "push %%ebx\n" \
- "movl 4(%2),%%ebp\n" \
- "movl 0(%2), %%ebx\n" \
- "movl %1,%%eax\n" \
- LSS_ENTRYPOINT \
- "pop %%ebx\n" \
- "pop %%ebp" \
- : "=a" (__res) \
- : "i" (__NR_##name), "0" ((long)(&__s)), \
- "c" ((long)(arg2)), "d" ((long)(arg3)), \
- "S" ((long)(arg4)), "D" ((long)(arg5)) \
- : "esp", "memory"); \
- LSS_RETURN(type,__res); \
- }
- LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
- int flags, void *arg, int *parent_tidptr,
- void *newtls, int *child_tidptr) {
- long __res;
- __asm__ __volatile__(/* if (fn == NULL)
- * return -EINVAL;
- */
- "movl %3,%%ecx\n"
- "jecxz 1f\n"
- /* if (child_stack == NULL)
- * return -EINVAL;
- */
- "movl %4,%%ecx\n"
- "jecxz 1f\n"
- /* Set up alignment of the child stack:
- * child_stack = (child_stack & ~0xF) - 20;
- */
- "andl $-16,%%ecx\n"
- "subl $20,%%ecx\n"
- /* Push "arg" and "fn" onto the stack that will be
- * used by the child.
- */
- "movl %6,%%eax\n"
- "movl %%eax,4(%%ecx)\n"
- "movl %3,%%eax\n"
- "movl %%eax,(%%ecx)\n"
- /* %eax = syscall(%eax = __NR_clone,
- * %ebx = flags,
- * %ecx = child_stack,
- * %edx = parent_tidptr,
- * %esi = newtls,
- * %edi = child_tidptr)
- * Also, make sure that %ebx gets preserved as it is
- * used in PIC mode.
- */
- "movl %8,%%esi\n"
- "movl %7,%%edx\n"
- "movl %5,%%eax\n"
- "movl %9,%%edi\n"
- "pushl %%ebx\n"
- "movl %%eax,%%ebx\n"
- "movl %2,%%eax\n"
- LSS_ENTRYPOINT
- /* In the parent: restore %ebx
- * In the child: move "fn" into %ebx
- */
- "popl %%ebx\n"
- /* if (%eax != 0)
- * return %eax;
- */
- "test %%eax,%%eax\n"
- "jnz 1f\n"
- /* In the child, now. Terminate frame pointer chain.
- */
- "movl $0,%%ebp\n"
- /* Call "fn". "arg" is already on the stack.
- */
- "call *%%ebx\n"
- /* Call _exit(%ebx). Unfortunately older versions
- * of gcc restrict the number of arguments that can
- * be passed to asm(). So, we need to hard-code the
- * system call number.
- */
- "movl %%eax,%%ebx\n"
- "movl $1,%%eax\n"
- LSS_ENTRYPOINT
- /* Return to parent.
- */
- "1:\n"
- : "=a" (__res)
- : "0"(-EINVAL), "i"(__NR_clone),
- "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
- "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
- : "esp", "memory", "ecx", "edx", "esi", "edi");
- LSS_RETURN(int, __res);
- }
- #define __NR__fadvise64_64 __NR_fadvise64_64
- LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
- unsigned, offset_lo, unsigned, offset_hi,
- unsigned, len_lo, unsigned, len_hi,
- int, advice)
- LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
- loff_t len, int advice) {
- return LSS_NAME(_fadvise64_64)(fd,
- (unsigned)offset, (unsigned)(offset >>32),
- (unsigned)len, (unsigned)(len >> 32),
- advice);
- }
- #define __NR__fallocate __NR_fallocate
- LSS_INLINE _syscall6(int, _fallocate, int, fd,
- int, mode,
- unsigned, offset_lo, unsigned, offset_hi,
- unsigned, len_lo, unsigned, len_hi)
- LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,
- loff_t offset, loff_t len) {
- union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };
- return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);
- }
- LSS_INLINE _syscall1(int, set_thread_area, void *, u)
- LSS_INLINE _syscall1(int, get_thread_area, void *, u)
- LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
- /* On i386, the kernel does not know how to return from a signal
- * handler. Instead, it relies on user space to provide a
- * restorer function that calls the {rt_,}sigreturn() system call.
- * Unfortunately, we cannot just reference the glibc version of this
- * function, as glibc goes out of its way to make it inaccessible.
- */
- void (*res)(void);
- __asm__ __volatile__("call 2f\n"
- "0:.align 16\n"
- "1:movl %1,%%eax\n"
- LSS_ENTRYPOINT
- "2:popl %0\n"
- "addl $(1b-0b),%0\n"
- : "=a" (res)
- : "i" (__NR_rt_sigreturn));
- return res;
- }
- LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
- /* On i386, the kernel does not know how to return from a signal
- * handler. Instead, it relies on user space to provide a
- * restorer function that calls the {rt_,}sigreturn() system call.
- * Unfortunately, we cannot just reference the glibc version of this
- * function, as glibc goes out of its way to make it inaccessible.
- */
- void (*res)(void);
- __asm__ __volatile__("call 2f\n"
- "0:.align 16\n"
- "1:pop %%eax\n"
- "movl %1,%%eax\n"
- LSS_ENTRYPOINT
- "2:popl %0\n"
- "addl $(1b-0b),%0\n"
- : "=a" (res)
- : "i" (__NR_sigreturn));
- return res;
- }
- #elif defined(__x86_64__)
- /* There are no known problems with any of the _syscallX() macros
- * currently shipping for x86_64, but we still need to be able to define
- * our own version so that we can override the location of the errno
- * location (e.g. when using the clone() system call with the CLONE_VM
- * option).
- */
- #undef LSS_ENTRYPOINT
- #ifdef SYS_SYSCALL_ENTRYPOINT
- static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) {
- void (**entrypoint)(void);
- asm volatile(".bss\n"
- ".align 8\n"
- ".globl "SYS_SYSCALL_ENTRYPOINT"\n"
- ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n"
- ".previous\n"
- "mov "SYS_SYSCALL_ENTRYPOINT"@GOTPCREL(%%rip), %0\n"
- : "=r"(entrypoint));
- return entrypoint;
- }
- #define LSS_ENTRYPOINT \
- ".bss\n" \
- ".align 8\n" \
- ".globl "SYS_SYSCALL_ENTRYPOINT"\n" \
- ".common "SYS_SYSCALL_ENTRYPOINT",8,8\n" \
- ".previous\n" \
- "mov "SYS_SYSCALL_ENTRYPOINT"@GOTPCREL(%%rip), %%rcx\n" \
- "mov 0(%%rcx), %%rcx\n" \
- "test %%rcx, %%rcx\n" \
- "jz 10001f\n" \
- "call *%%rcx\n" \
- "jmp 10002f\n" \
- "10001:syscall\n" \
- "10002:\n"
- #else
- #define LSS_ENTRYPOINT "syscall\n"
- #endif
- #undef LSS_BODY
- #define LSS_BODY(type,name, ...) \
- long __res; \
- __asm__ __volatile__(LSS_ENTRYPOINT \
- : "=a" (__res) : "0" (__NR_##name), \
- ##__VA_ARGS__ : "r11", "rcx", "memory"); \
- LSS_RETURN(type, __res)
- #undef _syscall0
- #define _syscall0(type,name) \
- type LSS_NAME(name)() { \
- LSS_BODY(type, name); \
- }
- #undef _syscall1
- #define _syscall1(type,name,type1,arg1) \
- type LSS_NAME(name)(type1 arg1) { \
- LSS_BODY(type, name, "D" ((long)(arg1))); \
- }
- #undef _syscall2
- #define _syscall2(type,name,type1,arg1,type2,arg2) \
- type LSS_NAME(name)(type1 arg1, type2 arg2) { \
- LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \
- }
- #undef _syscall3
- #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
- type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
- LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \
- "d" ((long)(arg3))); \
- }
- #undef _syscall4
- #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
- type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
- long __res; \
- __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \
- "=a" (__res) : "0" (__NR_##name), \
- "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
- "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \
- LSS_RETURN(type, __res); \
- }
- #undef _syscall5
- #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
- type5,arg5) \
- type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
- type5 arg5) { \
- long __res; \
- __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\
- "=a" (__res) : "0" (__NR_##name), \
- "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
- "r" ((long)(arg4)), "r" ((long)(arg5)) : \
- "r8", "r10", "r11", "rc