clone.S 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* Copyright (C) 1996-2017 Free Software Foundation, Inc.
  2. Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de)
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library. If not, see
  13. <http://www.gnu.org/licenses/>. */
  14. /* clone is even more special than fork as it mucks with stacks
  15. and invokes a function in the right context after its all over. */
  16. #define _ERRNO_H
  17. #include <sysdep.h>
  18. #include <features.h>
  19. #include <bits/errno.h>
  20. #include <sys/syscall.h>
  21. #include "m68k_pic.S"
  22. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  23. void *parent_tidptr, void *tls, void *child_tidptr) */
  24. .text
  25. .align 4
  26. .globl __clone
  27. .type __clone,@function
  28. __clone:
  29. /* Sanity check arguments. */
  30. movel #-EINVAL, %d0
  31. movel 4(%sp), %d1 /* no NULL function pointers */
  32. movel %d1, %a0
  33. tstl %d1
  34. beq.w __syscall_error_trampoline
  35. movel 8(%sp), %d1 /* no NULL stack pointers */
  36. movel %d1, %a1
  37. tstl %d1
  38. beq.w __syscall_error_trampoline
  39. /* Allocate space and copy the argument onto the new stack. */
  40. movel 16(%sp), -(%a1)
  41. /* Do the system call */
  42. movel 12(%sp), %d1 /* get flags */
  43. movel %d3, -(%a1) /* save %d3 and get parent_tidptr */
  44. movel %d3, -(%sp)
  45. cfi_adjust_cfa_offset (4)
  46. cfi_rel_offset (%d3, 0)
  47. movel 20+4(%sp), %d3
  48. movel %d4, -(%a1) /* save %d4 and get child_tidptr */
  49. movel %d4, -(%sp)
  50. cfi_adjust_cfa_offset (4)
  51. cfi_rel_offset (%d4, 0)
  52. movel 28+8(%sp), %d4
  53. movel %d5, -(%a1) /* save %d5 and get tls */
  54. movel %d5, -(%sp)
  55. cfi_adjust_cfa_offset (4)
  56. cfi_rel_offset (%d5, 0)
  57. movel 24+12(%sp), %d5
  58. /* save %d2 and get stack pointer */
  59. #ifdef __mcoldfire__
  60. movel %d2, -(%a1)
  61. movel %d2, -(%sp)
  62. cfi_adjust_cfa_offset (4)
  63. cfi_rel_offset (%d2, 0)
  64. movel %a1, %d2
  65. #else
  66. exg %d2, %a1 /* save %d2 and get stack pointer */
  67. cfi_register (%d2, %a1)
  68. #endif
  69. movel #__NR_clone, %d0
  70. /* End FDE now, because in the child the unwind info will be
  71. wrong. */
  72. cfi_endproc
  73. trap #0
  74. #ifdef __mcoldfire__
  75. movel (%sp)+, %d2
  76. #else
  77. exg %d2, %a1 /* restore %d2 */
  78. #endif
  79. movel (%sp)+, %d5 /* restore %d5, %d4 and %d3 */
  80. movel (%sp)+, %d4
  81. movel (%sp)+, %d3
  82. tstl %d0
  83. bmi.w __syscall_error_trampoline
  84. beq.w thread_start
  85. rts
  86. thread_start:
  87. cfi_startproc
  88. cfi_undefined (pc) /* Mark end of stack */
  89. subl %fp, %fp /* terminate the stack frame */
  90. jsr (%a0)
  91. movel %d0, %d1
  92. movel #__NR_exit, %d0
  93. trap #0
  94. cfi_endproc
  95. cfi_startproc
  96. __syscall_error_trampoline:
  97. JUMP __syscall_error,%a0
  98. .size __clone,.-__clone
  99. weak_alias(__clone,clone)
  100. libc_hidden_def(clone)