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