Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Unified Diff: linux_syscall_support.h

Issue 220933002: Add arm64 support to linux_syscall_support.h (Closed) Base URL: http://linux-syscall-support.googlecode.com/svn/trunk/lss
Patch Set: Add comment. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: linux_syscall_support.h
diff --git a/linux_syscall_support.h b/linux_syscall_support.h
index 1ca17fdefdd2b5dc0382a50fefdbf632b26549b3..007c6b25ed6e90ae43b8fde0382edb4af4642ac5 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 long __r##r __asm__("x"#r) = (long)a
+ #undef LSS_BODY
+ #define LSS_BODY(type,name,args...) \
+ register long __res_x0 __asm__("x0"); \
+ long __res; \
+ __asm__ __volatile__ ("mov x8, %1\n" \
+ "svc 0x0\n" \
+ : "=r"(__res_x0) \
+ : "i"(__NR_##name) , ## args \
+ : "x8", "x30", "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) {
+ long __res;
+ {
+ register int __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;
+ */
+ "adds %0, xzr, x0\n"
rmcilroy 2014/04/15 09:18:48 Jacob: Note - this is really meant to be a "movs %
+ "bne 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", "x30", "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. */
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698