1/* 2 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "config.h" 22 23#ifdef __ELF__ 24# define ELF 25#else 26# define ELF # 27#endif 28 29#if HAVE_AS_FUNC 30# define FUNC 31#else 32# define FUNC # 33#endif 34 35#ifndef __has_feature 36# define __has_feature(x) 0 37#endif 38 39 40/* Support macros for 41 * - Armv8.3-A Pointer Authentication and 42 * - Armv8.5-A Branch Target Identification 43 * features which require emitting a .note.gnu.property section with the 44 * appropriate architecture-dependent feature bits set. 45 * 46 * |AARCH64_SIGN_LINK_REGISTER| and |AARCH64_VALIDATE_LINK_REGISTER| expand to 47 * PACIxSP and AUTIxSP, respectively. |AARCH64_SIGN_LINK_REGISTER| should be 48 * used immediately before saving the LR register (x30) to the stack. 49 * |AARCH64_VALIDATE_LINK_REGISTER| should be used immediately after restoring 50 * it. Note |AARCH64_SIGN_LINK_REGISTER|'s modifications to LR must be undone 51 * with |AARCH64_VALIDATE_LINK_REGISTER| before RET. The SP register must also 52 * have the same value at the two points. For example: 53 * 54 * .global f 55 * f: 56 * AARCH64_SIGN_LINK_REGISTER 57 * stp x29, x30, [sp, #-96]! 58 * mov x29, sp 59 * ... 60 * ldp x29, x30, [sp], #96 61 * AARCH64_VALIDATE_LINK_REGISTER 62 * ret 63 * 64 * |AARCH64_VALID_CALL_TARGET| expands to BTI 'c'. Either it, or 65 * |AARCH64_SIGN_LINK_REGISTER|, must be used at every point that may be an 66 * indirect call target. In particular, all symbols exported from a file must 67 * begin with one of these macros. For example, a leaf function that does not 68 * save LR can instead use |AARCH64_VALID_CALL_TARGET|: 69 * 70 * .globl return_zero 71 * return_zero: 72 * AARCH64_VALID_CALL_TARGET 73 * mov x0, #0 74 * ret 75 * 76 * A non-leaf function which does not immediately save LR may need both macros 77 * because |AARCH64_SIGN_LINK_REGISTER| appears late. For example, the function 78 * may jump to an alternate implementation before setting up the stack: 79 * 80 * .globl with_early_jump 81 * with_early_jump: 82 * AARCH64_VALID_CALL_TARGET 83 * cmp x0, #128 84 * b.lt .Lwith_early_jump_128 85 * AARCH64_SIGN_LINK_REGISTER 86 * stp x29, x30, [sp, #-96]! 87 * mov x29, sp 88 * ... 89 * ldp x29, x30, [sp], #96 90 * AARCH64_VALIDATE_LINK_REGISTER 91 * ret 92 * 93 * .Lwith_early_jump_128: 94 * ... 95 * ret 96 * 97 * These annotations are only required with indirect calls. Private symbols that 98 * are only the target of direct calls do not require annotations. Also note 99 * that |AARCH64_VALID_CALL_TARGET| is only valid for indirect calls (BLR), not 100 * indirect jumps (BR). Indirect jumps in assembly are supported through 101 * |AARCH64_VALID_JUMP_TARGET|. Landing Pads which shall serve for jumps and 102 * calls can be created using |AARCH64_VALID_JUMP_CALL_TARGET|. 103 * 104 * Although not necessary, it is safe to use these macros in 32-bit ARM 105 * assembly. This may be used to simplify dual 32-bit and 64-bit files. 106 * 107 * References: 108 * - "ELF for the Arm® 64-bit Architecture" 109 * https: *github.com/ARM-software/abi-aa/blob/master/aaelf64/aaelf64.rst 110 * - "Providing protection for complex software" 111 * https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software 112 */ 113#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) 114# define GNU_PROPERTY_AARCH64_BTI (1 << 0) // Has BTI 115# define AARCH64_VALID_CALL_TARGET hint #34 // BTI 'c' 116# define AARCH64_VALID_JUMP_TARGET hint #38 // BTI 'j' 117#else 118# define GNU_PROPERTY_AARCH64_BTI 0 // No BTI 119# define AARCH64_VALID_CALL_TARGET 120# define AARCH64_VALID_JUMP_TARGET 121#endif 122 123#if defined(__ARM_FEATURE_PAC_DEFAULT) 124# if ((__ARM_FEATURE_PAC_DEFAULT & (1 << 0)) != 0) // authentication using key A 125# define AARCH64_SIGN_LINK_REGISTER paciasp 126# define AARCH64_VALIDATE_LINK_REGISTER autiasp 127# elif ((__ARM_FEATURE_PAC_DEFAULT & (1 << 1)) != 0) // authentication using key B 128# define AARCH64_SIGN_LINK_REGISTER pacibsp 129# define AARCH64_VALIDATE_LINK_REGISTER autibsp 130# else 131# error Pointer authentication defines no valid key! 132# endif 133# if ((__ARM_FEATURE_PAC_DEFAULT & (1 << 2)) != 0) 134# error Authentication of leaf functions is enabled but not supported in FFmpeg! 135# endif 136# define GNU_PROPERTY_AARCH64_PAC (1 << 1) 137#else 138# define GNU_PROPERTY_AARCH64_PAC 0 139# define AARCH64_SIGN_LINK_REGISTER 140# define AARCH64_VALIDATE_LINK_REGISTER 141#endif 142 143 144#if (GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_PAC != 0) && defined(__ELF__) 145 .pushsection .note.gnu.property, "a" 146 .balign 8 147 .long 4 148 .long 0x10 149 .long 0x5 150 .asciz "GNU" 151 .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ 152 .long 4 153 .long (GNU_PROPERTY_AARCH64_BTI | GNU_PROPERTY_AARCH64_PAC) 154 .long 0 155 .popsection 156#endif 157 158.macro function name, export=0, align=2 159 .macro endfunc 160ELF .size \name, . - \name 161FUNC .endfunc 162 .purgem endfunc 163 .endm 164 .text 165 .align \align 166 .if \export 167 .global EXTERN_ASM\name 168ELF .type EXTERN_ASM\name, %function 169FUNC .func EXTERN_ASM\name 170EXTERN_ASM\name: 171 AARCH64_VALID_CALL_TARGET 172 .else 173ELF .type \name, %function 174FUNC .func \name 175\name: 176 .endif 177.endm 178 179.macro const name, align=2, relocate=0 180 .macro endconst 181ELF .size \name, . - \name 182 .purgem endconst 183 .endm 184#if HAVE_SECTION_DATA_REL_RO 185.if \relocate 186 .section .data.rel.ro 187.else 188 .section .rodata 189.endif 190#elif defined(_WIN32) 191 .section .rdata 192#elif !defined(__MACH__) 193 .section .rodata 194#else 195 .const_data 196#endif 197 .align \align 198\name: 199.endm 200 201.macro movrel rd, val, offset=0 202#if CONFIG_PIC && defined(__APPLE__) 203 .if \offset < 0 204 adrp \rd, \val@PAGE 205 add \rd, \rd, \val@PAGEOFF 206 sub \rd, \rd, -(\offset) 207 .else 208 adrp \rd, \val+(\offset)@PAGE 209 add \rd, \rd, \val+(\offset)@PAGEOFF 210 .endif 211#elif CONFIG_PIC && defined(_WIN32) 212 .if \offset < 0 213 adrp \rd, \val 214 add \rd, \rd, :lo12:\val 215 sub \rd, \rd, -(\offset) 216 .else 217 adrp \rd, \val+(\offset) 218 add \rd, \rd, :lo12:\val+(\offset) 219 .endif 220#elif CONFIG_PIC 221# if __has_feature(hwaddress_sanitizer) 222 adrp \rd, :pg_hi21_nc:\val+(\offset) 223# else 224 adrp \rd, \val+(\offset) 225# endif 226 add \rd, \rd, :lo12:\val+(\offset) 227#else 228 ldr \rd, =\val+\offset 229#endif 230.endm 231 232#define GLUE(a, b) a ## b 233#define JOIN(a, b) GLUE(a, b) 234#define X(s) JOIN(EXTERN_ASM, s) 235 236#define x18 do_not_use_x18 237#define w18 do_not_use_w18 238