sysdep-cancel.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, write to the Free
  13. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA. */
  15. #include <tls.h>
  16. #include <sysdep.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. # define _IMM12 #-12
  22. # define _IMM16 #-16
  23. # define _IMP16 #16
  24. # undef PSEUDO
  25. # define PSEUDO(name, syscall_name, args) \
  26. .text; \
  27. ENTRY (name); \
  28. .Lpseudo_start: \
  29. SINGLE_THREAD_P; \
  30. bf .Lpseudo_cancel; \
  31. .type __##syscall_name##_nocancel,@function; \
  32. .globl __##syscall_name##_nocancel; \
  33. __##syscall_name##_nocancel: \
  34. DO_CALL (syscall_name, args); \
  35. mov r0,r1; \
  36. mov _IMM12,r2; \
  37. shad r2,r1; \
  38. not r1,r1; \
  39. tst r1,r1; \
  40. bt .Lsyscall_error; \
  41. bra .Lpseudo_end; \
  42. nop; \
  43. .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
  44. .Lpseudo_cancel: \
  45. sts.l pr,@-r15; \
  46. .LCFI0: \
  47. add _IMM16,r15; \
  48. SAVE_ARGS_##args; \
  49. .LCFI1: \
  50. CENABLE; \
  51. LOAD_ARGS_##args; \
  52. add _IMP16,r15; \
  53. .LCFI2: \
  54. lds.l @r15+,pr; \
  55. .LCFI3: \
  56. DO_CALL(syscall_name, args); \
  57. SYSCALL_INST_PAD; \
  58. sts.l pr,@-r15; \
  59. .LCFI4: \
  60. mov.l r0,@-r15; \
  61. .LCFI5: \
  62. CDISABLE; \
  63. mov.l @r15+,r0; \
  64. .LCFI6: \
  65. lds.l @r15+,pr; \
  66. .LCFI7: \
  67. mov r0,r1; \
  68. mov _IMM12,r2; \
  69. shad r2,r1; \
  70. not r1,r1; \
  71. tst r1,r1; \
  72. bf .Lpseudo_end; \
  73. .Lsyscall_error: \
  74. SYSCALL_ERROR_HANDLER; \
  75. .Lpseudo_end: \
  76. /* Create unwinding information for the syscall wrapper. */ \
  77. .section .eh_frame,"a",@progbits; \
  78. .Lframe1: \
  79. .ualong .LECIE1-.LSCIE1; \
  80. .LSCIE1: \
  81. .ualong 0x0; \
  82. .byte 0x1; \
  83. AUGMENTATION_STRING; \
  84. .uleb128 0x1; \
  85. .sleb128 -4; \
  86. .byte 0x11; \
  87. AUGMENTATION_PARAM; \
  88. .byte 0xc; \
  89. .uleb128 0xf; \
  90. .uleb128 0x0; \
  91. .align 2; \
  92. .LECIE1: \
  93. .LSFDE1: \
  94. .ualong .LEFDE1-.LASFDE1; \
  95. .LASFDE1: \
  96. .ualong .LASFDE1-.Lframe1; \
  97. START_SYMBOL_REF; \
  98. .ualong .Lpseudo_end - .Lpseudo_start; \
  99. AUGMENTATION_PARAM_FDE; \
  100. .byte 0x4; \
  101. .ualong .LCFI0-.Lpseudo_start; \
  102. .byte 0xe; \
  103. .uleb128 0x4; \
  104. .byte 0x91; \
  105. .uleb128 0x1; \
  106. .byte 0x4; \
  107. .ualong .LCFI1-.LCFI0; \
  108. .byte 0xe; \
  109. .uleb128 0x14; \
  110. FRAME_REG_##args; \
  111. .byte 0x4; \
  112. .ualong .LCFI2-.LCFI1; \
  113. .byte 0xe; \
  114. .uleb128 0x4; \
  115. .byte 0x4; \
  116. .ualong .LCFI3-.LCFI2; \
  117. .byte 0xe; \
  118. .uleb128 0x0; \
  119. .byte 0xd1; \
  120. .byte 0x4; \
  121. .ualong .LCFI4-.LCFI3; \
  122. .byte 0xe; \
  123. .uleb128 0x4; \
  124. .byte 0x91; \
  125. .uleb128 0x1; \
  126. .byte 0x4; \
  127. .ualong .LCFI5-.LCFI4; \
  128. .byte 0xe; \
  129. .uleb128 0x8; \
  130. .byte 0x80; \
  131. .uleb128 0x2; \
  132. .byte 0x4; \
  133. .ualong .LCFI6-.LCFI5; \
  134. .byte 0xe; \
  135. .uleb128 0x4; \
  136. .byte 0xc0; \
  137. .byte 0x4; \
  138. .ualong .LCFI7-.LCFI6; \
  139. .byte 0xe; \
  140. .uleb128 0x0; \
  141. .byte 0xd1; \
  142. .align 2; \
  143. .LEFDE1: \
  144. .previous
  145. # ifdef SHARED
  146. # define AUGMENTATION_STRING .string "zR"
  147. # define AUGMENTATION_PARAM .uleb128 1; .byte 0x1b
  148. # define AUGMENTATION_PARAM_FDE .uleb128 0
  149. # define START_SYMBOL_REF .long .Lpseudo_start-.
  150. # else
  151. # define AUGMENTATION_STRING .ascii "\0"
  152. # define AUGMENTATION_PARAM
  153. # define AUGMENTATION_PARAM_FDE
  154. # define START_SYMBOL_REF .long .Lpseudo_start
  155. # endif
  156. # define FRAME_REG_0 /* Nothing. */
  157. # define FRAME_REG_1 FRAME_REG_0; .byte 0x84; .uleb128 5
  158. # define FRAME_REG_2 FRAME_REG_1; .byte 0x85; .uleb128 4
  159. # define FRAME_REG_3 FRAME_REG_2; .byte 0x86; .uleb128 3
  160. # define FRAME_REG_4 FRAME_REG_3; .byte 0x87; .uleb128 2
  161. # define FRAME_REG_5 FRAME_REG_4
  162. # define FRAME_REG_6 FRAME_REG_5
  163. # undef PSEUDO_END
  164. # define PSEUDO_END(sym) \
  165. END (sym)
  166. # define SAVE_ARGS_0 /* Nothing. */
  167. # define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15)
  168. # define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15)
  169. # define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15)
  170. # define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15)
  171. # define SAVE_ARGS_5 SAVE_ARGS_4
  172. # define SAVE_ARGS_6 SAVE_ARGS_5
  173. # define LOAD_ARGS_0 /* Nothing. */
  174. # define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
  175. # define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
  176. # define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
  177. # define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
  178. # define LOAD_ARGS_5 LOAD_ARGS_4
  179. # define LOAD_ARGS_6 LOAD_ARGS_5
  180. # ifdef IS_IN_libpthread
  181. # define __local_enable_asynccancel __pthread_enable_asynccancel
  182. # define __local_disable_asynccancel __pthread_disable_asynccancel
  183. # elif !defined NOT_IN_libc
  184. # define __local_enable_asynccancel __libc_enable_asynccancel
  185. # define __local_disable_asynccancel __libc_disable_asynccancel
  186. # elif defined IS_IN_librt
  187. # define __local_enable_asynccancel __librt_enable_asynccancel
  188. # define __local_disable_asynccancel __librt_disable_asynccancel
  189. # else
  190. # error Unsupported library
  191. # endif
  192. # define CENABLE \
  193. mov.l 1f,r0; \
  194. bsrf r0; \
  195. nop; \
  196. 0: bra 2f; \
  197. mov r0,r2; \
  198. .align 2; \
  199. 1: .long __local_enable_asynccancel - 0b; \
  200. 2:
  201. # define CDISABLE \
  202. mov.l 1f,r0; \
  203. bsrf r0; \
  204. mov r2,r4; \
  205. 0: bra 2f; \
  206. nop; \
  207. .align 2; \
  208. 1: .long __local_disable_asynccancel - 0b; \
  209. 2:
  210. # ifndef __ASSEMBLER__
  211. # define SINGLE_THREAD_P \
  212. __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
  213. header.multiple_threads) == 0, 1)
  214. # else
  215. # define SINGLE_THREAD_P \
  216. stc gbr,r0; \
  217. mov.w 0f,r1; \
  218. sub r1,r0; \
  219. mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
  220. bra 1f; \
  221. tst r0,r0; \
  222. 0: .word TLS_PRE_TCB_SIZE; \
  223. 1:
  224. # endif
  225. #elif !defined __ASSEMBLER__
  226. # define SINGLE_THREAD_P (1)
  227. # define NO_CANCELLATION 1
  228. #endif