clone.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /* Copyright (C) 1997, 2000, 2007 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Richard Henderson (rth@tamu.edu).
  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, write to the Free
  14. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA. */
  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. .register %g2,#scratch
  27. .register %g3,#scratch
  28. .text
  29. ENTRY (__clone)
  30. save %sp, -192, %sp
  31. cfi_def_cfa_register(%fp)
  32. cfi_window_save
  33. cfi_register(%o7, %i7)
  34. /* sanity check arguments */
  35. brz,pn %i0, 99f /* fn non-NULL? */
  36. mov %i0, %g2
  37. brz,pn %i1, 99f /* child_stack non-NULL? */
  38. mov %i2, %o0 /* clone flags */
  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. Also, subtract STACK_BIAS. */
  42. sub %i1, 192 + 0x7ff, %o1
  43. mov %i3, %g3
  44. mov %i2, %g4
  45. mov %i4,%o2 /* PTID */
  46. mov %i5,%o3 /* TLS */
  47. ldx [%fp+0x7ff+176],%o4 /* CTID */
  48. /* Do the system call */
  49. set __NR_clone, %g1
  50. ta 0x6d
  51. bcs,pn %xcc, 98f
  52. nop
  53. brnz,pn %o1, __thread_start
  54. nop
  55. jmpl %i7 + 8, %g0
  56. restore %o0, %g0, %o0
  57. 99: mov EINVAL, %o0
  58. 98: call HIDDEN_JUMPTARGET(__errno_location)
  59. mov %o0, %i0
  60. st %i0, [%o0]
  61. jmpl %i7 + 8, %g0
  62. restore %g0,-1,%o0
  63. END(__clone)
  64. .type __thread_start,@function
  65. __thread_start:
  66. #ifdef RESET_PID
  67. sethi %hi(CLONE_THREAD), %l0
  68. andcc %g4, %l0, %g0
  69. bne,pt %icc, 1f
  70. andcc %g4, CLONE_VM, %g0
  71. bne,a,pn %icc, 2f
  72. mov -1,%o0
  73. set __NR_getpid,%g1
  74. ta 0x6d
  75. 2: st %o0,[%g7 + PID]
  76. st %o0,[%g7 + TID]
  77. 1:
  78. #endif
  79. mov %g0, %fp /* terminate backtrace */
  80. call %g2
  81. mov %g3,%o0
  82. call HIDDEN_JUMPTARGET(_exit),0
  83. nop
  84. .size __thread_start, .-__thread_start
  85. weak_alias (__clone, clone)