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(__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 \ 225aliasname: \ 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