clone.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* Copyright (C) 1996, 1997, 1998, 2000, 2003, 2004, 2007
  2. Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Richard Henderson (rth@tamu.edu).
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. /* clone() is even more special than fork() as it mucks with stacks
  17. and invokes a function in the right context after its all over. */
  18. #include <asm/errno.h>
  19. #include <asm/unistd.h>
  20. #ifdef RESET_PID
  21. #include <tcb-offsets.h>
  22. #endif
  23. #include <sysdep.h>
  24. #define CLONE_VM 0x00000100
  25. #define CLONE_THREAD 0x00010000
  26. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  27. pid_t *ptid, void *tls, pid_t *ctid); */
  28. .text
  29. ENTRY (__clone)
  30. save %sp,-96,%sp
  31. cfi_def_cfa_register(%fp)
  32. cfi_window_save
  33. cfi_register(%o7, %i7)
  34. /* sanity check arguments */
  35. orcc %i0,%g0,%g2
  36. be .Leinval
  37. orcc %i1,%g0,%o1
  38. be .Leinval
  39. mov %i2,%o0
  40. /* The child_stack is the top of the stack, allocate one
  41. whole stack frame from that as this is what the kernel
  42. expects. */
  43. sub %o1, 96, %o1
  44. mov %i3, %g3
  45. mov %i2, %g4
  46. /* ptid */
  47. mov %i4,%o2
  48. /* tls */
  49. mov %i5,%o3
  50. /* ctid */
  51. ld [%fp+92],%o4
  52. /* Do the system call */
  53. set __NR_clone,%g1
  54. ta 0x10
  55. bcs .Lerror
  56. tst %o1
  57. bne __thread_start
  58. nop
  59. jmpl %i7 + 8, %g0
  60. restore %o0,%g0,%o0
  61. .Leinval:
  62. mov EINVAL, %o0
  63. .Lerror:
  64. call __errno_location
  65. mov %o0, %i0
  66. st %i0,[%o0]
  67. jmpl %i7 + 8, %g0
  68. restore %g0,-1,%o0
  69. END(__clone)
  70. .type __thread_start,@function
  71. __thread_start:
  72. #ifdef RESET_PID
  73. sethi %hi(CLONE_THREAD), %l0
  74. andcc %g4, %l0, %g0
  75. bne 1f
  76. andcc %g4, CLONE_VM, %g0
  77. bne,a 2f
  78. mov -1,%o0
  79. set __NR_getpid,%g1
  80. ta 0x10
  81. 2:
  82. st %o0,[%g7 + PID]
  83. st %o0,[%g7 + TID]
  84. 1:
  85. #endif
  86. mov %g0, %fp /* terminate backtrace */
  87. call %g2
  88. mov %g3,%o0
  89. call exit,0
  90. nop
  91. .size __thread_start, .-__thread_start
  92. weak_alias (__clone, clone)