clone.S 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. ! Copyright (C) 2013 Imagination Technologies Ltd.
  2. ! Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
  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. #include <asm/errno.h>
  6. #include <asm/unistd.h>
  7. #define CLONE_VM 0x00000100
  8. #define CLONE_THREAD 0x00010000
  9. #ifdef __PIC__
  10. #define __CLONE_METAG_LOAD_TP ___metag_load_tp@PLT
  11. #else
  12. #define __CLONE_METAG_LOAD_TP ___metag_load_tp
  13. #endif
  14. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  15. pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
  16. .text
  17. .global __clone
  18. .type __clone,function
  19. __clone:
  20. ! sanity check args
  21. MOV D0Re0, #-EINVAL
  22. CMP D1Ar1, #0
  23. BEQ ___error
  24. CMP D0Ar2, #0
  25. BEQ ___error
  26. ! save function pointer
  27. MOV D0FrT, D1Ar1
  28. ! do the system call
  29. MOV D1Ar1, D1Ar3
  30. MOV D1Ar3, D1Ar5
  31. MOV D1Ar5, D0Ar6
  32. MOV D0Ar6, D0Ar4
  33. GETD D0Ar4, [A0StP+#-4]
  34. ! new sp is already in D0Ar2
  35. MOV D1Re0, #__NR_clone
  36. SWITCH #0x440001
  37. CMP D0Re0,#0
  38. ! Error on -1
  39. BLT ___error
  40. ! If non-zero we are the parent
  41. MOVNE PC, D1RtP
  42. ! BRKPNT
  43. ! We are the child
  44. ! Rearrange the function arg and call address from registers
  45. MOV D0Ar2, D0FrT
  46. MOV D1Ar1, D0Ar6
  47. MOV D1RtP, PC
  48. ADD D1RtP, D1RtP, #8
  49. MOV PC, D0Ar2
  50. ! and we are done, passing the return value D0Re0 through D1Ar1
  51. MOV D1Ar1, D0Re0
  52. #ifdef __PIC__
  53. B _exit@PLT
  54. #else
  55. B _exit
  56. #endif
  57. ___error:
  58. MOV D1Ar1, D0Re0
  59. #ifdef __PIC__
  60. B ___syscall_error@PLT
  61. #else
  62. B ___syscall_error
  63. #endif
  64. .size __clone, .-__clone
  65. .weak _clone
  66. _clone = __clone