clone.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, write to the Free
  13. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA. */
  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. #define _ERRNO_H 1
  18. #include <bits/errno.h>
  19. #include <sys/syscall.h>
  20. #define CLONE_VM 0x00000100
  21. #define CLONE_THREAD 0x00010000
  22. /* The userland implementation is:
  23. int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
  24. the kernel entry is:
  25. int clone (long flags, void *child_stack).
  26. The parameters are passed in register and on the stack from userland:
  27. rdi: fn
  28. rsi: child_stack
  29. rdx: flags
  30. rcx: arg
  31. r8d: TID field in parent
  32. r9d: thread pointer
  33. %esp+8: TID field in child
  34. The kernel expects:
  35. rax: system call number
  36. rdi: flags
  37. rsi: child_stack
  38. rdx: TID field in parent
  39. r10: TID field in child
  40. r8: thread pointer */
  41. .text
  42. .global __clone
  43. .type __clone,%function
  44. .align 4
  45. __clone:
  46. /* Sanity check arguments. */
  47. movq $-EINVAL,%rax
  48. testq %rdi,%rdi /* no NULL function pointers */
  49. jz __error
  50. testq %rsi,%rsi /* no NULL stack pointers */
  51. jz __error
  52. /* Insert the argument onto the new stack. */
  53. subq $16,%rsi
  54. movq %rcx,8(%rsi)
  55. /* Save the function pointer. It will be popped off in the
  56. child in the ebx frobbing below. */
  57. movq %rdi,0(%rsi)
  58. /* Do the system call. */
  59. movq %rdx, %rdi
  60. movq %r8, %rdx
  61. movq %r9, %r8
  62. movq 8(%rsp), %r10
  63. movl $__NR_clone,%eax
  64. syscall
  65. testq %rax,%rax
  66. jl __error
  67. jz .Lthread_start
  68. .Lpseudo_end:
  69. ret
  70. .Lthread_start:
  71. /* Clear the frame pointer. The ABI suggests this be done, to mark
  72. the outermost frame obviously. */
  73. xorl %ebp, %ebp
  74. #ifdef RESET_PID
  75. testq $CLONE_THREAD, %rdi
  76. jne 1f
  77. testq $CLONE_VM, %rdi
  78. movl $-1, %eax
  79. jne 2f
  80. movl $__NR_getpid, %eax
  81. syscall
  82. 2: movl %eax, %fs:PID
  83. movl %eax, %fs:TID
  84. 1:
  85. #endif
  86. /* Set up arguments for the function call. */
  87. popq %rax /* Function to call. */
  88. popq %rdi /* Argument. */
  89. call *%rax
  90. /* Call exit with return value from function call. */
  91. movq %rax, %rdi
  92. call _exit@PLT //HIDDEN_JUMPTARGET (_exit)
  93. __error:
  94. jmp __syscall_error
  95. .size __clone,.-__clone
  96. .weak clone
  97. clone = __clone