clone.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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), %a0 /* no NULL function pointers */
  32. tstl %a0
  33. beq.w __syscall_error_trampoline
  34. movel 8(%sp), %a1 /* no NULL stack pointers */
  35. tstl %a1
  36. beq.w __syscall_error_trampoline
  37. /* Allocate space and copy the argument onto the new stack. */
  38. movel 16(%sp), -(%a1)
  39. /* Do the system call */
  40. movel 12(%sp), %d1 /* get flags */
  41. movel %d3, -(%a1) /* save %d3 and get parent_tidptr */
  42. movel %d3, -(%sp)
  43. cfi_adjust_cfa_offset (4)
  44. cfi_rel_offset (%d3, 0)
  45. movel 20+4(%sp), %d3
  46. movel %d4, -(%a1) /* save %d4 and get child_tidptr */
  47. movel %d4, -(%sp)
  48. cfi_adjust_cfa_offset (4)
  49. cfi_rel_offset (%d4, 0)
  50. movel 28+8(%sp), %d4
  51. movel %d5, -(%a1) /* save %d5 and get tls */
  52. movel %d5, -(%sp)
  53. cfi_adjust_cfa_offset (4)
  54. cfi_rel_offset (%d5, 0)
  55. movel 24+12(%sp), %d5
  56. /* save %d2 and get stack pointer */
  57. #ifdef __mcoldfire__
  58. movel %d2, -(%a1)
  59. movel %d2, -(%sp)
  60. cfi_adjust_cfa_offset (4)
  61. cfi_rel_offset (%d2, 0)
  62. movel %a1, %d2
  63. #else
  64. exg %d2, %a1 /* save %d2 and get stack pointer */
  65. cfi_register (%d2, %a1)
  66. #endif
  67. movel #__NR_clone, %d0
  68. /* End FDE now, because in the child the unwind info will be
  69. wrong. */
  70. cfi_endproc
  71. trap #0
  72. #ifdef __mcoldfire__
  73. movel (%sp)+, %d2
  74. #else
  75. exg %d2, %a1 /* restore %d2 */
  76. #endif
  77. movel (%sp)+, %d5 /* restore %d5, %d4 and %d3 */
  78. movel (%sp)+, %d4
  79. movel (%sp)+, %d3
  80. tstl %d0
  81. bmi.w __syscall_error_trampoline
  82. beq.w thread_start
  83. rts
  84. thread_start:
  85. cfi_startproc
  86. cfi_undefined (pc) /* Mark end of stack */
  87. subl %fp, %fp /* terminate the stack frame */
  88. jsr (%a0)
  89. movel %d0, %d1
  90. movel #__NR_exit, %d0
  91. trap #0
  92. cfi_endproc
  93. cfi_startproc
  94. __syscall_error_trampoline:
  95. JUMP __syscall_error,%a0
  96. .size __clone,.-__clone
  97. weak_alias(__clone,clone)
  98. libc_hidden_def(clone)