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