]>
Commit | Line | Data |
---|---|---|
6d7e8eda | 1 | /* Copyright (C) 1997-2023 Free Software Foundation, Inc. |
554066b8 MS |
2 | |
3 | This file is part of the GNU C Library. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public License as | |
7 | published by the Free Software Foundation; either version 2.1 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
554066b8 | 18 | |
389d1f1b SE |
19 | #ifndef _AARCH64_SYSDEP_H |
20 | #define _AARCH64_SYSDEP_H | |
21 | ||
554066b8 MS |
22 | #include <sysdeps/generic/sysdep.h> |
23 | ||
389d1f1b SE |
24 | #ifdef __LP64__ |
25 | # define AARCH64_R(NAME) R_AARCH64_ ## NAME | |
26 | # define PTR_REG(n) x##n | |
27 | # define PTR_LOG_SIZE 3 | |
45b1e17e SN |
28 | # define PTR_ARG(n) |
29 | # define SIZE_ARG(n) | |
389d1f1b SE |
30 | #else |
31 | # define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME | |
32 | # define PTR_REG(n) w##n | |
33 | # define PTR_LOG_SIZE 2 | |
45b1e17e SN |
34 | # define PTR_ARG(n) mov w##n, w##n |
35 | # define SIZE_ARG(n) mov w##n, w##n | |
389d1f1b SE |
36 | #endif |
37 | ||
38 | #define PTR_SIZE (1<<PTR_LOG_SIZE) | |
39 | ||
c9476771 SN |
40 | #ifndef __ASSEMBLER__ |
41 | /* Strip pointer authentication code from pointer p. */ | |
42 | static inline void * | |
43 | strip_pac (void *p) | |
44 | { | |
45 | register void *ra asm ("x30") = (p); | |
46 | asm ("hint 7 // xpaclri" : "+r"(ra)); | |
47 | return ra; | |
48 | } | |
d174ec24 SN |
49 | |
50 | /* This is needed when glibc is built with -mbranch-protection=pac-ret | |
51 | with a gcc that is affected by PR target/94891. */ | |
52 | # if HAVE_AARCH64_PAC_RET | |
53 | # undef RETURN_ADDRESS | |
54 | # define RETURN_ADDRESS(n) strip_pac (__builtin_return_address (n)) | |
55 | # endif | |
c9476771 SN |
56 | #endif |
57 | ||
554066b8 MS |
58 | #ifdef __ASSEMBLER__ |
59 | ||
60 | /* Syntactic details of assembler. */ | |
61 | ||
62 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name | |
63 | ||
91181954 | 64 | /* Branch Target Identitication support. */ |
bd4317fb NT |
65 | #if HAVE_AARCH64_BTI |
66 | # define BTI_C hint 34 | |
67 | # define BTI_J hint 36 | |
68 | #else | |
69 | # define BTI_C nop | |
70 | # define BTI_J nop | |
71 | #endif | |
91181954 | 72 | |
1be3d6eb SN |
73 | /* Return address signing support (pac-ret). */ |
74 | #define PACIASP hint 25 | |
75 | #define AUTIASP hint 29 | |
76 | ||
91181954 SD |
77 | /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */ |
78 | #define FEATURE_1_AND 0xc0000000 | |
79 | #define FEATURE_1_BTI 1 | |
80 | #define FEATURE_1_PAC 2 | |
81 | ||
82 | /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ | |
83 | #define GNU_PROPERTY(type, value) \ | |
84 | .section .note.gnu.property, "a"; \ | |
85 | .p2align 3; \ | |
86 | .word 4; \ | |
87 | .word 16; \ | |
88 | .word 5; \ | |
89 | .asciz "GNU"; \ | |
90 | .word type; \ | |
91 | .word 4; \ | |
92 | .word value; \ | |
93 | .word 0; \ | |
94 | .text | |
95 | ||
96 | /* Add GNU property note with the supported features to all asm code | |
97 | where sysdep.h is included. */ | |
1be3d6eb SN |
98 | #if HAVE_AARCH64_BTI && HAVE_AARCH64_PAC_RET |
99 | GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC) | |
100 | #elif HAVE_AARCH64_BTI | |
91181954 SD |
101 | GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI) |
102 | #endif | |
103 | ||
554066b8 | 104 | /* Define an entry point visible from C. */ |
62216a0a MS |
105 | #define ENTRY(name) \ |
106 | .globl C_SYMBOL_NAME(name); \ | |
107 | .type C_SYMBOL_NAME(name),%function; \ | |
34f0d01d | 108 | .p2align 6; \ |
62216a0a MS |
109 | C_LABEL(name) \ |
110 | cfi_startproc; \ | |
91181954 | 111 | BTI_C; \ |
554066b8 MS |
112 | CALL_MCOUNT |
113 | ||
14d941e4 MS |
114 | /* Define an entry point visible from C. */ |
115 | #define ENTRY_ALIGN(name, align) \ | |
116 | .globl C_SYMBOL_NAME(name); \ | |
117 | .type C_SYMBOL_NAME(name),%function; \ | |
118 | .p2align align; \ | |
119 | C_LABEL(name) \ | |
120 | cfi_startproc; \ | |
91181954 | 121 | BTI_C; \ |
14d941e4 MS |
122 | CALL_MCOUNT |
123 | ||
4499bb3e MS |
124 | /* Define an entry point visible from C with a specified alignment and |
125 | pre-padding with NOPs. This can be used to ensure that a critical | |
126 | loop within a function is cache line aligned. Note this version | |
127 | does not adjust the padding if CALL_MCOUNT is defined. */ | |
128 | ||
129 | #define ENTRY_ALIGN_AND_PAD(name, align, padding) \ | |
130 | .globl C_SYMBOL_NAME(name); \ | |
131 | .type C_SYMBOL_NAME(name),%function; \ | |
132 | .p2align align; \ | |
91181954 | 133 | .rep padding - 1; /* -1 for bti c. */ \ |
4499bb3e MS |
134 | nop; \ |
135 | .endr; \ | |
136 | C_LABEL(name) \ | |
137 | cfi_startproc; \ | |
91181954 | 138 | BTI_C; \ |
4499bb3e MS |
139 | CALL_MCOUNT |
140 | ||
554066b8 | 141 | #undef END |
62216a0a MS |
142 | #define END(name) \ |
143 | cfi_endproc; \ | |
554066b8 MS |
144 | ASM_SIZE_DIRECTIVE(name) |
145 | ||
146 | /* If compiled for profiling, call `mcount' at the start of each function. */ | |
147 | #ifdef PROF | |
62216a0a | 148 | # define CALL_MCOUNT \ |
efbe665c SN |
149 | str x30, [sp, #-80]!; \ |
150 | cfi_adjust_cfa_offset (80); \ | |
151 | cfi_rel_offset (x30, 0); \ | |
152 | stp x0, x1, [sp, #16]; \ | |
153 | cfi_rel_offset (x0, 16); \ | |
154 | cfi_rel_offset (x1, 24); \ | |
155 | stp x2, x3, [sp, #32]; \ | |
156 | cfi_rel_offset (x2, 32); \ | |
157 | cfi_rel_offset (x3, 40); \ | |
158 | stp x4, x5, [sp, #48]; \ | |
159 | cfi_rel_offset (x4, 48); \ | |
160 | cfi_rel_offset (x5, 56); \ | |
161 | stp x6, x7, [sp, #64]; \ | |
162 | cfi_rel_offset (x6, 64); \ | |
163 | cfi_rel_offset (x7, 72); \ | |
164 | mov x0, x30; \ | |
62216a0a | 165 | bl mcount; \ |
efbe665c SN |
166 | ldp x0, x1, [sp, #16]; \ |
167 | cfi_restore (x0); \ | |
168 | cfi_restore (x1); \ | |
169 | ldp x2, x3, [sp, #32]; \ | |
170 | cfi_restore (x2); \ | |
171 | cfi_restore (x3); \ | |
172 | ldp x4, x5, [sp, #48]; \ | |
173 | cfi_restore (x4); \ | |
174 | cfi_restore (x5); \ | |
175 | ldp x6, x7, [sp, #64]; \ | |
176 | cfi_restore (x6); \ | |
177 | cfi_restore (x7); \ | |
178 | ldr x30, [sp], #80; \ | |
179 | cfi_adjust_cfa_offset (-80); \ | |
180 | cfi_restore (x30); | |
554066b8 MS |
181 | #else |
182 | # define CALL_MCOUNT /* Do nothing. */ | |
183 | #endif | |
184 | ||
185 | /* Local label name for asm code. */ | |
186 | #ifndef L | |
187 | # define L(name) .L##name | |
188 | #endif | |
189 | ||
389d1f1b SE |
190 | /* Load or store to/from a pc-relative EXPR into/from R, using T. |
191 | Note R and T are register numbers and not register names. */ | |
192 | #define LDST_PCREL(OP, R, T, EXPR) \ | |
193 | adrp x##T, EXPR; \ | |
194 | OP PTR_REG (R), [x##T, #:lo12:EXPR]; \ | |
9188b681 | 195 | |
389d1f1b SE |
196 | /* Load or store to/from a got-relative EXPR into/from R, using T. |
197 | Note R and T are register numbers and not register names. */ | |
198 | #define LDST_GLOBAL(OP, R, T, EXPR) \ | |
199 | adrp x##T, :got:EXPR; \ | |
200 | ldr PTR_REG (T), [x##T, #:got_lo12:EXPR]; \ | |
201 | OP PTR_REG (R), [x##T]; | |
9188b681 | 202 | |
6cd380dd WB |
203 | /* Load an immediate into R. |
204 | Note R is a register number and not a register name. */ | |
205 | #ifdef __LP64__ | |
206 | # define MOVL(R, NAME) \ | |
207 | movz PTR_REG (R), #:abs_g3:NAME; \ | |
208 | movk PTR_REG (R), #:abs_g2_nc:NAME; \ | |
209 | movk PTR_REG (R), #:abs_g1_nc:NAME; \ | |
210 | movk PTR_REG (R), #:abs_g0_nc:NAME; | |
211 | #else | |
212 | # define MOVL(R, NAME) \ | |
213 | movz PTR_REG (R), #:abs_g1:NAME; \ | |
214 | movk PTR_REG (R), #:abs_g0_nc:NAME; | |
215 | #endif | |
216 | ||
554066b8 MS |
217 | /* Since C identifiers are not normally prefixed with an underscore |
218 | on this system, the asm identifier `syscall_error' intrudes on the | |
219 | C name space. Make sure we use an innocuous name. */ | |
220 | #define syscall_error __syscall_error | |
221 | #define mcount _mcount | |
222 | ||
223 | #endif /* __ASSEMBLER__ */ | |
389d1f1b SE |
224 | |
225 | #endif /* _AARCH64_SYSDEP_H */ |