clone.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* Copyright (C) 1999, 2000, 2003, 2004, 2007 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 its all over. */
  15. #include <features.h>
  16. #include <asm/unistd.h>
  17. #include <sysdep.h>
  18. #define _ERRNO_H 1
  19. #include <bits/errno.h>
  20. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  21. pid_t *ptid, void *tls, pid_t *ctid); */
  22. .text
  23. ENTRY(__clone)
  24. /* sanity check arguments. */
  25. tst r4, r4
  26. bt/s 0f
  27. tst r5, r5
  28. bf 1f
  29. 0:
  30. bra .Lsyscall_error
  31. mov #-EINVAL,r0
  32. 1:
  33. /* insert the args onto the new stack */
  34. mov.l r7, @-r5
  35. /* save the function pointer as the 0th element */
  36. mov.l r4, @-r5
  37. /* do the system call */
  38. mov r6, r4
  39. mov.l @r15, r6
  40. mov.l @(8,r15), r7
  41. mov.l @(4,r15), r0
  42. mov #+SYS_ify(clone), r3
  43. trapa #0x15
  44. mov r0, r1
  45. #ifdef __sh2__
  46. /* 12 arithmetic shifts for the sh2, because shad doesn't exist! */
  47. shar r1
  48. shar r1
  49. shar r1
  50. shar r1
  51. shar r1
  52. shar r1
  53. shar r1
  54. shar r1
  55. shar r1
  56. shar r1
  57. shar r1
  58. shar r1
  59. #else
  60. mov #-12, r2
  61. shad r2, r1
  62. #endif
  63. not r1, r1 // r1=0 means r0 = -1 to -4095
  64. tst r1, r1 // i.e. error in linux
  65. bf .Lclone_end
  66. .Lsyscall_error:
  67. SYSCALL_ERROR_HANDLER
  68. .Lclone_end:
  69. tst r0, r0
  70. bt 2f
  71. .Lpseudo_end:
  72. rts
  73. nop
  74. 2:
  75. /* terminate the stack frame */
  76. mov #0, r14
  77. /* thread starts */
  78. mov.l @r15, r1
  79. jsr @r1
  80. mov.l @(4,r15), r4
  81. /* we are done, passing the return value through r0 */
  82. mov.l .L3, r1
  83. #ifdef SHARED
  84. mov.l r12, @-r15
  85. sts.l pr, @-r15
  86. mov r0, r4
  87. mova .LG, r0
  88. mov.l .LG, r12
  89. add r0, r12
  90. mova .L3, r0
  91. add r0, r1
  92. jsr @r1
  93. nop
  94. lds.l @r15+, pr
  95. rts
  96. mov.l @r15+, r12
  97. #else
  98. jmp @r1
  99. mov r0, r4
  100. #endif
  101. .align 2
  102. .LG:
  103. .long _GLOBAL_OFFSET_TABLE_
  104. .L3:
  105. .long PLTJMP(C_SYMBOL_NAME(_exit))
  106. PSEUDO_END (__clone)
  107. weak_alias (__clone, clone)