clone.S 2.5 KB

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