308 lines · c
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-exception6 *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_H16#define UNWIND_ASSEMBLY_H17 18#if defined(__CET__)19#include <cet.h>20#define _LIBUNWIND_CET_ENDBR _CET_ENDBR21#else22#define _LIBUNWIND_CET_ENDBR23#endif24 25#if defined(__powerpc64__)26#define SEPARATOR ;27#define PPC64_OFFS_SRR0 028#define PPC64_OFFS_CR 27229#define PPC64_OFFS_XER 28030#define PPC64_OFFS_LR 28831#define PPC64_OFFS_CTR 29632#define PPC64_OFFS_VRSAVE 30433#define PPC64_OFFS_FP 31234#define PPC64_OFFS_V 82435#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# endif43 44# if __riscv_xlen == 6445# define ILOAD ld46# define ISTORE sd47# elif __riscv_xlen == 3248# define ILOAD lw49# define ISTORE sw50# else51# error "Unsupported __riscv_xlen"52# endif53 54# if defined(__riscv_flen)55# if __riscv_flen == 6456# define FLOAD fld57# define FSTORE fsd58# elif __riscv_flen == 3259# define FLOAD flw60# define FSTORE fsw61# else62# error "Unsupported __riscv_flen"63# endif64# endif65# define SEPARATOR ;66#else67#define SEPARATOR ;68#endif69 70#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) && \71 !defined(_AIX)72#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR73#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#else81#define PPC64_OPD182#define PPC64_OPD283#endif84 85#if defined(__aarch64__)86#if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)87// Set BTI, PAC, and GCS gnu property bits88#define GNU_PROPERTY 789// We indirectly branch to __libunwind_Registers_arm64_jumpto from90// __unw_phase2_resume, so we need to use bti jc.91#define AARCH64_BTI bti jc92#elif defined(__ARM_FEATURE_GCS_DEFAULT)93// Set GCS gnu property bit94#define GNU_PROPERTY 495#elif defined(__ARM_FEATURE_BTI_DEFAULT)96// Set BTI and PAC gnu property bits97#define GNU_PROPERTY 398#define AARCH64_BTI bti c99#endif100#ifdef GNU_PROPERTY101 .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 SEPARATOR112#endif113#endif114#if !defined(AARCH64_BTI)115#define AARCH64_BTI116#endif117 118#if !defined(__aarch64__)119#ifdef __ARM_FEATURE_PAC_DEFAULT120 .eabi_attribute Tag_PAC_extension, 2121 .eabi_attribute Tag_PACRET_use, 1122#endif123#ifdef __ARM_FEATURE_BTI_DEFAULT124 .eabi_attribute Tag_BTI_extension, 1125 .eabi_attribute Tag_BTI_use, 1126#endif127#endif128 129#define GLUE2(a, b) a ## b130#define GLUE(a, b) GLUE2(a, b)131#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)132 133#if defined(__APPLE__)134 135#if defined(__aarch64__) || defined(__arm64__) || defined(__arm64e__)136#define _LIBUNWIND_TRACE_RET_INJECT 1137#endif138 139#define SYMBOL_IS_FUNC(name)140#define HIDDEN_SYMBOL(name) .private_extern name141#if defined(_LIBUNWIND_HIDE_SYMBOLS)142#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)143#else144#define EXPORT_SYMBOL(name)145#endif146#define WEAK_ALIAS(name, aliasname) \147 .globl SYMBOL_NAME(aliasname) SEPARATOR \148 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \149 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)150 151#define NO_EXEC_STACK_DIRECTIVE152 153#elif defined(__ELF__)154 155#if defined(__arm__)156#define SYMBOL_IS_FUNC(name) .type name,%function157#else158#define SYMBOL_IS_FUNC(name) .type name,@function159#endif160#define HIDDEN_SYMBOL(name) .hidden name161#if defined(_LIBUNWIND_HIDE_SYMBOLS)162#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)163#else164#define EXPORT_SYMBOL(name)165#endif166#define WEAK_SYMBOL(name) .weak name167 168#if defined(__hexagon__)169#define WEAK_ALIAS(name, aliasname) \170 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \171 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \172 .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)173#else174#define WEAK_ALIAS(name, aliasname) \175 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \176 WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \177 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)178#endif179 180#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \181 defined(__linux__)182#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits183#else184#define NO_EXEC_STACK_DIRECTIVE185#endif186 187#elif defined(_WIN32)188 189#define SYMBOL_IS_FUNC(name) \190 .def name SEPARATOR \191 .scl 2 SEPARATOR \192 .type 32 SEPARATOR \193 .endef194#define EXPORT_SYMBOL2(name) \195 .section .drectve,"yn" SEPARATOR \196 .ascii "-export:", #name, "\0" SEPARATOR \197 .text198#if defined(_LIBUNWIND_HIDE_SYMBOLS)199#define EXPORT_SYMBOL(name)200#else201#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)202#endif203#define HIDDEN_SYMBOL(name)204 205#if defined(__MINGW32__)206#define WEAK_ALIAS(name, aliasname) \207 .globl SYMBOL_NAME(aliasname) SEPARATOR \208 EXPORT_SYMBOL(aliasname) SEPARATOR \209 SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)210#else211#define WEAK_ALIAS3(name, aliasname) \212 .section .drectve,"yn" SEPARATOR \213 .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR \214 .text215#define WEAK_ALIAS2(name, aliasname) \216 WEAK_ALIAS3(name, aliasname)217#define WEAK_ALIAS(name, aliasname) \218 EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \219 WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))220#endif221 222#define NO_EXEC_STACK_DIRECTIVE223 224#elif defined(__sparc__)225 226#elif defined(_AIX)227 228#if defined(__powerpc64__)229#define VBYTE_LEN 8230#define CSECT_ALIGN 3231#else232#define VBYTE_LEN 4233#define CSECT_ALIGN 2234#endif235 236// clang-format off237#define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname) \238 .csect .text[PR], 2 SEPARATOR \239 .csect .name[PR], 2 SEPARATOR \240 .globl name[DS] SEPARATOR \241 .globl .name[PR] SEPARATOR \242 .align 4 SEPARATOR \243 .csect name[DS], CSECT_ALIGN SEPARATOR \244aliasname: \245 .vbyte VBYTE_LEN, .name[PR] SEPARATOR \246 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \247 .vbyte VBYTE_LEN, 0 SEPARATOR \248 .weak aliasname SEPARATOR \249 .weak .aliasname SEPARATOR \250 .csect .name[PR], 2 SEPARATOR \251.aliasname: \252 253#define WEAK_ALIAS(name, aliasname)254#define NO_EXEC_STACK_DIRECTIVE255 256// clang-format on257#else258 259#error Unsupported target260 261#endif262 263#if defined(_AIX)264 // clang-format off265#define DEFINE_LIBUNWIND_FUNCTION(name) \266 .globl name[DS] SEPARATOR \267 .globl .name SEPARATOR \268 .align 4 SEPARATOR \269 .csect name[DS], CSECT_ALIGN SEPARATOR \270 .vbyte VBYTE_LEN, .name SEPARATOR \271 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \272 .vbyte VBYTE_LEN, 0 SEPARATOR \273 .csect .text[PR], 2 SEPARATOR \274.name:275 // clang-format on276#else277#define DEFINE_LIBUNWIND_FUNCTION(name) \278 .globl SYMBOL_NAME(name) SEPARATOR \279 HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \280 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \281 PPC64_OPD1 \282 SYMBOL_NAME(name): \283 PPC64_OPD2 \284 AARCH64_BTI285#endif286 287#if defined(__arm__)288#if !defined(__ARM_ARCH)289#define __ARM_ARCH 4290#endif291 292#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5293#define ARM_HAS_BX294#endif295 296#ifdef ARM_HAS_BX297#define JMP(r) bx r298#else299#define JMP(r) mov pc, r300#endif301#endif /* __arm__ */302 303#if defined(__powerpc__)304#define PPC_LEFT_SHIFT(index) << (index)305#endif306 307#endif /* UNWIND_ASSEMBLY_H */308