clone.S 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* Copyright (C) 2011-2018 Free Software Foundation, Inc.
  2. The GNU C Library is free software; you can redistribute it and/or
  3. modify it under the terms of the GNU Lesser General Public
  4. License as published by the Free Software Foundation; either
  5. version 2.1 of the License, or (at your option) any later version.
  6. The GNU C Library is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  9. Lesser General Public License for more details.
  10. You should have received a copy of the GNU Lesser General Public
  11. License along with the GNU C Library. If not, see
  12. <http://www.gnu.org/licenses/>. */
  13. /* clone() is even more special than fork() as it mucks with stacks
  14. and invokes a function in the right context after it's all over. */
  15. #include <sysdep.h>
  16. #define _ERRNO_H 1
  17. #include <bits/errno.h>
  18. #include <asm/unistd.h>
  19. #include <arch/abi.h>
  20. #include <linux/sched.h>
  21. /* What we save where in the stack frame; must include all callee-saves. */
  22. #define FRAME_NEXT_LR (0 * REGSIZE) /* reserved by ABI; not used here */
  23. #define FRAME_SP (1 * REGSIZE)
  24. #define FRAME_R30 (2 * REGSIZE)
  25. #define FRAME_R31 (3 * REGSIZE)
  26. #define FRAME_R32 (4 * REGSIZE)
  27. #define FRAME_SIZE (5 * REGSIZE)
  28. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  29. pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
  30. .text
  31. ENTRY (__clone)
  32. /* Create a stack frame so we can pass callee-saves to new task. */
  33. {
  34. move r10, sp
  35. st sp, lr
  36. ADDI_PTR sp, sp, -FRAME_SIZE
  37. }
  38. cfi_offset (lr, 0)
  39. cfi_def_cfa_offset (FRAME_SIZE)
  40. ADDI_PTR r11, sp, FRAME_SP
  41. {
  42. st r11, r10
  43. ADDI_PTR r11, sp, FRAME_R30
  44. }
  45. {
  46. st r11, r30
  47. ADDI_PTR r11, sp, FRAME_R31
  48. }
  49. cfi_offset (r30, FRAME_R30 - FRAME_SIZE)
  50. {
  51. st r11, r31
  52. ADDI_PTR r11, sp, FRAME_R32
  53. }
  54. cfi_offset (r31, FRAME_R31 - FRAME_SIZE)
  55. st r11, r32
  56. cfi_offset (r32, FRAME_R32 - FRAME_SIZE)
  57. /* sanity check arguments */
  58. beqz r0, .Linvalid
  59. beqz r1, .Linvalid
  60. /* Make sure child stack is properly aligned, and set up the
  61. top frame so that we can call out of it immediately in the
  62. child. Setting it up here means we fault in the parent if
  63. it's bogus, which is probably cleaner than faulting first
  64. thing in the child. */
  65. ADDI_PTR r1, r1, -C_ABI_SAVE_AREA_SIZE
  66. andi r1, r1, -C_ABI_SAVE_AREA_SIZE
  67. ADDI_PTR r9, r1, REGSIZE /* sp of this frame on entry, i.e. zero */
  68. st r9, zero
  69. /* We need to switch the argument convention around from
  70. libc to kernel:
  71. libc:
  72. r0 fn
  73. r1 child_stack
  74. r2 flags
  75. r3 arg
  76. r4 ptid
  77. r5 tls
  78. r6 ctid
  79. kernel:
  80. r0 flags
  81. r1 child_stack [same as libc]
  82. r2 ptid
  83. r3 ctid
  84. r4 tls
  85. Plus the callee-saves as described at .Lthread_start, below. */
  86. {
  87. move r32, r0
  88. move r0, r2
  89. }
  90. {
  91. move r31, r3
  92. move r3, r6
  93. }
  94. {
  95. move r30, r2
  96. move r2, r4
  97. }
  98. {
  99. move r4, r5
  100. moveli TREG_SYSCALL_NR_NAME, __NR_clone
  101. }
  102. swint1
  103. beqz r0, .Lthread_start /* If in child task. */
  104. .Ldone:
  105. /* Restore the callee-saved registers and return. */
  106. ADDLI_PTR lr, sp, FRAME_SIZE
  107. {
  108. ld lr, lr
  109. ADDLI_PTR r30, sp, FRAME_R30
  110. }
  111. {
  112. ld r30, r30
  113. ADDLI_PTR r31, sp, FRAME_R31
  114. }
  115. {
  116. ld r31, r31
  117. ADDLI_PTR r32, sp, FRAME_R32
  118. }
  119. {
  120. ld r32, r32
  121. ADDI_PTR sp, sp, FRAME_SIZE
  122. }
  123. cfi_def_cfa_offset (0)
  124. bnez r1, .Lerror
  125. jrp lr
  126. .Lerror:
  127. j SYSCALL_ERROR_NAME
  128. .Linvalid:
  129. {
  130. movei r1, EINVAL
  131. j .Ldone
  132. }
  133. /* This function expects to receive:
  134. sp: the top of a valid stack area
  135. r30: clone() flags
  136. r31: the argument to pass to the user function
  137. r32: the user function pointer */
  138. .Lthread_start:
  139. cfi_def_cfa_offset (FRAME_SIZE)
  140. cfi_undefined (lr)
  141. {
  142. /* Invoke user function with specified argument. */
  143. move r0, r31
  144. jalr r32
  145. }
  146. moveli TREG_SYSCALL_NR_NAME, __NR_exit
  147. swint1
  148. PSEUDO_END (__clone)
  149. libc_hidden_def (clone)
  150. weak_alias (__clone, clone)