clone.S 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* Copyright (C) 1996-2018 Free Software Foundation, Inc.
  2. Contributed by David Huggins-Daines <dhd@debian.org>, 2000.
  3. Based on the Alpha version by Richard Henderson <rth@tamu.edu>, 1996.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library. If not, see
  14. <http://www.gnu.org/licenses/>. */
  15. /* clone() is even more special than fork() as it mucks with stacks
  16. and invokes a function in the right context after its all over. */
  17. #include <asm/unistd.h>
  18. #include <sysdep.h>
  19. #define _ERRNO_H 1
  20. #include <bits/errno.h>
  21. /* Non-thread code calls __clone with the following parameters:
  22. int clone(int (*fn)(void *arg),
  23. void *child_stack,
  24. int flags,
  25. void *arg)
  26. NPTL Code will call __clone with the following parameters:
  27. int clone(int (*fn)(void *arg),
  28. void *child_stack,
  29. int flags,
  30. void *arg,
  31. int *parent_tidptr,
  32. struct user_desc *newtls,
  33. int *child_pidptr)
  34. The code should not mangle the extra input registers.
  35. Syscall expects: Input to __clone:
  36. 4(r25) - function pointer (r26, arg0)
  37. 0(r25) - argument (r23, arg3)
  38. r26 - clone flags. (r24, arg2)
  39. r25+64 - user stack pointer. (r25, arg1)
  40. r24 - parent tid pointer. (stack - 52)
  41. r23 - struct user_desc newtls pointer. (stack - 56)
  42. r22 - child tid pointer. (stack - 60)
  43. r20 - clone syscall number (constant)
  44. Return:
  45. On success the thread ID of the child process is returend in
  46. the callers context.
  47. On error return -1, and set errno to the value returned by
  48. the syscall.
  49. */
  50. .text
  51. ENTRY(__clone)
  52. /* Prologue */
  53. stwm %r4, 64(%sp)
  54. .cfi_def_cfa_offset -64
  55. .cfi_offset 4, 0
  56. stw %sp, -4(%sp)
  57. #ifdef __PIC__
  58. stw %r19, -32(%sp)
  59. .cfi_offset 19, 32
  60. #endif
  61. /* Sanity check arguments. */
  62. comib,=,n 0, %arg0, .LerrorSanity /* no NULL function pointers */
  63. comib,=,n 0, %arg1, .LerrorSanity /* no NULL stack pointers */
  64. /* Save the function pointer, arg, and flags on the new stack. */
  65. stwm %r26, 64(%r25)
  66. stw %r23, -60(%r25)
  67. stw %r24, -56(%r25)
  68. /* Clone arguments are (int flags, void * child_stack) */
  69. copy %r24, %r26 /* flags are first */
  70. /* User stack pointer is in the correct register already */
  71. /* Load args from stack... */
  72. ldw -116(%sp), %r24 /* Load parent_tidptr */
  73. ldw -120(%sp), %r23 /* Load newtls */
  74. ldw -124(%sp), %r22 /* Load child_tidptr */
  75. /* Save the PIC register. */
  76. #ifdef __PIC__
  77. copy %r19, %r4 /* parent */
  78. #endif
  79. /* Do the system call */
  80. ble 0x100(%sr2, %r0)
  81. ldi __NR_clone, %r20
  82. ldi -4096, %r1
  83. comclr,>>= %r1, %ret0, %r0 /* Note: unsigned compare. */
  84. b,n .LerrorRest
  85. /* Restore the PIC register. */
  86. #ifdef __PIC__
  87. copy %r4, %r19 /* parent */
  88. #endif
  89. comib,=,n 0, %ret0, .LthreadStart
  90. /* Successful return from the parent
  91. No need to restore the PIC register,
  92. since we return immediately. */
  93. ldw -84(%sp), %rp
  94. bv %r0(%rp)
  95. ldwm -64(%sp), %r4
  96. .LerrorRest:
  97. /* Something bad happened -- no child created */
  98. bl __syscall_error, %rp
  99. sub %r0, %ret0, %arg0
  100. ldw -84(%sp), %rp
  101. /* Return after setting errno, ret0 is set to -1 by __syscall_error. */
  102. bv %r0(%rp)
  103. ldwm -64(%sp), %r4
  104. .LerrorSanity:
  105. /* Sanity checks failed, return -1, and set errno to EINVAL. */
  106. bl __syscall_error, %rp
  107. ldi EINVAL, %arg0
  108. ldw -84(%sp), %rp
  109. bv %r0(%rp)
  110. ldwm -64(%sp), %r4
  111. .LthreadStart:
  112. /* Load up the arguments. */
  113. ldw -60(%sp), %arg0
  114. ldw -64(%sp), %r22
  115. /* $$dyncall fixes child's PIC register */
  116. /* Call the user's function */
  117. #ifdef __PIC__
  118. copy %r19, %r4
  119. #endif
  120. bl $$dyncall, %r31
  121. copy %r31, %rp
  122. #ifdef __PIC__
  123. copy %r4, %r19
  124. #endif
  125. copy %r28, %r26
  126. ble 0x100(%sr2, %r0)
  127. ldi __NR_exit, %r20
  128. /* We should not return from exit.
  129. We do not restore r4, or the stack state. */
  130. iitlbp %r0, (%sr0, %r0)
  131. PSEUDO_END(__clone)
  132. libc_hidden_def (__clone)
  133. weak_alias (__clone, clone)