clone.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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, see
  14. <http://www.gnu.org/licenses/>. */
  15. /* clone() is even more special than fork() as it mucks with stacks
  16. and invokes a function in the right context after its all over. */
  17. #include <asm/errno.h>
  18. #include <asm/unistd.h>
  19. #include <tcb-offsets.h>
  20. #include <sysdep.h>
  21. #define CLONE_VM 0x00000100
  22. #define CLONE_THREAD 0x00010000
  23. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  24. pid_t *ptid, void *tls, pid_t *ctid); */
  25. .register %g2,#scratch
  26. .register %g3,#scratch
  27. .text
  28. ENTRY (__clone)
  29. save %sp, -192, %sp
  30. cfi_def_cfa_register(%fp)
  31. cfi_window_save
  32. cfi_register(%o7, %i7)
  33. /* sanity check arguments */
  34. brz,pn %i0, 99f /* fn non-NULL? */
  35. mov %i0, %g2
  36. brz,pn %i1, 99f /* child_stack non-NULL? */
  37. mov %i2, %o0 /* clone flags */
  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. Also, subtract STACK_BIAS. */
  41. sub %i1, 192 + 0x7ff, %o1
  42. mov %i3, %g3
  43. mov %i2, %g4
  44. mov %i4,%o2 /* PTID */
  45. mov %i5,%o3 /* TLS */
  46. ldx [%fp+0x7ff+176],%o4 /* CTID */
  47. /* Do the system call */
  48. set __NR_clone, %g1
  49. ta 0x6d
  50. bcs,pn %xcc, 98f
  51. nop
  52. brnz,pn %o1, __thread_start
  53. nop
  54. jmpl %i7 + 8, %g0
  55. restore %o0, %g0, %o0
  56. 99: mov EINVAL, %o0
  57. 98: call HIDDEN_JUMPTARGET(__errno_location)
  58. mov %o0, %i0
  59. st %i0, [%o0]
  60. jmpl %i7 + 8, %g0
  61. restore %g0,-1,%o0
  62. END(__clone)
  63. .type __thread_start,@function
  64. __thread_start:
  65. #ifdef RESET_PID
  66. sethi %hi(CLONE_THREAD), %l0
  67. andcc %g4, %l0, %g0
  68. bne,pt %icc, 1f
  69. andcc %g4, CLONE_VM, %g0
  70. bne,a,pn %icc, 2f
  71. mov -1,%o0
  72. set __NR_getpid,%g1
  73. ta 0x6d
  74. 2: st %o0,[%g7 + PID]
  75. st %o0,[%g7 + TID]
  76. 1:
  77. #endif
  78. mov %g0, %fp /* terminate backtrace */
  79. call %g2
  80. mov %g3,%o0
  81. call HIDDEN_JUMPTARGET(_exit),0
  82. nop
  83. .size __thread_start, .-__thread_start
  84. weak_alias (__clone, clone)