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