366 lines · c
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-exception6//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_H15#define COMPILERRT_ASSEMBLY_H16 17#ifdef __CET__18#if __has_include(<cet.h>)19#include <cet.h>20#endif21#endif22 23#if defined(__APPLE__) && defined(__aarch64__)24#define SEPARATOR %%25#else26#define SEPARATOR ;27#endif28 29#if defined(__APPLE__)30#define HIDDEN(name) .private_extern name31#define LOCAL_LABEL(name) L_##name32// tell linker it can break up file at label boundaries33#define FILE_LEVEL_DIRECTIVE .subsections_via_symbols34#define SYMBOL_IS_FUNC(name)35#define CONST_SECTION .const36 37#define NO_EXEC_STACK_DIRECTIVE38 39#elif defined(__ELF__)40 41#define HIDDEN(name) .hidden name42#define LOCAL_LABEL(name) .L_##name43#define FILE_LEVEL_DIRECTIVE44#if defined(__arm__) || defined(__aarch64__)45#define SYMBOL_IS_FUNC(name) .type name,%function46#else47#define SYMBOL_IS_FUNC(name) .type name,@function48#endif49#define CONST_SECTION .section .rodata50 51#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \52 defined(__linux__)53#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits54#else55#define NO_EXEC_STACK_DIRECTIVE56#endif57 58#else // !__APPLE__ && !__ELF__59 60#define HIDDEN(name)61#define LOCAL_LABEL(name) .L ## name62#define FILE_LEVEL_DIRECTIVE63#define SYMBOL_IS_FUNC(name) \64 .def FUNC_SYMBOL(name) SEPARATOR \65 .scl 2 SEPARATOR \66 .type 32 SEPARATOR \67 .endef68#define CONST_SECTION .section .rdata,"rd"69 70#define NO_EXEC_STACK_DIRECTIVE71 72#endif73 74#if defined(__aarch64__) && defined(__ELF__) && \75 defined(COMPILER_RT_EXECUTE_ONLY_CODE)76// The assembler always creates an implicit '.text' section with default flags77// (SHF_ALLOC | SHF_EXECINSTR), which is incompatible with the execute-only78// '.text' section we want to create here because of the missing79// SHF_AARCH64_PURECODE section flag. To solve this, we use 'unique,0' to80// differentiate the two sections. The output will therefore have two separate81// sections named '.text', where code will be placed into the execute-only82// '.text' section, and the implicitly-created one will be empty.83#define TEXT_SECTION \84 .section .text,"axy",@progbits,unique,085#else86#define TEXT_SECTION \87 .text88#endif89 90#if defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__)91#define FUNC_ALIGN \92 .balign 16 SEPARATOR93#else94#define FUNC_ALIGN95#endif96 97// BTI, PAC, and GCS gnu property note98#define NT_GNU_PROPERTY_TYPE_0 599#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000100#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1101#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2102#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS 4103 104#if defined(__ARM_FEATURE_BTI_DEFAULT)105#define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI106#else107#define BTI_FLAG 0108#endif109 110#if __ARM_FEATURE_PAC_DEFAULT & 3111#define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC112#else113#define PAC_FLAG 0114#endif115 116#if defined(__ARM_FEATURE_GCS_DEFAULT)117#define GCS_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_GCS118#else119#define GCS_FLAG 0120#endif121 122#define GNU_PROPERTY(type, value) \123 .pushsection .note.gnu.property, "a" SEPARATOR \124 .p2align 3 SEPARATOR \125 .word 4 SEPARATOR \126 .word 16 SEPARATOR \127 .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \128 .asciz "GNU" SEPARATOR \129 .word type SEPARATOR \130 .word 4 SEPARATOR \131 .word value SEPARATOR \132 .word 0 SEPARATOR \133 .popsection134 135#if BTI_FLAG != 0136#define BTI_C hint #34137#define BTI_J hint #36138#else139#define BTI_C140#define BTI_J141#endif142 143#if (BTI_FLAG | PAC_FLAG | GCS_FLAG) != 0144#define GNU_PROPERTY_BTI_PAC_GCS \145 GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, \146 BTI_FLAG | PAC_FLAG | GCS_FLAG)147#else148#define GNU_PROPERTY_BTI_PAC_GCS149#endif150 151#if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM)152#define CFI_START .cfi_startproc153#define CFI_END .cfi_endproc154#else155#define CFI_START156#define CFI_END157#endif158 159#if defined(__arm__)160 161// Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:162// - for '-mthumb -march=armv6' compiler defines '__thumb__'163// - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'164#if defined(__thumb2__) || defined(__thumb__)165#define DEFINE_CODE_STATE .thumb SEPARATOR166#define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR167#if defined(__thumb2__)168#define USE_THUMB_2169#define IT(cond) it cond170#define ITT(cond) itt cond171#define ITE(cond) ite cond172#else173#define USE_THUMB_1174#define IT(cond)175#define ITT(cond)176#define ITE(cond)177#endif // defined(__thumb__2)178#else // !defined(__thumb2__) && !defined(__thumb__)179#define DEFINE_CODE_STATE .arm SEPARATOR180#define DECLARE_FUNC_ENCODING181#define IT(cond)182#define ITT(cond)183#define ITE(cond)184#endif185 186#if defined(USE_THUMB_1) && defined(USE_THUMB_2)187#error "USE_THUMB_1 and USE_THUMB_2 can't be defined together."188#endif189 190#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5191#define ARM_HAS_BX192#endif193#if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \194 (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))195#define __ARM_FEATURE_CLZ196#endif197 198#ifdef ARM_HAS_BX199#define JMP(r) bx r200#define JMPc(r, c) bx##c r201#else202#define JMP(r) mov pc, r203#define JMPc(r, c) mov##c pc, r204#endif205 206// pop {pc} can't switch Thumb mode on ARMv4T207#if __ARM_ARCH >= 5208#define POP_PC() pop {pc}209#else210#define POP_PC() \211 pop {ip}; \212 JMP(ip)213#endif214 215#if defined(USE_THUMB_2)216#define WIDE(op) op.w217#else218#define WIDE(op) op219#endif220 221#if defined(__ARM_FEATURE_PAC_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)222#define PACBTI_LANDING pacbti r12, lr, sp223#elif defined(__ARM_FEATURE_PAC_DEFAULT)224#define PACBTI_LANDING pac r12, lr, sp225#elif defined(__ARM_FEATURE_BTI_DEFAULT)226#define PACBTI_LANDING bti227#else228#define PACBTI_LANDING229#endif230 231#if defined(__ARM_FEATURE_PAUTH)232#define PAC_RETURN bxaut r12, lr, sp233#else234#define PAC_RETURN aut r12, lr, sp SEPARATOR bx lr235#endif236 237#else // !defined(__arm)238#define DECLARE_FUNC_ENCODING239#define DEFINE_CODE_STATE240#endif241 242#define GLUE2_(a, b) a##b243#define GLUE(a, b) GLUE2_(a, b)244#define GLUE2(a, b) GLUE2_(a, b)245#define GLUE3_(a, b, c) a##b##c246#define GLUE3(a, b, c) GLUE3_(a, b, c)247#define GLUE4_(a, b, c, d) a##b##c##d248#define GLUE4(a, b, c, d) GLUE4_(a, b, c, d)249 250#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)251#ifndef __arm64ec__252#define FUNC_SYMBOL(name) name253#else254// On ARM64EC, function names and calls (but not address-taking or data symbol255// references) use symbols prefixed with "#".256#define QUOTE(a) #a257#define STR(a) QUOTE(a)258#define HASH #259#define FUNC_SYMBOL(name) STR(GLUE2(HASH, name))260#endif261 262#ifdef VISIBILITY_HIDDEN263#define DECLARE_SYMBOL_VISIBILITY(name) \264 HIDDEN(SYMBOL_NAME(name)) SEPARATOR265#define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \266 HIDDEN(name) SEPARATOR267#else268#define DECLARE_SYMBOL_VISIBILITY(name)269#define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name)270#endif271 272#define DEFINE_COMPILERRT_FUNCTION(name) \273 TEXT_SECTION SEPARATOR \274 DEFINE_CODE_STATE \275 FILE_LEVEL_DIRECTIVE SEPARATOR \276 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \277 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \278 DECLARE_SYMBOL_VISIBILITY(name) \279 DECLARE_FUNC_ENCODING \280 FUNC_SYMBOL(SYMBOL_NAME(name)):281 282#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \283 TEXT_SECTION SEPARATOR \284 DEFINE_CODE_STATE \285 FILE_LEVEL_DIRECTIVE SEPARATOR \286 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \287 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \288 DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \289 .thumb_func SEPARATOR \290 FUNC_SYMBOL(SYMBOL_NAME(name)):291 292#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \293 TEXT_SECTION SEPARATOR \294 DEFINE_CODE_STATE \295 FILE_LEVEL_DIRECTIVE SEPARATOR \296 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \297 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \298 HIDDEN(SYMBOL_NAME(name)) SEPARATOR \299 DECLARE_FUNC_ENCODING \300 FUNC_SYMBOL(SYMBOL_NAME(name)):301 302#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \303 TEXT_SECTION SEPARATOR \304 DEFINE_CODE_STATE \305 .globl FUNC_SYMBOL(name) SEPARATOR \306 SYMBOL_IS_FUNC(name) SEPARATOR \307 HIDDEN(name) SEPARATOR \308 DECLARE_FUNC_ENCODING \309 FUNC_SYMBOL(name):310 311#define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \312 TEXT_SECTION SEPARATOR \313 DEFINE_CODE_STATE \314 FUNC_ALIGN \315 .globl FUNC_SYMBOL(name) SEPARATOR \316 SYMBOL_IS_FUNC(name) SEPARATOR \317 DECLARE_SYMBOL_VISIBILITY_UNMANGLED(FUNC_SYMBOL(name)) SEPARATOR \318 DECLARE_FUNC_ENCODING \319 FUNC_SYMBOL(name): \320 SEPARATOR CFI_START \321 SEPARATOR BTI_C322 323#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \324 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \325 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \326 DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \327 .set FUNC_SYMBOL(SYMBOL_NAME(name)), FUNC_SYMBOL(SYMBOL_NAME(target)) SEPARATOR328 329#if defined(__ARM_EABI__)330#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \331 DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)332#else333#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)334#endif335 336#ifdef __ELF__337#define END_COMPILERRT_FUNCTION(name) \338 .size SYMBOL_NAME(name), . - SYMBOL_NAME(name)339#define END_COMPILERRT_OUTLINE_FUNCTION(name) \340 CFI_END SEPARATOR \341 .size SYMBOL_NAME(name), . - SYMBOL_NAME(name)342#else343#define END_COMPILERRT_FUNCTION(name)344#define END_COMPILERRT_OUTLINE_FUNCTION(name) \345 CFI_END346#endif347 348#ifdef __arm__349#include "int_endianness.h"350 351#if _YUGA_BIG_ENDIAN352#define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src1, src0 SEPARATOR353#define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst1, dst0, src SEPARATOR354#else355#define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src0, src1 SEPARATOR356#define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst0, dst1, src SEPARATOR357#endif358#endif359 360#if defined(__ASSEMBLER__) && (defined(__i386__) || defined(__amd64__)) && \361 !defined(__arm64ec__)362.att_syntax363#endif364 365#endif // COMPILERRT_ASSEMBLY_H366