kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

assembly.h (8643B)


      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-exception
      6 //
      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_H
     15 #define COMPILERRT_ASSEMBLY_H
     16 
     17 #if defined(__linux__) && defined(__CET__)
     18 #if __has_include(<cet.h>)
     19 #include <cet.h>
     20 #endif
     21 #endif
     22 
     23 #if defined(__APPLE__) && defined(__aarch64__)
     24 #define SEPARATOR % %
     25 #else
     26 #define SEPARATOR ;
     27 #endif
     28 
     29 #if defined(__APPLE__)
     30 #define HIDDEN(name) .private_extern name
     31 #define LOCAL_LABEL(name) L_##name
     32 // tell linker it can break up file at label boundaries
     33 #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols
     34 #define SYMBOL_IS_FUNC(name)
     35 #define CONST_SECTION .const
     36 
     37 #define NO_EXEC_STACK_DIRECTIVE
     38 
     39 #elif defined(__ELF__)
     40 
     41 #define HIDDEN(name) .hidden name
     42 #define LOCAL_LABEL(name) .L_##name
     43 #define FILE_LEVEL_DIRECTIVE
     44 #if defined(__arm__) || defined(__aarch64__)
     45 #define SYMBOL_IS_FUNC(name) .type name, % function
     46 #else
     47 #define SYMBOL_IS_FUNC(name) .type name, @function
     48 #endif
     49 #define CONST_SECTION .section.rodata
     50 
     51 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
     52     defined(__linux__)
     53 #define NO_EXEC_STACK_DIRECTIVE .section.note.GNU - stack, "", % progbits
     54 #else
     55 #define NO_EXEC_STACK_DIRECTIVE
     56 #endif
     57 
     58 #else  // !__APPLE__ && !__ELF__
     59 
     60 #define HIDDEN(name)
     61 #define LOCAL_LABEL(name) .L##name
     62 #define FILE_LEVEL_DIRECTIVE
     63 #define SYMBOL_IS_FUNC(name) \
     64   .def name SEPARATOR.scl 2 SEPARATOR.type 32 SEPARATOR.endef
     65 #define CONST_SECTION .section.rdata, "rd"
     66 
     67 #define NO_EXEC_STACK_DIRECTIVE
     68 
     69 #endif
     70 
     71 #if defined(__arm__) || defined(__aarch64__)
     72 #define FUNC_ALIGN .text SEPARATOR.balign 16 SEPARATOR
     73 #else
     74 #define FUNC_ALIGN
     75 #endif
     76 
     77 // BTI and PAC gnu property note
     78 #define NT_GNU_PROPERTY_TYPE_0 5
     79 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
     80 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1
     81 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2
     82 
     83 #if defined(__ARM_FEATURE_BTI_DEFAULT)
     84 #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI
     85 #else
     86 #define BTI_FLAG 0
     87 #endif
     88 
     89 #if __ARM_FEATURE_PAC_DEFAULT & 3
     90 #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC
     91 #else
     92 #define PAC_FLAG 0
     93 #endif
     94 
     95 #define GNU_PROPERTY(type, value)                                          \
     96   .pushsection.note.gnu.property,                                          \
     97       "a" SEPARATOR.p2align 3 SEPARATOR.word 4 SEPARATOR.word 16 SEPARATOR \
     98           .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR.asciz                     \
     99       "GNU" SEPARATOR.word type SEPARATOR.word 4 SEPARATOR.word value      \
    100           SEPARATOR.word 0 SEPARATOR.popsection
    101 
    102 #if BTI_FLAG != 0
    103 #define BTI_C hint #34
    104 #define BTI_J hint #36
    105 #else
    106 #define BTI_C
    107 #define BTI_J
    108 #endif
    109 
    110 #if (BTI_FLAG | PAC_FLAG) != 0
    111 #define GNU_PROPERTY_BTI_PAC \
    112   GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG)
    113 #else
    114 #define GNU_PROPERTY_BTI_PAC
    115 #endif
    116 
    117 #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM)
    118 #define CFI_START .cfi_startproc
    119 #define CFI_END .cfi_endproc
    120 #else
    121 #define CFI_START
    122 #define CFI_END
    123 #endif
    124 
    125 #if defined(__arm__)
    126 
    127 // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:
    128 // - for '-mthumb -march=armv6' compiler defines '__thumb__'
    129 // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'
    130 #if defined(__thumb2__) || defined(__thumb__)
    131 #define DEFINE_CODE_STATE .thumb SEPARATOR
    132 #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR
    133 #if defined(__thumb2__)
    134 #define USE_THUMB_2
    135 #define IT(cond) it cond
    136 #define ITT(cond) itt cond
    137 #define ITE(cond) ite cond
    138 #else
    139 #define USE_THUMB_1
    140 #define IT(cond)
    141 #define ITT(cond)
    142 #define ITE(cond)
    143 #endif  // defined(__thumb__2)
    144 #else   // !defined(__thumb2__) && !defined(__thumb__)
    145 #define DEFINE_CODE_STATE .arm SEPARATOR
    146 #define DECLARE_FUNC_ENCODING
    147 #define IT(cond)
    148 #define ITT(cond)
    149 #define ITE(cond)
    150 #endif
    151 
    152 #if defined(USE_THUMB_1) && defined(USE_THUMB_2)
    153 #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together."
    154 #endif
    155 
    156 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
    157 #define ARM_HAS_BX
    158 #endif
    159 #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \
    160     (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))
    161 #define __ARM_FEATURE_CLZ
    162 #endif
    163 
    164 #ifdef ARM_HAS_BX
    165 #define JMP(r) bx r
    166 #define JMPc(r, c) bx##c r
    167 #else
    168 #define JMP(r) mov pc, r
    169 #define JMPc(r, c) mov##c pc, r
    170 #endif
    171 
    172 // pop {pc} can't switch Thumb mode on ARMv4T
    173 #if __ARM_ARCH >= 5
    174 #define POP_PC() \
    175   pop { pc }
    176 #else
    177 #define POP_PC() \
    178   pop{ip};       \
    179   JMP(ip)
    180 #endif
    181 
    182 #if defined(USE_THUMB_2)
    183 #define WIDE(op) op.w
    184 #else
    185 #define WIDE(op) op
    186 #endif
    187 #else  // !defined(__arm)
    188 #define DECLARE_FUNC_ENCODING
    189 #define DEFINE_CODE_STATE
    190 #endif
    191 
    192 #define GLUE2_(a, b) a##b
    193 #define GLUE(a, b) GLUE2_(a, b)
    194 #define GLUE2(a, b) GLUE2_(a, b)
    195 #define GLUE3_(a, b, c) a##b##c
    196 #define GLUE3(a, b, c) GLUE3_(a, b, c)
    197 #define GLUE4_(a, b, c, d) a##b##c##d
    198 #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d)
    199 
    200 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
    201 
    202 #ifdef VISIBILITY_HIDDEN
    203 #define DECLARE_SYMBOL_VISIBILITY(name) HIDDEN(SYMBOL_NAME(name)) SEPARATOR
    204 #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) HIDDEN(name) SEPARATOR
    205 #else
    206 #define DECLARE_SYMBOL_VISIBILITY(name)
    207 #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name)
    208 #endif
    209 
    210 #define DEFINE_COMPILERRT_FUNCTION(name)                                      \
    211   DEFINE_CODE_STATE                                                           \
    212   FILE_LEVEL_DIRECTIVE SEPARATOR.globl SYMBOL_NAME(name)                      \
    213   SEPARATOR                                                                   \
    214   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR DECLARE_SYMBOL_VISIBILITY(name) \
    215   DECLARE_FUNC_ENCODING                                                       \
    216   SYMBOL_NAME(name) :
    217 
    218 #define DEFINE_COMPILERRT_THUMB_FUNCTION(name)           \
    219   DEFINE_CODE_STATE                                      \
    220   FILE_LEVEL_DIRECTIVE SEPARATOR.globl SYMBOL_NAME(name) \
    221   SEPARATOR                                              \
    222   SYMBOL_IS_FUNC(SYMBOL_NAME(name))                      \
    223   SEPARATOR DECLARE_SYMBOL_VISIBILITY(name)              \
    224       SEPARATOR.thumb_func SEPARATOR SYMBOL_NAME(name)   \
    225       :
    226 
    227 #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name)         \
    228   DEFINE_CODE_STATE                                      \
    229   FILE_LEVEL_DIRECTIVE SEPARATOR.globl SYMBOL_NAME(name) \
    230   SEPARATOR                                              \
    231   SYMBOL_IS_FUNC(SYMBOL_NAME(name))                      \
    232   SEPARATOR HIDDEN(SYMBOL_NAME(name))                    \
    233       SEPARATOR DECLARE_FUNC_ENCODING SYMBOL_NAME(name)  \
    234       :
    235 
    236 #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name)    \
    237   DEFINE_CODE_STATE.globl name SEPARATOR SYMBOL_IS_FUNC(name) \
    238   SEPARATOR                                                   \
    239   HIDDEN(name) SEPARATOR DECLARE_FUNC_ENCODING name:
    240 
    241 #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \
    242   DEFINE_CODE_STATE                                        \
    243   FUNC_ALIGN.globl name SEPARATOR SYMBOL_IS_FUNC(name)     \
    244   SEPARATOR                                                \
    245   DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name)                \
    246   SEPARATOR DECLARE_FUNC_ENCODING name : SEPARATOR CFI_START SEPARATOR BTI_C
    247 
    248 #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target)                       \
    249   .globl SYMBOL_NAME(name)                                                   \
    250   SEPARATOR                                                                  \
    251   SYMBOL_IS_FUNC(SYMBOL_NAME(name))                                          \
    252   SEPARATOR DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR.set SYMBOL_NAME(name), \
    253       SYMBOL_NAME(target) SEPARATOR
    254 
    255 #if defined(__ARM_EABI__)
    256 #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \
    257   DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)
    258 #else
    259 #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)
    260 #endif
    261 
    262 #ifdef __ELF__
    263 #define END_COMPILERRT_FUNCTION(name) \
    264   .size SYMBOL_NAME(name), .- SYMBOL_NAME(name)
    265 #define END_COMPILERRT_OUTLINE_FUNCTION(name) \
    266   CFI_END SEPARATOR.size SYMBOL_NAME(name), .- SYMBOL_NAME(name)
    267 #else
    268 #define END_COMPILERRT_FUNCTION(name)
    269 #define END_COMPILERRT_OUTLINE_FUNCTION(name) CFI_END
    270 #endif
    271 
    272 #endif  // COMPILERRT_ASSEMBLY_H