Spaces:
Runtime error
Runtime error
/* | |
* Copyright (c) 2008 Mans Rullgard <[email protected]> | |
* | |
* This file is part of FFmpeg. | |
* | |
* FFmpeg is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU Lesser General Public | |
* License as published by the Free Software Foundation; either | |
* version 2.1 of the License, or (at your option) any later version. | |
* | |
* FFmpeg is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* Lesser General Public License for more details. | |
* | |
* You should have received a copy of the GNU Lesser General Public | |
* License along with FFmpeg; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
/* Support macros for | |
* - Armv8.3-A Pointer Authentication and | |
* - Armv8.5-A Branch Target Identification | |
* features which require emitting a .note.gnu.property section with the | |
* appropriate architecture-dependent feature bits set. | |
* | |
* |AARCH64_SIGN_LINK_REGISTER| and |AARCH64_VALIDATE_LINK_REGISTER| expand to | |
* PACIxSP and AUTIxSP, respectively. |AARCH64_SIGN_LINK_REGISTER| should be | |
* used immediately before saving the LR register (x30) to the stack. | |
* |AARCH64_VALIDATE_LINK_REGISTER| should be used immediately after restoring | |
* it. Note |AARCH64_SIGN_LINK_REGISTER|'s modifications to LR must be undone | |
* with |AARCH64_VALIDATE_LINK_REGISTER| before RET. The SP register must also | |
* have the same value at the two points. For example: | |
* | |
* .global f | |
* f: | |
* AARCH64_SIGN_LINK_REGISTER | |
* stp x29, x30, [sp, #-96]! | |
* mov x29, sp | |
* ... | |
* ldp x29, x30, [sp], #96 | |
* AARCH64_VALIDATE_LINK_REGISTER | |
* ret | |
* | |
* |AARCH64_VALID_CALL_TARGET| expands to BTI 'c'. Either it, or | |
* |AARCH64_SIGN_LINK_REGISTER|, must be used at every point that may be an | |
* indirect call target. In particular, all symbols exported from a file must | |
* begin with one of these macros. For example, a leaf function that does not | |
* save LR can instead use |AARCH64_VALID_CALL_TARGET|: | |
* | |
* .globl return_zero | |
* return_zero: | |
* AARCH64_VALID_CALL_TARGET | |
* mov x0, #0 | |
* ret | |
* | |
* A non-leaf function which does not immediately save LR may need both macros | |
* because |AARCH64_SIGN_LINK_REGISTER| appears late. For example, the function | |
* may jump to an alternate implementation before setting up the stack: | |
* | |
* .globl with_early_jump | |
* with_early_jump: | |
* AARCH64_VALID_CALL_TARGET | |
* cmp x0, #128 | |
* b.lt .Lwith_early_jump_128 | |
* AARCH64_SIGN_LINK_REGISTER | |
* stp x29, x30, [sp, #-96]! | |
* mov x29, sp | |
* ... | |
* ldp x29, x30, [sp], #96 | |
* AARCH64_VALIDATE_LINK_REGISTER | |
* ret | |
* | |
* .Lwith_early_jump_128: | |
* ... | |
* ret | |
* | |
* These annotations are only required with indirect calls. Private symbols that | |
* are only the target of direct calls do not require annotations. Also note | |
* that |AARCH64_VALID_CALL_TARGET| is only valid for indirect calls (BLR), not | |
* indirect jumps (BR). Indirect jumps in assembly are supported through | |
* |AARCH64_VALID_JUMP_TARGET|. Landing Pads which shall serve for jumps and | |
* calls can be created using |AARCH64_VALID_JUMP_CALL_TARGET|. | |
* | |
* Although not necessary, it is safe to use these macros in 32-bit ARM | |
* assembly. This may be used to simplify dual 32-bit and 64-bit files. | |
* | |
* References: | |
* - "ELF for the Arm® 64-bit Architecture" | |
* https: *github.com/ARM-software/abi-aa/blob/master/aaelf64/aaelf64.rst | |
* - "Providing protection for complex software" | |
* https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software | |
*/ | |
.pushsection .note.gnu.property, "a" | |
.balign 8 | |
.long 4 | |
.long 0x10 | |
.long 0x5 | |
.asciz "GNU" | |
.long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ | |
.long 4 | |
.long (GNU_PROPERTY_AARCH64_BTI | GNU_PROPERTY_AARCH64_PAC) | |
.long 0 | |
.popsection | |
.macro function name, export=0, align=2 | |
.macro endfunc | |
ELF .size \name, . - \name | |
FUNC .endfunc | |
.purgem endfunc | |
.endm | |
.text | |
.align \align | |
.if \export | |
.global EXTERN_ASM\name | |
ELF .type EXTERN_ASM\name, %function | |
FUNC .func EXTERN_ASM\name | |
EXTERN_ASM\name: | |
AARCH64_VALID_CALL_TARGET | |
.else | |
ELF .type \name, %function | |
FUNC .func \name | |
\name: | |
.endif | |
.endm | |
.macro const name, align=2, relocate=0 | |
.macro endconst | |
ELF .size \name, . - \name | |
.purgem endconst | |
.endm | |
.if \relocate | |
.section .data.rel.ro | |
.else | |
.section .rodata | |
.endif | |
.section .rdata | |
.section .rodata | |
.const_data | |
.align \align | |
\name: | |
.endm | |
.macro movrel rd, val, offset=0 | |
.if \offset < 0 | |
adrp \rd, \val@PAGE | |
add \rd, \rd, \val@PAGEOFF | |
sub \rd, \rd, -(\offset) | |
.else | |
adrp \rd, \val+(\offset)@PAGE | |
add \rd, \rd, \val+(\offset)@PAGEOFF | |
.endif | |
.if \offset < 0 | |
adrp \rd, \val | |
add \rd, \rd, :lo12:\val | |
sub \rd, \rd, -(\offset) | |
.else | |
adrp \rd, \val+(\offset) | |
add \rd, \rd, :lo12:\val+(\offset) | |
.endif | |
adrp \rd, :pg_hi21_nc:\val+(\offset) | |
adrp \rd, \val+(\offset) | |
add \rd, \rd, :lo12:\val+(\offset) | |
ldr \rd, =\val+\offset | |
.endm | |