assembly.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. //===-- assembly.h - compiler-rt assembler support macros -----------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines macros for use in compiler-rt assembler source.
  10. // This file is not part of the interface of this library.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef COMPILERRT_ASSEMBLY_H
  14. #define COMPILERRT_ASSEMBLY_H
  15. #if defined(__linux__) && defined(__CET__)
  16. #if __has_include(<cet.h>)
  17. #include <cet.h>
  18. #endif
  19. #endif
  20. #if defined(__APPLE__) && defined(__aarch64__)
  21. #define SEPARATOR % %
  22. #else
  23. #define SEPARATOR ;
  24. #endif
  25. #if defined(__APPLE__)
  26. #define HIDDEN(name) .private_extern name
  27. #define LOCAL_LABEL(name) L_##name
  28. // tell linker it can break up file at label boundaries
  29. #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols
  30. #define SYMBOL_IS_FUNC(name)
  31. #define CONST_SECTION .const
  32. #define NO_EXEC_STACK_DIRECTIVE
  33. #elif defined(__ELF__)
  34. #define HIDDEN(name) .hidden name
  35. #define LOCAL_LABEL(name) .L_##name
  36. #define FILE_LEVEL_DIRECTIVE
  37. #if defined(__arm__) || defined(__aarch64__)
  38. #define SYMBOL_IS_FUNC(name) .type name, % function
  39. #else
  40. #define SYMBOL_IS_FUNC(name) .type name, @function
  41. #endif
  42. #define CONST_SECTION .section.rodata
  43. #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || defined(__linux__)
  44. #define NO_EXEC_STACK_DIRECTIVE .section.note.GNU - stack, "", % progbits
  45. #else
  46. #define NO_EXEC_STACK_DIRECTIVE
  47. #endif
  48. #else // !__APPLE__ && !__ELF__
  49. #define HIDDEN(name)
  50. #define LOCAL_LABEL(name) .L##name
  51. #define FILE_LEVEL_DIRECTIVE
  52. #define SYMBOL_IS_FUNC(name) .def name SEPARATOR.scl 2 SEPARATOR.type 32 SEPARATOR.endef
  53. #define CONST_SECTION .section.rdata, "rd"
  54. #define NO_EXEC_STACK_DIRECTIVE
  55. #endif
  56. #if defined(__arm__) || defined(__aarch64__)
  57. #define FUNC_ALIGN .text SEPARATOR.balign 16 SEPARATOR
  58. #else
  59. #define FUNC_ALIGN
  60. #endif
  61. // BTI and PAC gnu property note
  62. #define NT_GNU_PROPERTY_TYPE_0 5
  63. #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
  64. #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1
  65. #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2
  66. #if defined(__ARM_FEATURE_BTI_DEFAULT)
  67. #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI
  68. #else
  69. #define BTI_FLAG 0
  70. #endif
  71. #if __ARM_FEATURE_PAC_DEFAULT & 3
  72. #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC
  73. #else
  74. #define PAC_FLAG 0
  75. #endif
  76. #define GNU_PROPERTY(type, value) \
  77. .pushsection.note.gnu.property, \
  78. "a" SEPARATOR.p2align 3 SEPARATOR.word 4 SEPARATOR.word 16 SEPARATOR \
  79. .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR.asciz "GNU" SEPARATOR.word type \
  80. SEPARATOR.word 4 SEPARATOR.word value SEPARATOR.word 0 SEPARATOR.popsection
  81. #if BTI_FLAG != 0
  82. #define BTI_C hint #34
  83. #define BTI_J hint #36
  84. #else
  85. #define BTI_C
  86. #define BTI_J
  87. #endif
  88. #if(BTI_FLAG | PAC_FLAG) != 0
  89. #define GNU_PROPERTY_BTI_PAC GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG)
  90. #else
  91. #define GNU_PROPERTY_BTI_PAC
  92. #endif
  93. #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM)
  94. #define CFI_START .cfi_startproc
  95. #define CFI_END .cfi_endproc
  96. #else
  97. #define CFI_START
  98. #define CFI_END
  99. #endif
  100. #if defined(__arm__)
  101. // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:
  102. // - for '-mthumb -march=armv6' compiler defines '__thumb__'
  103. // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'
  104. #if defined(__thumb2__) || defined(__thumb__)
  105. #define DEFINE_CODE_STATE .thumb SEPARATOR
  106. #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR
  107. #if defined(__thumb2__)
  108. #define USE_THUMB_2
  109. #define IT(cond) it cond
  110. #define ITT(cond) itt cond
  111. #define ITE(cond) ite cond
  112. #else
  113. #define USE_THUMB_1
  114. #define IT(cond)
  115. #define ITT(cond)
  116. #define ITE(cond)
  117. #endif // defined(__thumb__2)
  118. #else // !defined(__thumb2__) && !defined(__thumb__)
  119. #define DEFINE_CODE_STATE .arm SEPARATOR
  120. #define DECLARE_FUNC_ENCODING
  121. #define IT(cond)
  122. #define ITT(cond)
  123. #define ITE(cond)
  124. #endif
  125. #if defined(USE_THUMB_1) && defined(USE_THUMB_2)
  126. #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together."
  127. #endif
  128. #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
  129. #define ARM_HAS_BX
  130. #endif
  131. #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \
  132. (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))
  133. #define __ARM_FEATURE_CLZ
  134. #endif
  135. #ifdef ARM_HAS_BX
  136. #define JMP(r) bx r
  137. #define JMPc(r, c) bx##c r
  138. #else
  139. #define JMP(r) mov pc, r
  140. #define JMPc(r, c) mov##c pc, r
  141. #endif
  142. // pop {pc} can't switch Thumb mode on ARMv4T
  143. #if __ARM_ARCH >= 5
  144. #define POP_PC() \
  145. pop { \
  146. pc \
  147. }
  148. #else
  149. #define POP_PC() \
  150. pop{ip}; \
  151. JMP(ip)
  152. #endif
  153. #if defined(USE_THUMB_2)
  154. #define WIDE(op) op.w
  155. #else
  156. #define WIDE(op) op
  157. #endif
  158. #else // !defined(__arm)
  159. #define DECLARE_FUNC_ENCODING
  160. #define DEFINE_CODE_STATE
  161. #endif
  162. #define GLUE2_(a, b) a##b
  163. #define GLUE(a, b) GLUE2_(a, b)
  164. #define GLUE2(a, b) GLUE2_(a, b)
  165. #define GLUE3_(a, b, c) a##b##c
  166. #define GLUE3(a, b, c) GLUE3_(a, b, c)
  167. #define GLUE4_(a, b, c, d) a##b##c##d
  168. #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d)
  169. #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
  170. #ifdef VISIBILITY_HIDDEN
  171. #define DECLARE_SYMBOL_VISIBILITY(name) HIDDEN(SYMBOL_NAME(name)) SEPARATOR
  172. #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) HIDDEN(name) SEPARATOR
  173. #else
  174. #define DECLARE_SYMBOL_VISIBILITY(name)
  175. #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name)
  176. #endif
  177. #define DEFINE_COMPILERRT_FUNCTION(name) \
  178. DEFINE_CODE_STATE \
  179. FILE_LEVEL_DIRECTIVE SEPARATOR.globl SYMBOL_NAME(name) \
  180. SEPARATOR \
  181. SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR DECLARE_SYMBOL_VISIBILITY(name) \
  182. DECLARE_FUNC_ENCODING \
  183. SYMBOL_NAME(name) \
  184. :
  185. #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \
  186. DEFINE_CODE_STATE \
  187. FILE_LEVEL_DIRECTIVE SEPARATOR.globl SYMBOL_NAME(name) \
  188. SEPARATOR \
  189. SYMBOL_IS_FUNC(SYMBOL_NAME(name)) \
  190. SEPARATOR DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR.thumb_func SEPARATOR SYMBOL_NAME(name) \
  191. :
  192. #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
  193. DEFINE_CODE_STATE \
  194. FILE_LEVEL_DIRECTIVE SEPARATOR.globl SYMBOL_NAME(name) \
  195. SEPARATOR \
  196. SYMBOL_IS_FUNC(SYMBOL_NAME(name)) \
  197. SEPARATOR HIDDEN(SYMBOL_NAME(name)) SEPARATOR DECLARE_FUNC_ENCODING SYMBOL_NAME(name) \
  198. :
  199. #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
  200. DEFINE_CODE_STATE.globl name SEPARATOR SYMBOL_IS_FUNC(name) \
  201. SEPARATOR \
  202. HIDDEN(name) SEPARATOR DECLARE_FUNC_ENCODING name:
  203. #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \
  204. DEFINE_CODE_STATE \
  205. FUNC_ALIGN.globl name SEPARATOR SYMBOL_IS_FUNC(name) \
  206. SEPARATOR \
  207. DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \
  208. SEPARATOR CFI_START SEPARATOR DECLARE_FUNC_ENCODING name : SEPARATOR BTI_C
  209. #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \
  210. .globl SYMBOL_NAME(name) \
  211. SEPARATOR \
  212. SYMBOL_IS_FUNC(SYMBOL_NAME(name)) \
  213. SEPARATOR DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR.set SYMBOL_NAME(name), \
  214. SYMBOL_NAME(target) SEPARATOR
  215. #if defined(__ARM_EABI__)
  216. #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \
  217. DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)
  218. #else
  219. #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)
  220. #endif
  221. #ifdef __ELF__
  222. #define END_COMPILERRT_FUNCTION(name) .size SYMBOL_NAME(name), .- SYMBOL_NAME(name)
  223. #define END_COMPILERRT_OUTLINE_FUNCTION(name) \
  224. CFI_END SEPARATOR.size SYMBOL_NAME(name), .- SYMBOL_NAME(name)
  225. #else
  226. #define END_COMPILERRT_FUNCTION(name)
  227. #define END_COMPILERRT_OUTLINE_FUNCTION(name) CFI_END
  228. #endif
  229. #endif // COMPILERRT_ASSEMBLY_H