1 /* clone_linux.c -- consistent wrapper around Linux clone syscall
3 Copyright 2016 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
8 #include <sys/syscall.h>
12 long rawClone (unsigned long flags
, void *child_stack
, void *ptid
,
13 void *ctid
, void *regs
)
14 __asm__ (GOSYM_PREFIX
"syscall.rawClone")
15 __attribute__ ((no_split_stack
));
18 rawClone (unsigned long flags
, void *child_stack
, void *ptid
, void *ctid
, void *regs
)
20 #if defined(__arc__) || defined(__aarch64__) || defined(__arm__) || defined(__mips__) || defined(__hppa__) || defined(__powerpc__) || defined(__score__) || defined(__i386__) || defined(__xtensa__)
22 return syscall(__NR_clone
, flags
, child_stack
, ptid
, regs
, ctid
);
23 #elif defined(__s390__) || defined(__cris__)
25 return syscall(__NR_clone
, child_stack
, flags
, ptid
, ctid
, regs
);
26 #elif defined(__microblaze__)
28 return syscall(__NR_clone
, flags
, child_stack
, 0, ptid
, ctid
, regs
);
29 #elif defined(__sparc__)
31 /* SPARC has a unique return value convention:
33 Parent --> %o0 == child's pid, %o1 == 0
34 Child --> %o0 == parent's pid, %o1 == 1
36 Translate this to look like a normal clone. */
38 # if defined(__arch64__)
40 # define SYSCALL_STRING \
44 "sub %%g0, %%o0, %%o0;" \
48 # define SYSCALL_CLOBBERS \
49 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
50 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
51 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
52 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
53 "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
54 "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
57 # else /* __arch64__ */
59 # define SYSCALL_STRING \
63 "sub %%g0, %%o0, %%o0;" \
67 # define SYSCALL_CLOBBERS \
68 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
69 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
70 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
71 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
74 # endif /* __arch64__ */
76 register long o0
__asm__ ("o0") = (long)flags
;
77 register long o1
__asm__ ("o1") = (long)child_stack
;
78 register long o2
__asm__ ("o2") = (long)ptid
;
79 register long o3
__asm__ ("o3") = (long)ctid
;
80 register long o4
__asm__ ("o4") = (long)regs
;
81 register long g1
__asm__ ("g1") = __NR_clone
;
83 __asm
__volatile (SYSCALL_STRING
:
84 "=r" (g1
), "=r" (o0
), "=r" (o1
) :
85 "0" (g1
), "1" (o0
), "2" (o1
),
86 "r" (o2
), "r" (o3
), "r" (o4
) :
89 if (__builtin_expect(g1
!= 0, 0))
100 return syscall(__NR_clone
, flags
, child_stack
, ptid
, ctid
, regs
);