1 /* ===-- assembly.h - libUnwind 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 libUnwind assembler source. 10 * This file is not part of the interface of this library. 11 * 12 * ===----------------------------------------------------------------------=== 13 */ 14 15 #ifndef UNWIND_ASSEMBLY_H 16 #define UNWIND_ASSEMBLY_H 17 18 #if defined(__linux__) && defined(__CET__) 19 #include <cet.h> 20 #define _LIBUNWIND_CET_ENDBR _CET_ENDBR 21 #else 22 #define _LIBUNWIND_CET_ENDBR 23 #endif 24 25 #if defined(__powerpc64__) 26 #define SEPARATOR ; 27 #define PPC64_OFFS_SRR0 0 28 #define PPC64_OFFS_CR 272 29 #define PPC64_OFFS_XER 280 30 #define PPC64_OFFS_LR 288 31 #define PPC64_OFFS_CTR 296 32 #define PPC64_OFFS_VRSAVE 304 33 #define PPC64_OFFS_FP 312 34 #define PPC64_OFFS_V 824 35 #elif defined(__APPLE__) && defined(__aarch64__) 36 #define SEPARATOR %% 37 #elif defined(__riscv) 38 # define RISCV_ISIZE (__riscv_xlen / 8) 39 # define RISCV_FOFFSET (RISCV_ISIZE * 32) 40 # if defined(__riscv_flen) 41 # define RISCV_FSIZE (__riscv_flen / 8) 42 # endif 43 44 # if __riscv_xlen == 64 45 # define ILOAD ld 46 # define ISTORE sd 47 # elif __riscv_xlen == 32 48 # define ILOAD lw 49 # define ISTORE sw 50 # else 51 # error "Unsupported __riscv_xlen" 52 # endif 53 54 # if defined(__riscv_flen) 55 # if __riscv_flen == 64 56 # define FLOAD fld 57 # define FSTORE fsd 58 # elif __riscv_flen == 32 59 # define FLOAD flw 60 # define FSTORE fsw 61 # else 62 # error "Unsupported __riscv_flen" 63 # endif 64 # endif 65 # define SEPARATOR ; 66 #else 67 #define SEPARATOR ; 68 #endif 69 70 #if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) && \ 71 !defined(_AIX) 72 #define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR 73 #define PPC64_OPD2 SEPARATOR \ 74 .p2align 3 SEPARATOR \ 75 .quad .Lfunc_begin0 SEPARATOR \ 76 .quad .TOC.@tocbase SEPARATOR \ 77 .quad 0 SEPARATOR \ 78 .text SEPARATOR \ 79 .Lfunc_begin0: 80 #else 81 #define PPC64_OPD1 82 #define PPC64_OPD2 83 #endif 84 85 #if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT) 86 .pushsection ".note.gnu.property", "a" SEPARATOR \ 87 .balign 8 SEPARATOR \ 88 .long 4 SEPARATOR \ 89 .long 0x10 SEPARATOR \ 90 .long 0x5 SEPARATOR \ 91 .asciz "GNU" SEPARATOR \ 92 .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \ 93 .long 4 SEPARATOR \ 94 .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \ 95 /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \ 96 .long 0 SEPARATOR \ 97 .popsection SEPARATOR 98 #define AARCH64_BTI bti c 99 #else 100 #define AARCH64_BTI 101 #endif 102 103 #if !defined(__aarch64__) 104 #ifdef __ARM_FEATURE_PAC_DEFAULT 105 .eabi_attribute Tag_PAC_extension, 2 106 .eabi_attribute Tag_PACRET_use, 1 107 #endif 108 #ifdef __ARM_FEATURE_BTI_DEFAULT 109 .eabi_attribute Tag_BTI_extension, 1 110 .eabi_attribute Tag_BTI_use, 1 111 #endif 112 #endif 113 114 #define GLUE2(a, b) a ## b 115 #define GLUE(a, b) GLUE2(a, b) 116 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) 117 118 #if defined(__APPLE__) 119 120 #define SYMBOL_IS_FUNC(name) 121 #define HIDDEN_SYMBOL(name) .private_extern name 122 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 123 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name) 124 #else 125 #define EXPORT_SYMBOL(name) 126 #endif 127 #define WEAK_ALIAS(name, aliasname) \ 128 .globl SYMBOL_NAME(aliasname) SEPARATOR \ 129 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 130 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) 131 132 #define NO_EXEC_STACK_DIRECTIVE 133 134 #elif defined(__ELF__) 135 136 #if defined(__arm__) 137 #define SYMBOL_IS_FUNC(name) .type name,%function 138 #else 139 #define SYMBOL_IS_FUNC(name) .type name,@function 140 #endif 141 #define HIDDEN_SYMBOL(name) .hidden name 142 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 143 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name) 144 #else 145 #define EXPORT_SYMBOL(name) 146 #endif 147 #define WEAK_SYMBOL(name) .weak name 148 149 #if defined(__hexagon__) 150 #define WEAK_ALIAS(name, aliasname) \ 151 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 152 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 153 .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name) 154 #else 155 #define WEAK_ALIAS(name, aliasname) \ 156 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 157 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 158 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) 159 #endif 160 161 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ 162 defined(__linux__) 163 #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits 164 #else 165 #define NO_EXEC_STACK_DIRECTIVE 166 #endif 167 168 #elif defined(_WIN32) 169 170 #define SYMBOL_IS_FUNC(name) \ 171 .def name SEPARATOR \ 172 .scl 2 SEPARATOR \ 173 .type 32 SEPARATOR \ 174 .endef 175 #define EXPORT_SYMBOL2(name) \ 176 .section .drectve,"yn" SEPARATOR \ 177 .ascii "-export:", #name, "\0" SEPARATOR \ 178 .text 179 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 180 #define EXPORT_SYMBOL(name) 181 #else 182 #define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name) 183 #endif 184 #define HIDDEN_SYMBOL(name) 185 186 #if defined(__MINGW32__) 187 #define WEAK_ALIAS(name, aliasname) \ 188 .globl SYMBOL_NAME(aliasname) SEPARATOR \ 189 EXPORT_SYMBOL(aliasname) SEPARATOR \ 190 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) 191 #else 192 #define WEAK_ALIAS3(name, aliasname) \ 193 .section .drectve,"yn" SEPARATOR \ 194 .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR \ 195 .text 196 #define WEAK_ALIAS2(name, aliasname) \ 197 WEAK_ALIAS3(name, aliasname) 198 #define WEAK_ALIAS(name, aliasname) \ 199 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 200 WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname)) 201 #endif 202 203 #define NO_EXEC_STACK_DIRECTIVE 204 205 #elif defined(__sparc__) 206 207 #elif defined(_AIX) 208 209 #if defined(__powerpc64__) 210 #define VBYTE_LEN 8 211 #define CSECT_ALIGN 3 212 #else 213 #define VBYTE_LEN 4 214 #define CSECT_ALIGN 2 215 #endif 216 217 // clang-format off 218 #define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname) \ 219 .csect .text[PR], 2 SEPARATOR \ 220 .csect .name[PR], 2 SEPARATOR \ 221 .globl name[DS] SEPARATOR \ 222 .globl .name[PR] SEPARATOR \ 223 .align 4 SEPARATOR \ 224 .csect name[DS], CSECT_ALIGN SEPARATOR \ 225 aliasname: \ 226 .vbyte VBYTE_LEN, .name[PR] SEPARATOR \ 227 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \ 228 .vbyte VBYTE_LEN, 0 SEPARATOR \ 229 .weak aliasname SEPARATOR \ 230 .weak .aliasname SEPARATOR \ 231 .csect .name[PR], 2 SEPARATOR \ 232 .aliasname: \ 233 234 #define WEAK_ALIAS(name, aliasname) 235 #define NO_EXEC_STACK_DIRECTIVE 236 237 // clang-format on 238 #else 239 240 #error Unsupported target 241 242 #endif 243 244 #if defined(_AIX) 245 // clang-format off 246 #define DEFINE_LIBUNWIND_FUNCTION(name) \ 247 .globl name[DS] SEPARATOR \ 248 .globl .name SEPARATOR \ 249 .align 4 SEPARATOR \ 250 .csect name[DS], CSECT_ALIGN SEPARATOR \ 251 .vbyte VBYTE_LEN, .name SEPARATOR \ 252 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \ 253 .vbyte VBYTE_LEN, 0 SEPARATOR \ 254 .csect .text[PR], 2 SEPARATOR \ 255 .name: 256 // clang-format on 257 #else 258 #define DEFINE_LIBUNWIND_FUNCTION(name) \ 259 .globl SYMBOL_NAME(name) SEPARATOR \ 260 HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ 261 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 262 PPC64_OPD1 \ 263 SYMBOL_NAME(name): \ 264 PPC64_OPD2 \ 265 AARCH64_BTI 266 #endif 267 268 #if defined(__arm__) 269 #if !defined(__ARM_ARCH) 270 #define __ARM_ARCH 4 271 #endif 272 273 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 274 #define ARM_HAS_BX 275 #endif 276 277 #ifdef ARM_HAS_BX 278 #define JMP(r) bx r 279 #else 280 #define JMP(r) mov pc, r 281 #endif 282 #endif /* __arm__ */ 283 284 #if defined(__powerpc__) 285 #define PPC_LEFT_SHIFT(index) << (index) 286 #endif 287 288 #endif /* UNWIND_ASSEMBLY_H */ 289