vfork.S 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * vfork for uClibc
  4. * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
  5. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  6. */
  7. #include <features.h>
  8. #include <bits/arm_asm.h>
  9. #define _ERRNO_H
  10. #include <bits/errno.h>
  11. #include <sys/syscall.h>
  12. #ifdef __NR_fork
  13. .text
  14. .global __vfork
  15. .hidden __vfork
  16. .type __vfork,%function
  17. .align 4
  18. #if defined(__thumb__) && !defined(__thumb2__)
  19. .thumb_func
  20. __vfork:
  21. #ifdef __NR_vfork
  22. DO_CALL (vfork)
  23. ldr r1, =0xfffff000
  24. cmp r0, r1
  25. bcs 1f
  26. bx lr
  27. 1:
  28. /* Check if vfork even exists. */
  29. ldr r1, =-ENOSYS
  30. cmp r0, r1
  31. bne __error
  32. /* If we don't have vfork, use fork. */
  33. DO_CALL (fork)
  34. ldr r1, =0xfffff000
  35. cmp r0, r1
  36. /* Syscall worked. Return to child/parent */
  37. bcs 1f
  38. bx lr
  39. 1:
  40. __error:
  41. push {r3, lr}
  42. bl __syscall_error
  43. POP_RET
  44. .pool
  45. #endif
  46. #else
  47. __vfork:
  48. #ifdef __NR_vfork
  49. DO_CALL (vfork)
  50. cmn r0, #4096
  51. IT(t, cc)
  52. #if defined(__USE_BX__)
  53. bxcc lr
  54. #else
  55. movcc pc, lr
  56. #endif
  57. /* Check if vfork even exists. */
  58. ldr r1, =-ENOSYS
  59. teq r0, r1
  60. bne __error
  61. #endif
  62. /* If we don't have vfork, use fork. */
  63. DO_CALL (fork)
  64. cmn r0, #4096
  65. /* Syscall worked. Return to child/parent */
  66. IT(t, cc)
  67. #if defined(__USE_BX__)
  68. bxcc lr
  69. #else
  70. movcc pc, lr
  71. #endif
  72. __error:
  73. b __syscall_error
  74. #endif
  75. .size __vfork,.-__vfork
  76. weak_alias(__vfork,vfork)
  77. libc_hidden_weak(vfork)
  78. #endif