clone.S 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* Adapted from glibc */
  2. /* Copyright (C) 1996, 1997 Free Software Foundation, Inc. */
  3. /* clone is even more special than fork as it mucks with stacks
  4. and invokes a function in the right context after its all over. */
  5. #define _ERRNO_H
  6. #include <bits/errno.h>
  7. #include <sys/syscall.h>
  8. /* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
  9. .text
  10. .align 4
  11. .type __clone,@function
  12. .globl __clone;
  13. __clone:
  14. /* Sanity check arguments. */
  15. movel #-EINVAL, %d0
  16. movel 4(%sp), %d1 /* no NULL function pointers */
  17. movel %d1, %a0
  18. tstl %d1
  19. jeq syscall_error
  20. movel 8(%sp), %d1 /* no NULL stack pointers */
  21. movel %d1, %a1
  22. tstl %d1
  23. jeq syscall_error
  24. /* Allocate space and copy the argument onto the new stack. */
  25. movel 16(%sp), -(%a1)
  26. /* Do the system call */
  27. #if 1 /* defined (CONFIG_COLDFIRE) */
  28. movel %d2, %d1 /* save %d2 and get stack pointer */
  29. movel %a1, %d2
  30. movel %d1, %a1
  31. #else
  32. exg %d2, %a1 /* save %d2 and get stack pointer */
  33. #endif
  34. movel 12(%sp), %d1 /* get flags */
  35. movel #__NR_clone, %d0
  36. trap #0
  37. #if 1 /* defined (CONFIG_COLDFIRE) */
  38. movel %d2, %d1 /* restore %d2 */
  39. movel %a1, %d2
  40. movel %d1, %a1
  41. #else
  42. exg %d2, %a1 /* restore %d2 */
  43. #endif
  44. tstl %d0
  45. jmi syscall_error
  46. jeq thread_start
  47. rts
  48. syscall_error:
  49. negl %d0
  50. movel %d0, %sp@-
  51. lea __errno_location-.-8, %a0
  52. jsr 0(%pc, %a0)
  53. movel %d0, %a0
  54. movel %sp@+, %a0@
  55. moveq #-1, %d0
  56. rts
  57. thread_start:
  58. /*subl %fp, %fp*/ /* terminate the stack frame */
  59. jsr (%a0)
  60. movel %d0, -(%sp)
  61. movel #__NR_exit, %d0
  62. trap #0
  63. /*jsr exit*/