clone.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. #include <tcb-offsets.h>
  21. #include <sysdep.h>
  22. #define CLONE_VM 0x00000100
  23. #define CLONE_THREAD 0x00010000
  24. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  25. pid_t *ptid, void *tls, pid_t *ctid); */
  26. .text
  27. ENTRY (__clone)
  28. save %sp,-96,%sp
  29. cfi_def_cfa_register(%fp)
  30. cfi_window_save
  31. cfi_register(%o7, %i7)
  32. /* sanity check arguments */
  33. orcc %i0,%g0,%g2
  34. be .Leinval
  35. orcc %i1,%g0,%o1
  36. be .Leinval
  37. mov %i2,%o0
  38. /* The child_stack is the top of the stack, allocate one
  39. whole stack frame from that as this is what the kernel
  40. expects. */
  41. sub %o1, 96, %o1
  42. mov %i3, %g3
  43. mov %i2, %g4
  44. /* ptid */
  45. mov %i4,%o2
  46. /* tls */
  47. mov %i5,%o3
  48. /* ctid */
  49. ld [%fp+92],%o4
  50. /* Do the system call */
  51. set __NR_clone,%g1
  52. ta 0x10
  53. bcs .Lerror
  54. tst %o1
  55. bne __thread_start
  56. nop
  57. jmpl %i7 + 8, %g0
  58. restore %o0,%g0,%o0
  59. .Leinval:
  60. mov EINVAL, %o0
  61. .Lerror:
  62. call __errno_location
  63. mov %o0, %i0
  64. st %i0,[%o0]
  65. jmpl %i7 + 8, %g0
  66. restore %g0,-1,%o0
  67. END(__clone)
  68. .type __thread_start,@function
  69. __thread_start:
  70. #ifdef RESET_PID
  71. sethi %hi(CLONE_THREAD), %l0
  72. andcc %g4, %l0, %g0
  73. bne 1f
  74. andcc %g4, CLONE_VM, %g0
  75. bne,a 2f
  76. mov -1,%o0
  77. set __NR_getpid,%g1
  78. ta 0x10
  79. 2:
  80. st %o0,[%g7 + PID]
  81. st %o0,[%g7 + TID]
  82. 1:
  83. #endif
  84. mov %g0, %fp /* terminate backtrace */
  85. call %g2
  86. mov %g3,%o0
  87. call exit,0
  88. nop
  89. .size __thread_start, .-__thread_start
  90. weak_alias (__clone, clone)