• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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