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__) 86 #if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT) 87 // Set BTI, PAC, and GCS gnu property bits 88 #define GNU_PROPERTY 7 89 // We indirectly branch to __libunwind_Registers_arm64_jumpto from 90 // __unw_phase2_resume, so we need to use bti jc. 91 #define AARCH64_BTI bti jc 92 #elif defined(__ARM_FEATURE_GCS_DEFAULT) 93 // Set GCS gnu property bit 94 #define GNU_PROPERTY 4 95 #elif defined(__ARM_FEATURE_BTI_DEFAULT) 96 // Set BTI and PAC gnu property bits 97 #define GNU_PROPERTY 3 98 #define AARCH64_BTI bti c 99 #endif 100 #ifdef GNU_PROPERTY 101 .pushsection ".note.gnu.property", "a" SEPARATOR \ 102 .balign 8 SEPARATOR \ 103 .long 4 SEPARATOR \ 104 .long 0x10 SEPARATOR \ 105 .long 0x5 SEPARATOR \ 106 .asciz "GNU" SEPARATOR \ 107 .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \ 108 .long 4 SEPARATOR \ 109 .long GNU_PROPERTY SEPARATOR \ 110 .long 0 SEPARATOR \ 111 .popsection SEPARATOR 112 #endif 113 #endif 114 #if !defined(AARCH64_BTI) 115 #define AARCH64_BTI 116 #endif 117 118 #if !defined(__aarch64__) 119 #ifdef __ARM_FEATURE_PAC_DEFAULT 120 .eabi_attribute Tag_PAC_extension, 2 121 .eabi_attribute Tag_PACRET_use, 1 122 #endif 123 #ifdef __ARM_FEATURE_BTI_DEFAULT 124 .eabi_attribute Tag_BTI_extension, 1 125 .eabi_attribute Tag_BTI_use, 1 126 #endif 127 #endif 128 129 #define GLUE2(a, b) a ## b 130 #define GLUE(a, b) GLUE2(a, b) 131 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) 132 133 #if defined(__APPLE__) 134 135 #define SYMBOL_IS_FUNC(name) 136 #define HIDDEN_SYMBOL(name) .private_extern name 137 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 138 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name) 139 #else 140 #define EXPORT_SYMBOL(name) 141 #endif 142 #define WEAK_ALIAS(name, aliasname) \ 143 .globl SYMBOL_NAME(aliasname) SEPARATOR \ 144 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 145 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) 146 147 #define NO_EXEC_STACK_DIRECTIVE 148 149 #elif defined(__ELF__) 150 151 #if defined(__arm__) 152 #define SYMBOL_IS_FUNC(name) .type name,%function 153 #else 154 #define SYMBOL_IS_FUNC(name) .type name,@function 155 #endif 156 #define HIDDEN_SYMBOL(name) .hidden name 157 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 158 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name) 159 #else 160 #define EXPORT_SYMBOL(name) 161 #endif 162 #define WEAK_SYMBOL(name) .weak name 163 164 #if defined(__hexagon__) 165 #define WEAK_ALIAS(name, aliasname) \ 166 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 167 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 168 .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name) 169 #else 170 #define WEAK_ALIAS(name, aliasname) \ 171 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 172 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 173 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) 174 #endif 175 176 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ 177 defined(__linux__) 178 #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits 179 #else 180 #define NO_EXEC_STACK_DIRECTIVE 181 #endif 182 183 #elif defined(_WIN32) 184 185 #define SYMBOL_IS_FUNC(name) \ 186 .def name SEPARATOR \ 187 .scl 2 SEPARATOR \ 188 .type 32 SEPARATOR \ 189 .endef 190 #define EXPORT_SYMBOL2(name) \ 191 .section .drectve,"yn" SEPARATOR \ 192 .ascii "-export:", #name, "\0" SEPARATOR \ 193 .text 194 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 195 #define EXPORT_SYMBOL(name) 196 #else 197 #define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name) 198 #endif 199 #define HIDDEN_SYMBOL(name) 200 201 #if defined(__MINGW32__) 202 #define WEAK_ALIAS(name, aliasname) \ 203 .globl SYMBOL_NAME(aliasname) SEPARATOR \ 204 EXPORT_SYMBOL(aliasname) SEPARATOR \ 205 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name) 206 #else 207 #define WEAK_ALIAS3(name, aliasname) \ 208 .section .drectve,"yn" SEPARATOR \ 209 .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR \ 210 .text 211 #define WEAK_ALIAS2(name, aliasname) \ 212 WEAK_ALIAS3(name, aliasname) 213 #define WEAK_ALIAS(name, aliasname) \ 214 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \ 215 WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname)) 216 #endif 217 218 #define NO_EXEC_STACK_DIRECTIVE 219 220 #elif defined(__sparc__) 221 222 #elif defined(_AIX) 223 224 #if defined(__powerpc64__) 225 #define VBYTE_LEN 8 226 #define CSECT_ALIGN 3 227 #else 228 #define VBYTE_LEN 4 229 #define CSECT_ALIGN 2 230 #endif 231 232 // clang-format off 233 #define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname) \ 234 .csect .text[PR], 2 SEPARATOR \ 235 .csect .name[PR], 2 SEPARATOR \ 236 .globl name[DS] SEPARATOR \ 237 .globl .name[PR] SEPARATOR \ 238 .align 4 SEPARATOR \ 239 .csect name[DS], CSECT_ALIGN SEPARATOR \ 240 aliasname: \ 241 .vbyte VBYTE_LEN, .name[PR] SEPARATOR \ 242 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \ 243 .vbyte VBYTE_LEN, 0 SEPARATOR \ 244 .weak aliasname SEPARATOR \ 245 .weak .aliasname SEPARATOR \ 246 .csect .name[PR], 2 SEPARATOR \ 247 .aliasname: \ 248 249 #define WEAK_ALIAS(name, aliasname) 250 #define NO_EXEC_STACK_DIRECTIVE 251 252 // clang-format on 253 #else 254 255 #error Unsupported target 256 257 #endif 258 259 #if defined(_AIX) 260 // clang-format off 261 #define DEFINE_LIBUNWIND_FUNCTION(name) \ 262 .globl name[DS] SEPARATOR \ 263 .globl .name SEPARATOR \ 264 .align 4 SEPARATOR \ 265 .csect name[DS], CSECT_ALIGN SEPARATOR \ 266 .vbyte VBYTE_LEN, .name SEPARATOR \ 267 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \ 268 .vbyte VBYTE_LEN, 0 SEPARATOR \ 269 .csect .text[PR], 2 SEPARATOR \ 270 .name: 271 // clang-format on 272 #else 273 #define DEFINE_LIBUNWIND_FUNCTION(name) \ 274 .globl SYMBOL_NAME(name) SEPARATOR \ 275 HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ 276 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 277 PPC64_OPD1 \ 278 SYMBOL_NAME(name): \ 279 PPC64_OPD2 \ 280 AARCH64_BTI 281 #endif 282 283 #if defined(__arm__) 284 #if !defined(__ARM_ARCH) 285 #define __ARM_ARCH 4 286 #endif 287 288 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 289 #define ARM_HAS_BX 290 #endif 291 292 #ifdef ARM_HAS_BX 293 #define JMP(r) bx r 294 #else 295 #define JMP(r) mov pc, r 296 #endif 297 #endif /* __arm__ */ 298 299 #if defined(__powerpc__) 300 #define PPC_LEFT_SHIFT(index) << (index) 301 #endif 302 303 #endif /* UNWIND_ASSEMBLY_H */ 304