clone.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* Copyright (C) 1996-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de)
  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 <sysdep.h>
  18. #define _ERRNO_H 1
  19. #include <bits/errno.h>
  20. #include <tls.h>
  21. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  22. void *parent_tidptr, void *tls, void *child_tidptr) */
  23. .text
  24. ENTRY (__clone)
  25. /* Sanity check arguments. */
  26. movel #-EINVAL, %d0
  27. movel 4(%sp), %a0 /* no NULL function pointers */
  28. tstl %a0
  29. jeq SYSCALL_ERROR_LABEL
  30. movel 8(%sp), %a1 /* no NULL stack pointers */
  31. tstl %a1
  32. jeq SYSCALL_ERROR_LABEL
  33. /* Allocate space and copy the argument onto the new stack. */
  34. movel 16(%sp), -(%a1)
  35. /* Do the system call */
  36. movel 12+0(%sp), %d1 /* get flags */
  37. movel %d3, -(%a1) /* save %d3 and get parent_tidptr */
  38. movel %d3, -(%sp)
  39. cfi_adjust_cfa_offset (4)
  40. cfi_rel_offset (%d3, 0)
  41. movel 20+4(%sp), %d3
  42. movel %d4, -(%a1) /* save %d4 and get child_tidptr */
  43. movel %d4, -(%sp)
  44. cfi_adjust_cfa_offset (4)
  45. cfi_rel_offset (%d4, 0)
  46. movel 28+8(%sp), %d4
  47. movel %d5, -(%a1) /* save %d5 and get tls */
  48. movel %d5, -(%sp)
  49. cfi_adjust_cfa_offset (4)
  50. cfi_rel_offset (%d5, 0)
  51. movel 24+12(%sp), %d5
  52. /* save %d2 and get stack pointer */
  53. #ifdef __mcoldfire__
  54. movel %d2, -(%a1)
  55. movel %d2, -(%sp)
  56. cfi_adjust_cfa_offset (4)
  57. cfi_rel_offset (%d2, 0)
  58. movel %a1, %d2
  59. #else
  60. exg %d2, %a1 /* save %d2 and get stack pointer */
  61. cfi_register (%d2, %a1)
  62. #endif
  63. movel #SYS_ify (clone), %d0
  64. /* End FDE now, because in the child the unwind info will be
  65. wrong. */
  66. cfi_endproc
  67. trap #0
  68. #ifdef __mcoldfire__
  69. movel (%sp)+, %d2
  70. #else
  71. exg %d2, %a1 /* restore %d2 */
  72. #endif
  73. movel (%sp)+, %d5 /* restore %d5, %d4 and %d3 */
  74. movel (%sp)+, %d4
  75. movel (%sp)+, %d3
  76. tstl %d0
  77. jmi SYSCALL_ERROR_LABEL
  78. jeq 1f
  79. rts
  80. 1:
  81. cfi_startproc
  82. cfi_undefined (pc) /* Mark end of stack */
  83. subl %fp, %fp /* terminate the stack frame */
  84. jsr (%a0)
  85. movel %d0, %d1
  86. movel #SYS_ify (exit), %d0
  87. trap #0
  88. cfi_endproc
  89. cfi_startproc
  90. PSEUDO_END (__clone)
  91. libc_hidden_def (__clone)
  92. weak_alias (__clone, clone)