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 \ 65 .scl 2 SEPARATOR \ 66 .type 32 SEPARATOR \ 67 .endef 68 #define CONST_SECTION .section .rdata,"rd" 69 70 #define NO_EXEC_STACK_DIRECTIVE 71 72 #endif 73 74 #if defined(__arm__) || defined(__aarch64__) 75 #define FUNC_ALIGN \ 76 .text SEPARATOR \ 77 .balign 16 SEPARATOR 78 #else 79 #define FUNC_ALIGN 80 #endif 81 82 // BTI and PAC gnu property note 83 #define NT_GNU_PROPERTY_TYPE_0 5 84 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 85 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1 86 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2 87 88 #if defined(__ARM_FEATURE_BTI_DEFAULT) 89 #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI 90 #else 91 #define BTI_FLAG 0 92 #endif 93 94 #if __ARM_FEATURE_PAC_DEFAULT & 3 95 #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC 96 #else 97 #define PAC_FLAG 0 98 #endif 99 100 #define GNU_PROPERTY(type, value) \ 101 .pushsection .note.gnu.property, "a" SEPARATOR \ 102 .p2align 3 SEPARATOR \ 103 .word 4 SEPARATOR \ 104 .word 16 SEPARATOR \ 105 .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \ 106 .asciz "GNU" SEPARATOR \ 107 .word type SEPARATOR \ 108 .word 4 SEPARATOR \ 109 .word value SEPARATOR \ 110 .word 0 SEPARATOR \ 111 .popsection 112 113 #if BTI_FLAG != 0 114 #define BTI_C hint #34 115 #define BTI_J hint #36 116 #else 117 #define BTI_C 118 #define BTI_J 119 #endif 120 121 #if (BTI_FLAG | PAC_FLAG) != 0 122 #define GNU_PROPERTY_BTI_PAC \ 123 GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG) 124 #else 125 #define GNU_PROPERTY_BTI_PAC 126 #endif 127 128 #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM) 129 #define CFI_START .cfi_startproc 130 #define CFI_END .cfi_endproc 131 #else 132 #define CFI_START 133 #define CFI_END 134 #endif 135 136 #if defined(__arm__) 137 138 // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: 139 // - for '-mthumb -march=armv6' compiler defines '__thumb__' 140 // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' 141 #if defined(__thumb2__) || defined(__thumb__) 142 #define DEFINE_CODE_STATE .thumb SEPARATOR 143 #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR 144 #if defined(__thumb2__) 145 #define USE_THUMB_2 146 #define IT(cond) it cond 147 #define ITT(cond) itt cond 148 #define ITE(cond) ite cond 149 #else 150 #define USE_THUMB_1 151 #define IT(cond) 152 #define ITT(cond) 153 #define ITE(cond) 154 #endif // defined(__thumb__2) 155 #else // !defined(__thumb2__) && !defined(__thumb__) 156 #define DEFINE_CODE_STATE .arm SEPARATOR 157 #define DECLARE_FUNC_ENCODING 158 #define IT(cond) 159 #define ITT(cond) 160 #define ITE(cond) 161 #endif 162 163 #if defined(USE_THUMB_1) && defined(USE_THUMB_2) 164 #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." 165 #endif 166 167 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 168 #define ARM_HAS_BX 169 #endif 170 #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ 171 (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) 172 #define __ARM_FEATURE_CLZ 173 #endif 174 175 #ifdef ARM_HAS_BX 176 #define JMP(r) bx r 177 #define JMPc(r, c) bx##c r 178 #else 179 #define JMP(r) mov pc, r 180 #define JMPc(r, c) mov##c pc, r 181 #endif 182 183 // pop {pc} can't switch Thumb mode on ARMv4T 184 #if __ARM_ARCH >= 5 185 #define POP_PC() pop {pc} 186 #else 187 #define POP_PC() \ 188 pop {ip}; \ 189 JMP(ip) 190 #endif 191 192 #if defined(USE_THUMB_2) 193 #define WIDE(op) op.w 194 #else 195 #define WIDE(op) op 196 #endif 197 #else // !defined(__arm) 198 #define DECLARE_FUNC_ENCODING 199 #define DEFINE_CODE_STATE 200 #endif 201 202 #define GLUE2_(a, b) a##b 203 #define GLUE(a, b) GLUE2_(a, b) 204 #define GLUE2(a, b) GLUE2_(a, b) 205 #define GLUE3_(a, b, c) a##b##c 206 #define GLUE3(a, b, c) GLUE3_(a, b, c) 207 #define GLUE4_(a, b, c, d) a##b##c##d 208 #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d) 209 210 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) 211 212 #ifdef VISIBILITY_HIDDEN 213 #define DECLARE_SYMBOL_VISIBILITY(name) \ 214 HIDDEN(SYMBOL_NAME(name)) SEPARATOR 215 #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \ 216 HIDDEN(name) SEPARATOR 217 #else 218 #define DECLARE_SYMBOL_VISIBILITY(name) 219 #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) 220 #endif 221 222 #define DEFINE_COMPILERRT_FUNCTION(name) \ 223 DEFINE_CODE_STATE \ 224 FILE_LEVEL_DIRECTIVE SEPARATOR \ 225 .globl SYMBOL_NAME(name) SEPARATOR \ 226 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 227 DECLARE_SYMBOL_VISIBILITY(name) \ 228 DECLARE_FUNC_ENCODING \ 229 SYMBOL_NAME(name): 230 231 #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ 232 DEFINE_CODE_STATE \ 233 FILE_LEVEL_DIRECTIVE SEPARATOR \ 234 .globl SYMBOL_NAME(name) SEPARATOR \ 235 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 236 DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ 237 .thumb_func SEPARATOR \ 238 SYMBOL_NAME(name): 239 240 #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ 241 DEFINE_CODE_STATE \ 242 FILE_LEVEL_DIRECTIVE SEPARATOR \ 243 .globl SYMBOL_NAME(name) SEPARATOR \ 244 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 245 HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ 246 DECLARE_FUNC_ENCODING \ 247 SYMBOL_NAME(name): 248 249 #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ 250 DEFINE_CODE_STATE \ 251 .globl name SEPARATOR \ 252 SYMBOL_IS_FUNC(name) SEPARATOR \ 253 HIDDEN(name) SEPARATOR \ 254 DECLARE_FUNC_ENCODING \ 255 name: 256 257 #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \ 258 DEFINE_CODE_STATE \ 259 FUNC_ALIGN \ 260 .globl name SEPARATOR \ 261 SYMBOL_IS_FUNC(name) SEPARATOR \ 262 DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \ 263 CFI_START SEPARATOR \ 264 DECLARE_FUNC_ENCODING \ 265 name: SEPARATOR BTI_C 266 267 #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ 268 .globl SYMBOL_NAME(name) SEPARATOR \ 269 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 270 DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \ 271 .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR 272 273 #if defined(__ARM_EABI__) 274 #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ 275 DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) 276 #else 277 #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) 278 #endif 279 280 #ifdef __ELF__ 281 #define END_COMPILERRT_FUNCTION(name) \ 282 .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 283 #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ 284 CFI_END SEPARATOR \ 285 .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 286 #else 287 #define END_COMPILERRT_FUNCTION(name) 288 #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ 289 CFI_END 290 #endif 291 292 #endif // COMPILERRT_ASSEMBLY_H 293