sysdep-cancel.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* Assembler macros with cancellation support, Nios II version.
  2. Copyright (C) 2003-2016 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <sysdep.h>
  16. #include <tls.h>
  17. #ifndef __ASSEMBLER__
  18. # include <pthreadP.h>
  19. #endif
  20. #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
  21. #ifdef __ASSEMBLER__
  22. # undef PSEUDO
  23. # define PSEUDO(name, syscall_name, args) \
  24. .type __##syscall_name##_nocancel, @function; \
  25. .globl __##syscall_name##_nocancel; \
  26. __##syscall_name##_nocancel: \
  27. cfi_startproc; \
  28. DO_CALL (syscall_name, args); \
  29. ret; \
  30. cfi_endproc; \
  31. .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
  32. ENTRY (name) \
  33. SINGLE_THREAD_P(r2); \
  34. bne r2, zero, pseudo_cancel; \
  35. DO_CALL (syscall_name, args); \
  36. ret; \
  37. pseudo_cancel: \
  38. SAVESTK_##args; /* save syscall args and adjust stack */ \
  39. SAVEREG(ra, 0); /* save return address */ \
  40. SAVEREG(r22, 4); /* save GOT pointer */ \
  41. nextpc r22; \
  42. 1: movhi r2, %hiadj(_gp_got - 1b); \
  43. addi r2, r2, %lo(_gp_got - 1b); \
  44. add r22, r22, r2; \
  45. CENABLE; \
  46. callr r3; \
  47. stw r2, 8(sp); /* save mask */ \
  48. LOADARGS_##args; \
  49. movi r2, SYS_ify(syscall_name); \
  50. trap; \
  51. stw r2, 12(sp); /* save syscall result */ \
  52. stw r7, 16(sp); /* save syscall error flag */ \
  53. ldw r4, 8(sp); /* pass mask as argument 1 */ \
  54. CDISABLE; \
  55. callr r3; \
  56. ldw r7, 16(sp); /* restore syscall error flag */ \
  57. ldw r2, 12(sp); /* restore syscall result */ \
  58. ldw ra, 0(sp); /* restore return address */ \
  59. ldw r22, 4(sp); /* restore GOT pointer */ \
  60. RESTORESTK_##args; \
  61. # undef PSEUDO_END
  62. # define PSEUDO_END(sym) \
  63. END (sym)
  64. #define SAVEREG(REG, LOC) stw REG, LOC(sp); cfi_rel_offset (REG, LOC)
  65. #define SAVESTK(X) subi sp, sp, X; cfi_adjust_cfa_offset(X)
  66. #define SAVESTK_0 SAVESTK(20)
  67. #define SAVEARG_1 SAVEREG(r4, 20)
  68. #define SAVESTK_1 SAVESTK(24); SAVEARG_1
  69. #define SAVEARG_2 SAVEREG(r5, 24); SAVEARG_1
  70. #define SAVESTK_2 SAVESTK(28); SAVEARG_2
  71. #define SAVEARG_3 SAVEREG(r6, 28); SAVEARG_2
  72. #define SAVESTK_3 SAVESTK(32); SAVEARG_3
  73. #define SAVEARG_4 SAVEREG(r7, 32); SAVEARG_3
  74. #define SAVESTK_4 SAVESTK(36); SAVEARG_4
  75. #define SAVESTK_5 SAVESTK_4
  76. #define SAVESTK_6 SAVESTK_5
  77. #define LOADARGS_0
  78. #define LOADARGS_1 ldw r4, 20(sp)
  79. #define LOADARGS_2 LOADARGS_1; ldw r5, 24(sp)
  80. #define LOADARGS_3 LOADARGS_2; ldw r6, 28(sp)
  81. #define LOADARGS_4 LOADARGS_3; ldw r7, 32(sp)
  82. #define LOADARGS_5 LOADARGS_4; ldw r8, 36(sp)
  83. #define LOADARGS_6 LOADARGS_5; ldw r9, 40(sp)
  84. #define RESTORESTK(X) addi sp, sp, X; cfi_adjust_cfa_offset(-X)
  85. #define RESTORESTK_0 RESTORESTK(20)
  86. #define RESTORESTK_1 RESTORESTK(24)
  87. #define RESTORESTK_2 RESTORESTK(28)
  88. #define RESTORESTK_3 RESTORESTK(32)
  89. #define RESTORESTK_4 RESTORESTK(36)
  90. #define RESTORESTK_5 RESTORESTK(36)
  91. #define RESTORESTK_6 RESTORESTK(36)
  92. # endif
  93. # ifdef IS_IN_libpthread
  94. # define CENABLE ldw r3, %call(__pthread_enable_asynccancel)(r22)
  95. # define CDISABLE ldw r3, %call(__pthread_disable_asynccancel)(r22)
  96. # elif defined IS_IN_librt
  97. # define CENABLE ldw r3, %call(__librt_enable_asynccancel)(r22)
  98. # define CDISABLE ldw r3, %call(__librt_disable_asynccancel)(r22)
  99. # elif !defined NOT_IN_libc
  100. # define CENABLE ldw r3, %call(__libc_enable_asynccancel)(r22)
  101. # define CDISABLE ldw r3, %call(__libc_disable_asynccancel)(r22)
  102. # else
  103. # error Unsupported library
  104. # endif
  105. # ifndef __ASSEMBLER__
  106. # define SINGLE_THREAD_P \
  107. __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
  108. header.multiple_threads) \
  109. == 0, 1)
  110. # else
  111. # define SINGLE_THREAD_P(reg) \
  112. ldw reg, MULTIPLE_THREADS_OFFSET(r23)
  113. # endif
  114. #elif !defined __ASSEMBLER__
  115. # define SINGLE_THREAD_P 1
  116. # define NO_CANCELLATION 1
  117. #endif
  118. #ifndef __ASSEMBLER__
  119. # define RTLD_SINGLE_THREAD_P \
  120. __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
  121. header.multiple_threads) == 0, 1)
  122. #endif