clone_linux.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /* clone_linux.c -- consistent wrapper around Linux clone syscall
  2. Copyright 2016 The Go Authors. All rights reserved.
  3. Use of this source code is governed by a BSD-style
  4. license that can be found in the LICENSE file. */
  5. #include <errno.h>
  6. #include <sys/syscall.h>
  7. #include "runtime.h"
  8. long rawClone (unsigned long flags, void *child_stack, void *ptid,
  9. void *ctid, void *regs)
  10. __asm__ (GOSYM_PREFIX "syscall.rawClone")
  11. __attribute__ ((no_split_stack));
  12. long
  13. rawClone (unsigned long flags, void *child_stack, void *ptid, void *ctid, void *regs)
  14. {
  15. #if defined(__arc__) || defined(__aarch64__) || defined(__arm__) || defined(__mips__) || defined(__hppa__) || defined(__powerpc__) || defined(__score__) || defined(__i386__) || defined(__xtensa__)
  16. // CLONE_BACKWARDS
  17. return syscall(__NR_clone, flags, child_stack, ptid, regs, ctid);
  18. #elif defined(__s390__) || defined(__cris__)
  19. // CLONE_BACKWARDS2
  20. return syscall(__NR_clone, child_stack, flags, ptid, ctid, regs);
  21. #elif defined(__microblaze__)
  22. // CLONE_BACKWARDS3
  23. return syscall(__NR_clone, flags, child_stack, 0, ptid, ctid, regs);
  24. #elif defined(__sparc__)
  25. /* SPARC has a unique return value convention:
  26. Parent --> %o0 == child's pid, %o1 == 0
  27. Child --> %o0 == parent's pid, %o1 == 1
  28. Translate this to look like a normal clone. */
  29. # if defined(__arch64__)
  30. # define SYSCALL_STRING \
  31. "ta 0x6d;" \
  32. "bcc,pt %%xcc, 1f;" \
  33. " mov 0, %%g1;" \
  34. "sub %%g0, %%o0, %%o0;" \
  35. "mov 1, %%g1;" \
  36. "1:"
  37. # define SYSCALL_CLOBBERS \
  38. "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
  39. "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
  40. "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
  41. "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
  42. "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
  43. "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
  44. "cc", "memory"
  45. # else /* __arch64__ */
  46. # define SYSCALL_STRING \
  47. "ta 0x10;" \
  48. "bcc 1f;" \
  49. " mov 0, %%g1;" \
  50. "sub %%g0, %%o0, %%o0;" \
  51. "mov 1, %%g1;" \
  52. "1:"
  53. # define SYSCALL_CLOBBERS \
  54. "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
  55. "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
  56. "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
  57. "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
  58. "cc", "memory"
  59. # endif /* __arch64__ */
  60. register long o0 __asm__ ("o0") = (long)flags;
  61. register long o1 __asm__ ("o1") = (long)child_stack;
  62. register long o2 __asm__ ("o2") = (long)ptid;
  63. register long o3 __asm__ ("o3") = (long)ctid;
  64. register long o4 __asm__ ("o4") = (long)regs;
  65. register long g1 __asm__ ("g1") = __NR_clone;
  66. __asm __volatile (SYSCALL_STRING :
  67. "=r" (g1), "=r" (o0), "=r" (o1) :
  68. "0" (g1), "1" (o0), "2" (o1),
  69. "r" (o2), "r" (o3), "r" (o4) :
  70. SYSCALL_CLOBBERS);
  71. if (__builtin_expect(g1 != 0, 0))
  72. {
  73. errno = -o0;
  74. o0 = -1L;
  75. }
  76. else
  77. o0 &= (o1 - 1);
  78. return o0;
  79. #else
  80. return syscall(__NR_clone, flags, child_stack, ptid, ctid, regs);
  81. #endif
  82. }