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