clone.S 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
  3. *
  4. * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
  5. */
  6. #include <asm/errno.h>
  7. #include <sys/syscall.h>
  8. #include <sysdep.h>
  9. ; Per man, libc clone( ) is as follows
  10. ;
  11. ; int clone(int (*fn)(void *), void *child_stack,
  12. ; int flags, void *arg, ...
  13. ; /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */);
  14. ;
  15. ; NOTE: I'm assuming that the last 3 args are NOT var-args and in case all
  16. ; 3 are not relevant, caller will nevertheless pass those as NULL.
  17. ; Current (Jul 2012) upstream powerpc/clone.S assumes similarly.
  18. ; Our LTP (from 2007) doesn't seem to have tests to prove otherwise
  19. ; clone syscall in kernel
  20. ;
  21. ; int sys_clone(unsigned long clone_flags, unsigned long newsp,
  22. ; int __user *parent_tidptr, void *tls,
  23. ; int __user *child_tidptr)
  24. ENTRY(clone)
  25. cmp r0, 0 ; @fn can't be NULL
  26. cmp.ne r1, 0 ; @child_stack can't be NULL
  27. bz .L__sys_err
  28. ; @fn and @args needed after the syscall for child
  29. ; However r3 containing @arg will be clobbered BEFORE syscall
  30. ; r0 containg @fn will be clobbered AFTER syscall (with ret val)
  31. mov r10, r0
  32. mov r11, r3
  33. ; adjust libc args for syscall
  34. mov r0, r2 ; libc @flags is 1st syscall arg
  35. mov r2, r4 ; libc @ptid
  36. mov r3, r5 ; libc @tls
  37. mov r4, r6 ; libc @ctid
  38. mov r8, __NR_clone
  39. ARC_TRAP_INSN
  40. cmp r0, 0 ; return code : 0 new process, !0 parent
  41. blt .L__sys_err2 ; < 0 (signed) error
  42. jnz [blink] ; Parent returns
  43. ; child jumps off to @fn with @arg as argument
  44. j.d [r10]
  45. mov r0, r11
  46. ; falls thru to _exit() with result from @fn (already in r0)
  47. b HIDDEN_JUMPTARGET(_exit)
  48. .L__sys_err:
  49. mov r0, -EINVAL
  50. .L__sys_err2:
  51. ; (1) No need to make -ve kernel error code as positive errno
  52. ; __syscall_error expects the -ve error code returned by kernel
  53. ; (2) r0 still had orig -ve kernel error code
  54. ; (3) Tail call to __syscall_error so we dont have to come back
  55. ; here hence instead of jmp-n-link (reg push/pop) we do jmp
  56. ; (4) No need to route __syscall_error via PLT, B is inherently
  57. ; position independent
  58. b __syscall_error
  59. END(clone)
  60. libc_hidden_def(clone)