| Index: linux_syscall_support.h
|
| diff --git a/linux_syscall_support.h b/linux_syscall_support.h
|
| index 1ca17fdefdd2b5dc0382a50fefdbf632b26549b3..f790bfacd405cc785c93b68160432ec8aa298ac0 100644
|
| --- a/linux_syscall_support.h
|
| +++ b/linux_syscall_support.h
|
| @@ -86,7 +86,8 @@
|
| * 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(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \
|
| + defined(__aarch64__)) \
|
| && (defined(__linux) || defined(__ANDROID__))
|
|
|
| #ifndef SYS_CPLUSPLUS
|
| @@ -100,6 +101,7 @@ extern "C" {
|
|
|
| #include <errno.h>
|
| #include <fcntl.h>
|
| +#include <sched.h>
|
| #include <signal.h>
|
| #include <stdarg.h>
|
| #include <stddef.h>
|
| @@ -172,12 +174,17 @@ struct kernel_dirent64 {
|
| };
|
|
|
| /* include/linux/dirent.h */
|
| +#if defined(__aarch64__)
|
| +// aarch64 only defines dirent64, just uses that for dirent too.
|
| +#define kernel_dirent kernel_dirent64
|
| +#else
|
| struct kernel_dirent {
|
| long d_ino;
|
| long d_off;
|
| unsigned short d_reclen;
|
| char d_name[256];
|
| };
|
| +#endif
|
|
|
| /* include/linux/uio.h */
|
| struct kernel_iovec {
|
| @@ -256,6 +263,8 @@ struct kernel_old_sigaction {
|
| } __attribute__((packed,aligned(4)));
|
| #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
|
| #define kernel_old_sigaction kernel_sigaction
|
| +#elif defined(__aarch64__)
|
| + // No kernel_old_sigaction defined for arm64.
|
| #endif
|
|
|
| /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
|
| @@ -273,7 +282,7 @@ struct kernel_old_sigaction {
|
| #define KERNEL_NSIG 64
|
| #endif
|
|
|
| -/* include/asm-{arm,i386,mips,x86_64}/signal.h */
|
| +/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */
|
| struct kernel_sigset_t {
|
| unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
|
| (8*sizeof(unsigned long))];
|
| @@ -305,7 +314,7 @@ struct kernel_sockaddr {
|
| char sa_data[14];
|
| };
|
|
|
| -/* include/asm-{arm,i386,mips,ppc}/stat.h */
|
| +/* include/asm-{arm,aarch64,i386,mips,ppc}/stat.h */
|
| #ifdef __mips__
|
| #if _MIPS_SIM == _MIPS_SIM_ABI64
|
| struct kernel_stat {
|
| @@ -378,7 +387,7 @@ struct kernel_stat64 {
|
| };
|
| #endif
|
|
|
| -/* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */
|
| +/* include/asm-{arm,aarch64,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
|
| @@ -472,9 +481,32 @@ struct kernel_stat {
|
| int st_blocks;
|
| int st_pad4[14];
|
| };
|
| +#elif defined(__aarch64__)
|
| +struct kernel_stat {
|
| + unsigned long st_dev;
|
| + unsigned long st_ino;
|
| + unsigned int st_mode;
|
| + unsigned int st_nlink;
|
| + unsigned int st_uid;
|
| + unsigned int st_gid;
|
| + unsigned long st_rdev;
|
| + unsigned long __pad1;
|
| + long st_size;
|
| + int st_blksize;
|
| + int __pad2;
|
| + 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 int __unused4;
|
| + unsigned int __unused5;
|
| +};
|
| #endif
|
|
|
| -/* include/asm-{arm,i386,mips,x86_64,ppc}/statfs.h */
|
| +/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc}/statfs.h */
|
| #ifdef __mips__
|
| #if _MIPS_SIM != _MIPS_SIM_ABI64
|
| struct kernel_statfs64 {
|
| @@ -559,7 +591,7 @@ struct kernel_statfs {
|
|
|
| /* Definitions missing from the standard header files */
|
| #ifndef O_DIRECTORY
|
| -#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
|
| +#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__)
|
| #define O_DIRECTORY 0040000
|
| #else
|
| #define O_DIRECTORY 0200000
|
| @@ -913,6 +945,102 @@ struct kernel_statfs {
|
| #define __NR_getcpu (__NR_SYSCALL_BASE + 345)
|
| #endif
|
| /* End of ARM 3/EABI definitions */
|
| +#elif defined(__aarch64__)
|
| +#ifndef __NR_setxattr
|
| +#define __NR_setxattr 5
|
| +#endif
|
| +#ifndef __NR_lsetxattr
|
| +#define __NR_lsetxattr 6
|
| +#endif
|
| +#ifndef __NR_getxattr
|
| +#define __NR_getxattr 8
|
| +#endif
|
| +#ifndef __NR_lgetxattr
|
| +#define __NR_lgetxattr 9
|
| +#endif
|
| +#ifndef __NR_listxattr
|
| +#define __NR_listxattr 11
|
| +#endif
|
| +#ifndef __NR_llistxattr
|
| +#define __NR_llistxattr 12
|
| +#endif
|
| +#ifndef __NR_ioprio_set
|
| +#define __NR_ioprio_set 30
|
| +#endif
|
| +#ifndef __NR_ioprio_get
|
| +#define __NR_ioprio_get 31
|
| +#endif
|
| +#ifndef __NR_unlinkat
|
| +#define __NR_unlinkat 35
|
| +#endif
|
| +#ifndef __NR_fallocate
|
| +#define __NR_fallocate 47
|
| +#endif
|
| +#ifndef __NR_openat
|
| +#define __NR_openat 56
|
| +#endif
|
| +#ifndef __NR_quotactl
|
| +#define __NR_quotactl 60
|
| +#endif
|
| +#ifndef __NR_getdents64
|
| +#define __NR_getdents64 61
|
| +#endif
|
| +#ifndef __NR_getdents
|
| +#define __NR_getdents __NR_getdents64
|
| +#endif
|
| +#ifndef __NR_pread64
|
| +#define __NR_pread64 67
|
| +#endif
|
| +#ifndef __NR_pwrite64
|
| +#define __NR_pwrite64 68
|
| +#endif
|
| +#ifndef __NR_ppoll
|
| +#define __NR_ppoll 73
|
| +#endif
|
| +#ifndef __NR_readlinkat
|
| +#define __NR_readlinkat 78
|
| +#endif
|
| +#ifndef __NR_newfstatat
|
| +#define __NR_newfstatat 79
|
| +#endif
|
| +#ifndef __NR_set_tid_address
|
| +#define __NR_set_tid_address 96
|
| +#endif
|
| +#ifndef __NR_futex
|
| +#define __NR_futex 98
|
| +#endif
|
| +#ifndef __NR_clock_gettime
|
| +#define __NR_clock_gettime 113
|
| +#endif
|
| +#ifndef __NR_clock_getres
|
| +#define __NR_clock_getres 114
|
| +#endif
|
| +#ifndef __NR_sched_setaffinity
|
| +#define __NR_sched_setaffinity 122
|
| +#define __NR_sched_getaffinity 123
|
| +#endif
|
| +#ifndef __NR_tkill
|
| +#define __NR_tkill 130
|
| +#endif
|
| +#ifndef __NR_setresuid
|
| +#define __NR_setresuid 147
|
| +#define __NR_getresuid 148
|
| +#define __NR_setresgid 149
|
| +#define __NR_getresgid 150
|
| +#endif
|
| +#ifndef __NR_gettid
|
| +#define __NR_gettid 178
|
| +#endif
|
| +#ifndef __NR_readahead
|
| +#define __NR_readahead 213
|
| +#endif
|
| +#ifndef __NR_fadvise64
|
| +#define __NR_fadvise64 223
|
| +#endif
|
| +#ifndef __NR_move_pages
|
| +#define __NR_move_pages 239
|
| +#endif
|
| +/* End of aarch64 definitions */
|
| #elif defined(__x86_64__)
|
| #ifndef __NR_pread64
|
| #define __NR_pread64 17
|
| @@ -1432,7 +1560,7 @@ struct kernel_statfs {
|
|
|
| #undef LSS_RETURN
|
| #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
|
| - || defined(__ARM_EABI__))
|
| + || defined(__ARM_EABI__) || defined(__aarch64__))
|
| /* Failing system calls return a negative result in the range of
|
| * -1..-4095. These are "errno" values with the sign inverted.
|
| */
|
| @@ -2315,6 +2443,123 @@ struct kernel_statfs {
|
| }
|
| LSS_RETURN(int, __res);
|
| }
|
| + #elif defined(__aarch64__)
|
| + /* 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_REG
|
| + #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a
|
| + #undef LSS_BODY
|
| + #define LSS_BODY(type,name,args...) \
|
| + register int64_t __res_x0 __asm__("x0"); \
|
| + int64_t __res; \
|
| + __asm__ __volatile__ ("mov x8, %1\n" \
|
| + "svc 0x0\n" \
|
| + : "=r"(__res_x0) \
|
| + : "i"(__NR_##name) , ## args \
|
| + : "x8", "memory"); \
|
| + __res = __res_x0; \
|
| + LSS_RETURN(type, __res)
|
| + #undef _syscall0
|
| + #define _syscall0(type, name) \
|
| + type LSS_NAME(name)(void) { \
|
| + LSS_BODY(type, name); \
|
| + }
|
| + #undef _syscall1
|
| + #define _syscall1(type, name, type1, arg1) \
|
| + type LSS_NAME(name)(type1 arg1) { \
|
| + LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
|
| + }
|
| + #undef _syscall2
|
| + #define _syscall2(type, name, type1, arg1, type2, arg2) \
|
| + type LSS_NAME(name)(type1 arg1, type2 arg2) { \
|
| + LSS_REG(0, arg1); LSS_REG(1, arg2); \
|
| + LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
|
| + }
|
| + #undef _syscall3
|
| + #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
|
| + type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
|
| + LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
|
| + LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
|
| + }
|
| + #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_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
|
| + LSS_REG(3, arg4); \
|
| + LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
|
| + }
|
| + #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) { \
|
| + LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
|
| + LSS_REG(3, arg4); LSS_REG(4, arg5); \
|
| + LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
|
| + "r"(__r4)); \
|
| + }
|
| + #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) { \
|
| + LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
|
| + LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
|
| + LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
|
| + "r"(__r4), "r"(__r5)); \
|
| + }
|
| +
|
| + LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
|
| + int flags, void *arg, int *parent_tidptr,
|
| + void *newtls, int *child_tidptr) {
|
| + int64_t __res;
|
| + {
|
| + register uint64_t __flags __asm__("x0") = flags;
|
| + register void *__stack __asm__("x1") = child_stack;
|
| + register void *__ptid __asm__("x2") = parent_tidptr;
|
| + register void *__tls __asm__("x3") = newtls;
|
| + register int *__ctid __asm__("x4") = child_tidptr;
|
| + __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be
|
| + * used by the child.
|
| + */
|
| + "stp %1, %4, [%2, #-16]!\n"
|
| +
|
| + /* %x0 = syscall(%x0 = flags,
|
| + * %x1 = child_stack,
|
| + * %x2 = parent_tidptr,
|
| + * %x3 = newtls,
|
| + * %x4 = child_tidptr)
|
| + */
|
| + "mov x8, %8\n"
|
| + "svc 0x0\n"
|
| +
|
| + /* if (%r0 != 0)
|
| + * return %r0;
|
| + */
|
| + "mov %0, x0\n"
|
| + "cbnz x0, 1f\n"
|
| +
|
| + /* In the child, now. Call "fn(arg)".
|
| + */
|
| + "ldp x1, x0, [sp], #16\n"
|
| + "blr x1\n"
|
| +
|
| + /* Call _exit(%r0).
|
| + */
|
| + "mov x8, %9\n"
|
| + "svc 0x0\n"
|
| + "1:\n"
|
| + : "=r" (__res)
|
| + : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
|
| + "r"(__ptid), "r"(__tls), "r"(__ctid),
|
| + "i"(__NR_clone), "i"(__NR_exit)
|
| + : "cc", "x8", "memory");
|
| + }
|
| + LSS_RETURN(int, __res);
|
| + }
|
| #elif defined(__mips__)
|
| #undef LSS_REG
|
| #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
|
| @@ -2728,15 +2973,21 @@ struct kernel_statfs {
|
| LSS_INLINE _syscall2(int, clock_gettime, int, c,
|
| struct kernel_timespec*, t)
|
| LSS_INLINE _syscall1(int, dup, int, f)
|
| - LSS_INLINE _syscall2(int, dup2, int, s,
|
| - int, d)
|
| + #if !defined(__aarch64__)
|
| + // The dup2 syscall has been deprecated on aarch64. We polyfill it below.
|
| + LSS_INLINE _syscall2(int, dup2, int, s,
|
| + int, d)
|
| + #endif
|
| LSS_INLINE _syscall3(int, execve, const char*, f,
|
| const char*const*,a,const char*const*, e)
|
| LSS_INLINE _syscall1(int, _exit, int, e)
|
| LSS_INLINE _syscall1(int, exit_group, int, e)
|
| LSS_INLINE _syscall3(int, fcntl, int, f,
|
| int, c, long, a)
|
| - LSS_INLINE _syscall0(pid_t, fork)
|
| + #if !defined(__aarch64__)
|
| + // The fork syscall has been deprecated on aarch64. We polyfill it below.
|
| + LSS_INLINE _syscall0(pid_t, fork)
|
| + #endif
|
| LSS_INLINE _syscall2(int, fstat, int, f,
|
| struct kernel_stat*, b)
|
| LSS_INLINE _syscall2(int, fstatfs, int, f,
|
| @@ -2754,12 +3005,15 @@ struct kernel_statfs {
|
| int, o, int, v,
|
| struct kernel_timespec*, t)
|
| LSS_INLINE _syscall3(int, getdents, int, f,
|
| - struct kernel_dirent*, d, int, c)
|
| + struct kernel_dirent*, d, int, c)
|
| LSS_INLINE _syscall3(int, getdents64, int, f,
|
| struct kernel_dirent64*, d, int, c)
|
| LSS_INLINE _syscall0(gid_t, getegid)
|
| LSS_INLINE _syscall0(uid_t, geteuid)
|
| - LSS_INLINE _syscall0(pid_t, getpgrp)
|
| + #if !defined(__aarch64__)
|
| + // The getgprp syscall has been deprecated on aarch64.
|
| + LSS_INLINE _syscall0(pid_t, getpgrp)
|
| + #endif
|
| LSS_INLINE _syscall0(pid_t, getpid)
|
| LSS_INLINE _syscall0(pid_t, getppid)
|
| LSS_INLINE _syscall2(int, getpriority, int, a,
|
| @@ -2818,10 +3072,14 @@ struct kernel_statfs {
|
| LSS_INLINE _syscall5(void*, _mremap, void*, o,
|
| size_t, os, size_t, ns,
|
| unsigned long, f, void *, a)
|
| - LSS_INLINE _syscall3(int, open, const char*, p,
|
| - int, f, int, m)
|
| - LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
|
| - unsigned int, n, int, t)
|
| + #if !defined(__aarch64__)
|
| + // The open and poll syscalls have been deprecated on aarch64. We polyfill
|
| + // them below.
|
| + LSS_INLINE _syscall3(int, open, const char*, p,
|
| + int, f, int, m)
|
| + LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
|
| + unsigned int, n, int, t)
|
| + #endif
|
| LSS_INLINE _syscall5(int, prctl, int, option,
|
| unsigned long, arg2,
|
| unsigned long, arg3,
|
| @@ -2836,8 +3094,11 @@ struct kernel_statfs {
|
| #endif
|
| LSS_INLINE _syscall3(ssize_t, read, int, f,
|
| void *, b, size_t, c)
|
| - LSS_INLINE _syscall3(int, readlink, const char*, p,
|
| - char*, b, size_t, s)
|
| + #if !defined(__aarch64__)
|
| + // The readlink syscall has been deprecated on aarch64. We polyfill below.
|
| + LSS_INLINE _syscall3(int, readlink, const char*, p,
|
| + char*, b, size_t, s)
|
| + #endif
|
| LSS_INLINE _syscall4(int, rt_sigaction, int, s,
|
| const struct kernel_sigaction*, a,
|
| struct kernel_sigaction*, o, size_t, c)
|
| @@ -2872,17 +3133,23 @@ struct kernel_statfs {
|
| LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
|
| const stack_t*, o)
|
| #if defined(__NR_sigreturn)
|
| - LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
|
| + LSS_INLINE _syscall1(int, sigreturn, unsigned long, u)
|
| + #endif
|
| + #if !defined(__aarch64__)
|
| + // The stat syscall has been deprecated on aarch64. We polyfill it below.
|
| + LSS_INLINE _syscall2(int, stat, const char*, f,
|
| + struct kernel_stat*, b)
|
| #endif
|
| - LSS_INLINE _syscall2(int, stat, const char*, f,
|
| - struct kernel_stat*, b)
|
| LSS_INLINE _syscall2(int, statfs, const char*, f,
|
| struct kernel_statfs*, b)
|
| LSS_INLINE _syscall3(int, tgkill, pid_t, p,
|
| pid_t, t, int, s)
|
| LSS_INLINE _syscall2(int, tkill, pid_t, p,
|
| int, s)
|
| - LSS_INLINE _syscall1(int, unlink, const char*, f)
|
| + #if !defined(__aarch64__)
|
| + // The unlink syscall has been deprecated on aarch64. We polyfill it below.
|
| + LSS_INLINE _syscall1(int, unlink, const char*, f)
|
| + #endif
|
| LSS_INLINE _syscall3(ssize_t, write, int, f,
|
| const void *, b, size_t, c)
|
| LSS_INLINE _syscall3(ssize_t, writev, int, f,
|
| @@ -2991,7 +3258,7 @@ struct kernel_statfs {
|
| }
|
| #endif
|
| #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
|
| - defined(__ARM_EABI__) || \
|
| + defined(__ARM_EABI__) || defined(__aarch64__) || \
|
| (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
|
| LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
|
| int*, s, int, o,
|
| @@ -3001,7 +3268,7 @@ struct kernel_statfs {
|
| return LSS_NAME(wait4)(pid, status, options, 0);
|
| }
|
| #endif
|
| - #if defined(__i386__) || defined(__x86_64__)
|
| + #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
|
| LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
|
| LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
|
| #endif
|
| @@ -3389,7 +3656,7 @@ struct kernel_statfs {
|
| LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
|
| }
|
| #endif
|
| - #if defined(__ARM_EABI__)
|
| + #if defined(__ARM_EABI__) || defined (__aarch64__)
|
| LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
|
| int, flags)
|
| LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
|
| @@ -3480,7 +3747,8 @@ struct kernel_statfs {
|
| return 0;
|
| }
|
| }
|
| - #else
|
| + #elif !defined(__aarch64__)
|
| + // The unlink syscall has been deprecated on aarch64. We polyfill it below.
|
| LSS_INLINE _syscall1(int, pipe, int *, p)
|
| #endif
|
| /* TODO(csilvers): see if ppc can/should support this as well */
|
| @@ -3658,6 +3926,84 @@ struct kernel_statfs {
|
| #endif
|
| #endif
|
|
|
| +#if defined(__aarch64__)
|
| + LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f)
|
| + LSS_INLINE _syscall6(void *, mmap, void *, addr, size_t, length, int, prot,
|
| + int, flags, int, fd, int64_t, offset)
|
| + LSS_INLINE _syscall4(int, newfstatat, int, dirfd, const char *, pathname,
|
| + struct kernel_stat *, buf, int, flags)
|
| + LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags)
|
| + LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u,
|
| + unsigned int, n, const struct kernel_timespec *, t,
|
| + const kernel_sigset_t *, sigmask, size_t, s)
|
| + LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b,
|
| + size_t, s)
|
| +#endif
|
| +
|
| +/*
|
| + * Polyfills for deprecated syscalls.
|
| + */
|
| +
|
| +#if defined(__aarch64__)
|
| + LSS_INLINE int LSS_NAME(dup2)(int s, int d) {
|
| + return LSS_NAME(dup3)(s, d, 0);
|
| + }
|
| +
|
| + LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) {
|
| + return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode);
|
| + }
|
| +
|
| + LSS_INLINE int LSS_NAME(unlink)(const char *pathname) {
|
| + return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0);
|
| + }
|
| +
|
| + LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer,
|
| + size_t size) {
|
| + return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size);
|
| + }
|
| +
|
| + LSS_INLINE pid_t LSS_NAME(pipe)(int *pipefd) {
|
| + return LSS_NAME(pipe2)(pipefd, 0);
|
| + }
|
| +
|
| + LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds,
|
| + int timeout) {
|
| + struct kernel_timespec timeout_ts;
|
| + struct kernel_timespec *timeout_ts_p = NULL;
|
| +
|
| + if (timeout >= 0) {
|
| + timeout_ts.tv_sec = timeout / 1000;
|
| + timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
|
| + timeout_ts_p = &timeout_ts;
|
| + }
|
| + return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0);
|
| + }
|
| +
|
| + LSS_INLINE int LSS_NAME(stat)(const char *pathname,
|
| + struct kernel_stat *buf) {
|
| + return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0);
|
| + }
|
| +
|
| + LSS_INLINE pid_t LSS_NAME(fork)(void) {
|
| + // No fork syscall on aarch64 - implement by means of the clone syscall.
|
| + // Note that this does not reset glibc's cached view of the PID/TID, so
|
| + // some glibc interfaces might go wrong in the forked subprocess.
|
| + int flags = SIGCHLD;
|
| + void *child_stack = NULL;
|
| + void *parent_tidptr = NULL;
|
| + void *newtls = NULL;
|
| + void *child_tidptr = NULL;
|
| +
|
| + LSS_REG(0, flags);
|
| + LSS_REG(1, child_stack);
|
| + LSS_REG(2, parent_tidptr);
|
| + LSS_REG(3, newtls);
|
| + LSS_REG(4, child_tidptr);
|
| + LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3),
|
| + "r"(__r4));
|
| + }
|
| +#endif
|
| +
|
| #ifdef __ANDROID__
|
| /* These restore the original values of these macros saved by the
|
| * corresponding #pragma push_macro near the top of this file. */
|
|
|