clone.S 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
  8. .text
  9. .global __clone
  10. .type __clone,function
  11. __clone:
  12. ! sanity check args
  13. MOV D0Re0, #-EINVAL
  14. CMP D1Ar1, #0
  15. BEQ ___error
  16. CMP D0Ar2, #0
  17. BEQ ___error
  18. ! save function pointer
  19. MOV D0FrT, D1Ar1
  20. ! do the system call
  21. ! get flags
  22. MOV D1Ar1, D1Ar3
  23. ! new sp is already in D0Ar2
  24. MOV D1Re0, #__NR_clone
  25. SWITCH #0x440001
  26. CMP D0Re0,#0
  27. ! Error on -1
  28. BLT ___error
  29. ! If non-zero we are the parent
  30. MOVNE PC, D1RtP
  31. ! BRKPNT
  32. ! We are the child
  33. ! pick the function arg and call address off the stack and execute
  34. MOV D0Ar2, D0FrT
  35. MOV D1Ar1, D0Ar4
  36. MOV D1RtP, PC
  37. ADD D1RtP, D1RtP, #8
  38. MOV PC, D0Ar2
  39. ! and we are done, passing the return value through D0Re0
  40. #ifdef __PIC__
  41. B _exit@PLT
  42. #else
  43. B _exit
  44. #endif
  45. ___error:
  46. MOV D1Ar1, D0Re0
  47. #ifdef __PIC__
  48. B ___syscall_error@PLT
  49. #else
  50. B ___syscall_error
  51. #endif
  52. .size __clone, .-__clone
  53. .weak _clone
  54. _clone = __clone