Update release-README after completing the 2.43 release.
[binutils-gdb.git] / bfd / elfnn-aarch64.c
blob94c9a01069b4384cf15e8512783dff4378ecd283
1 /* AArch64-specific support for NN-bit ELF.
2 Copyright (C) 2009-2024 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* Notes on implementation:
23 Thread Local Store (TLS)
25 Overview:
27 The implementation currently supports both traditional TLS and TLS
28 descriptors, but only general dynamic (GD).
30 For traditional TLS the assembler will present us with code
31 fragments of the form:
33 adrp x0, :tlsgd:foo
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
37 bl __tls_get_addr
38 nop
40 For TLS descriptors the assembler will present us with code
41 fragments of the form:
43 adrp x0, :tlsdesc:foo R_AARCH64_TLSDESC_ADR_PAGE21(foo)
44 ldr x1, [x0, #:tlsdesc_lo12:foo] R_AARCH64_TLSDESC_LD64_LO12(foo)
45 add x0, x0, #:tlsdesc_lo12:foo R_AARCH64_TLSDESC_ADD_LO12(foo)
46 .tlsdesccall foo
47 blr x1 R_AARCH64_TLSDESC_CALL(foo)
49 The relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} against foo
50 indicate that foo is thread local and should be accessed via the
51 traditional TLS mechanims.
53 The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
54 against foo indicate that 'foo' is thread local and should be accessed
55 via a TLS descriptor mechanism.
57 The precise instruction sequence is only relevant from the
58 perspective of linker relaxation which is currently not implemented.
60 The static linker must detect that 'foo' is a TLS object and
61 allocate a double GOT entry. The GOT entry must be created for both
62 global and local TLS symbols. Note that this is different to none
63 TLS local objects which do not need a GOT entry.
65 In the traditional TLS mechanism, the double GOT entry is used to
66 provide the tls_index structure, containing module and offset
67 entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
68 on the module entry. The loader will subsequently fixup this
69 relocation with the module identity.
71 For global traditional TLS symbols the static linker places an
72 R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
73 will subsequently fixup the offset. For local TLS symbols the static
74 linker fixes up offset.
76 In the TLS descriptor mechanism the double GOT entry is used to
77 provide the descriptor. The static linker places the relocation
78 R_AARCH64_TLSDESC on the first GOT slot. The loader will
79 subsequently fix this up.
81 Implementation:
83 The handling of TLS symbols is implemented across a number of
84 different backend functions. The following is a top level view of
85 what processing is performed where.
87 The TLS implementation maintains state information for each TLS
88 symbol. The state information for local and global symbols is kept
89 in different places. Global symbols use generic BFD structures while
90 local symbols use backend specific structures that are allocated and
91 maintained entirely by the backend.
93 The flow:
95 elfNN_aarch64_check_relocs()
97 This function is invoked for each relocation.
99 The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
100 R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
101 spotted. One time creation of local symbol data structures are
102 created when the first local symbol is seen.
104 The reference count for a symbol is incremented. The GOT type for
105 each symbol is marked as general dynamic.
107 elfNN_aarch64_allocate_dynrelocs ()
109 For each global with positive reference count we allocate a double
110 GOT slot. For a traditional TLS symbol we allocate space for two
111 relocation entries on the GOT, for a TLS descriptor symbol we
112 allocate space for one relocation on the slot. Record the GOT offset
113 for this symbol.
115 elfNN_aarch64_late_size_sections ()
117 Iterate all input BFDS, look for in the local symbol data structure
118 constructed earlier for local TLS symbols and allocate them double
119 GOT slots along with space for a single GOT relocation. Update the
120 local symbol structure to record the GOT offset allocated.
122 elfNN_aarch64_relocate_section ()
124 Calls elfNN_aarch64_final_link_relocate ()
126 Emit the relevant TLS relocations against the GOT for each TLS
127 symbol. For local TLS symbols emit the GOT offset directly. The GOT
128 relocations are emitted once the first time a TLS symbol is
129 encountered. The implementation uses the LSB of the GOT offset to
130 flag that the relevant GOT relocations for a symbol have been
131 emitted. All of the TLS code that uses the GOT offset needs to take
132 care to mask out this flag bit before using the offset.
134 elfNN_aarch64_final_link_relocate ()
136 Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
138 #include "sysdep.h"
139 #include "bfd.h"
140 #include "libiberty.h"
141 #include "libbfd.h"
142 #include "elf-bfd.h"
143 #include "bfdlink.h"
144 #include "objalloc.h"
145 #include "elf/aarch64.h"
146 #include "elfxx-aarch64.h"
147 #include "cpu-aarch64.h"
149 #define ARCH_SIZE NN
151 #if ARCH_SIZE == 64
152 #define AARCH64_R(NAME) R_AARCH64_ ## NAME
153 #define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
154 #define HOWTO64(...) HOWTO (__VA_ARGS__)
155 #define HOWTO32(...) EMPTY_HOWTO (0)
156 #define LOG_FILE_ALIGN 3
157 #define BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
158 #endif
160 #if ARCH_SIZE == 32
161 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
162 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
163 #define HOWTO64(...) EMPTY_HOWTO (0)
164 #define HOWTO32(...) HOWTO (__VA_ARGS__)
165 #define LOG_FILE_ALIGN 2
166 #define BFD_RELOC_AARCH64_TLSDESC_LD32_LO12 BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
167 #define R_AARCH64_P32_TLSDESC_ADD_LO12 R_AARCH64_P32_TLSDESC_ADD_LO12_NC
168 #endif
170 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
171 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12 \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12 \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12 \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12 \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12 \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12 \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0 \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1 \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2 \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12 \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC \
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12 \
207 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC \
208 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12 \
209 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC \
210 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12 \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC \
212 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
213 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
214 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
215 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
216 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
220 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
222 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
223 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
224 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
225 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
226 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
227 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
228 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
229 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
230 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
231 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
232 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
233 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
234 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
235 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
236 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
237 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
238 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
239 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
240 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
241 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
242 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
243 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
244 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
246 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
247 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
248 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
249 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
250 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
251 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
252 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
253 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
254 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12 \
255 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
256 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
257 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
258 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
260 #define ELIMINATE_COPY_RELOCS 1
262 /* Return size of a relocation entry. HTAB is the bfd's
263 elf_aarch64_link_hash_entry. */
264 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
266 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
267 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
268 #define PLT_ENTRY_SIZE (32)
269 #define PLT_SMALL_ENTRY_SIZE (16)
270 #define PLT_TLSDESC_ENTRY_SIZE (32)
271 /* PLT sizes with BTI insn. */
272 #define PLT_BTI_SMALL_ENTRY_SIZE (24)
273 /* PLT sizes with PAC insn. */
274 #define PLT_PAC_SMALL_ENTRY_SIZE (24)
275 /* PLT sizes with BTI and PAC insn. */
276 #define PLT_BTI_PAC_SMALL_ENTRY_SIZE (24)
278 /* Encoding of the nop instruction. */
279 #define INSN_NOP 0xd503201f
281 #define aarch64_compute_jump_table_size(htab) \
282 (((htab)->root.srelplt == NULL) ? 0 \
283 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
285 /* The first entry in a procedure linkage table looks like this
286 if the distance between the PLTGOT and the PLT is < 4GB use
287 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
288 in x16 and needs to work out PLTGOT[1] by using an address of
289 [x16,#-GOT_ENTRY_SIZE]. */
290 static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
292 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
293 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
294 #if ARCH_SIZE == 64
295 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
296 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
297 #else
298 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
299 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
300 #endif
301 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
302 0x1f, 0x20, 0x03, 0xd5, /* nop */
303 0x1f, 0x20, 0x03, 0xd5, /* nop */
304 0x1f, 0x20, 0x03, 0xd5, /* nop */
307 static const bfd_byte elfNN_aarch64_small_plt0_bti_entry[PLT_ENTRY_SIZE] =
309 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
310 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
311 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
312 #if ARCH_SIZE == 64
313 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
314 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
315 #else
316 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
317 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
318 #endif
319 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
320 0x1f, 0x20, 0x03, 0xd5, /* nop */
321 0x1f, 0x20, 0x03, 0xd5, /* nop */
324 /* Per function entry in a procedure linkage table looks like this
325 if the distance between the PLTGOT and the PLT is < 4GB use
326 these PLT entries. Use BTI versions of the PLTs when enabled. */
327 static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
329 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
330 #if ARCH_SIZE == 64
331 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
332 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
333 #else
334 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
335 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
336 #endif
337 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
340 static const bfd_byte
341 elfNN_aarch64_small_plt_bti_entry[PLT_BTI_SMALL_ENTRY_SIZE] =
343 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
344 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
345 #if ARCH_SIZE == 64
346 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
347 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
348 #else
349 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
350 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
351 #endif
352 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
353 0x1f, 0x20, 0x03, 0xd5, /* nop */
356 static const bfd_byte
357 elfNN_aarch64_small_plt_pac_entry[PLT_PAC_SMALL_ENTRY_SIZE] =
359 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
360 #if ARCH_SIZE == 64
361 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
362 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
363 #else
364 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
365 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
366 #endif
367 0x9f, 0x21, 0x03, 0xd5, /* autia1716 */
368 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
369 0x1f, 0x20, 0x03, 0xd5, /* nop */
372 static const bfd_byte
373 elfNN_aarch64_small_plt_bti_pac_entry[PLT_BTI_PAC_SMALL_ENTRY_SIZE] =
375 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
376 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
377 #if ARCH_SIZE == 64
378 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
379 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
380 #else
381 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
382 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
383 #endif
384 0x9f, 0x21, 0x03, 0xd5, /* autia1716 */
385 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
388 static const bfd_byte
389 elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
391 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
392 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
393 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
394 #if ARCH_SIZE == 64
395 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
396 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
397 #else
398 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
399 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
400 #endif
401 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
402 0x1f, 0x20, 0x03, 0xd5, /* nop */
403 0x1f, 0x20, 0x03, 0xd5, /* nop */
406 static const bfd_byte
407 elfNN_aarch64_tlsdesc_small_plt_bti_entry[PLT_TLSDESC_ENTRY_SIZE] =
409 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
410 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
411 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
412 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
413 #if ARCH_SIZE == 64
414 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
415 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
416 #else
417 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
418 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
419 #endif
420 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
421 0x1f, 0x20, 0x03, 0xd5, /* nop */
424 #define elf_info_to_howto elfNN_aarch64_info_to_howto
425 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
427 #define AARCH64_ELF_ABI_VERSION 0
429 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
430 #define ALL_ONES (~ (bfd_vma) 0)
432 /* Indexed by the bfd interal reloc enumerators.
433 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
434 in reloc.c. */
436 static reloc_howto_type elfNN_aarch64_howto_table[] =
438 EMPTY_HOWTO (0),
440 /* Basic data relocations. */
442 /* Deprecated, but retained for backwards compatibility. */
443 HOWTO64 (R_AARCH64_NULL, /* type */
444 0, /* rightshift */
445 0, /* size */
446 0, /* bitsize */
447 false, /* pc_relative */
448 0, /* bitpos */
449 complain_overflow_dont, /* complain_on_overflow */
450 bfd_elf_generic_reloc, /* special_function */
451 "R_AARCH64_NULL", /* name */
452 false, /* partial_inplace */
453 0, /* src_mask */
454 0, /* dst_mask */
455 false), /* pcrel_offset */
456 HOWTO (R_AARCH64_NONE, /* type */
457 0, /* rightshift */
458 0, /* size */
459 0, /* bitsize */
460 false, /* pc_relative */
461 0, /* bitpos */
462 complain_overflow_dont, /* complain_on_overflow */
463 bfd_elf_generic_reloc, /* special_function */
464 "R_AARCH64_NONE", /* name */
465 false, /* partial_inplace */
466 0, /* src_mask */
467 0, /* dst_mask */
468 false), /* pcrel_offset */
470 /* .xword: (S+A) */
471 HOWTO64 (AARCH64_R (ABS64), /* type */
472 0, /* rightshift */
473 8, /* size */
474 64, /* bitsize */
475 false, /* pc_relative */
476 0, /* bitpos */
477 complain_overflow_unsigned, /* complain_on_overflow */
478 bfd_elf_generic_reloc, /* special_function */
479 AARCH64_R_STR (ABS64), /* name */
480 false, /* partial_inplace */
481 0, /* src_mask */
482 ALL_ONES, /* dst_mask */
483 false), /* pcrel_offset */
485 /* .word: (S+A) */
486 HOWTO (AARCH64_R (ABS32), /* type */
487 0, /* rightshift */
488 4, /* size */
489 32, /* bitsize */
490 false, /* pc_relative */
491 0, /* bitpos */
492 complain_overflow_unsigned, /* complain_on_overflow */
493 bfd_elf_generic_reloc, /* special_function */
494 AARCH64_R_STR (ABS32), /* name */
495 false, /* partial_inplace */
496 0, /* src_mask */
497 0xffffffff, /* dst_mask */
498 false), /* pcrel_offset */
500 /* .half: (S+A) */
501 HOWTO (AARCH64_R (ABS16), /* type */
502 0, /* rightshift */
503 2, /* size */
504 16, /* bitsize */
505 false, /* pc_relative */
506 0, /* bitpos */
507 complain_overflow_unsigned, /* complain_on_overflow */
508 bfd_elf_generic_reloc, /* special_function */
509 AARCH64_R_STR (ABS16), /* name */
510 false, /* partial_inplace */
511 0, /* src_mask */
512 0xffff, /* dst_mask */
513 false), /* pcrel_offset */
515 /* .xword: (S+A-P) */
516 HOWTO64 (AARCH64_R (PREL64), /* type */
517 0, /* rightshift */
518 8, /* size */
519 64, /* bitsize */
520 true, /* pc_relative */
521 0, /* bitpos */
522 complain_overflow_signed, /* complain_on_overflow */
523 bfd_elf_generic_reloc, /* special_function */
524 AARCH64_R_STR (PREL64), /* name */
525 false, /* partial_inplace */
526 0, /* src_mask */
527 ALL_ONES, /* dst_mask */
528 true), /* pcrel_offset */
530 /* .word: (S+A-P) */
531 HOWTO (AARCH64_R (PREL32), /* type */
532 0, /* rightshift */
533 4, /* size */
534 32, /* bitsize */
535 true, /* pc_relative */
536 0, /* bitpos */
537 complain_overflow_signed, /* complain_on_overflow */
538 bfd_elf_generic_reloc, /* special_function */
539 AARCH64_R_STR (PREL32), /* name */
540 false, /* partial_inplace */
541 0, /* src_mask */
542 0xffffffff, /* dst_mask */
543 true), /* pcrel_offset */
545 /* .half: (S+A-P) */
546 HOWTO (AARCH64_R (PREL16), /* type */
547 0, /* rightshift */
548 2, /* size */
549 16, /* bitsize */
550 true, /* pc_relative */
551 0, /* bitpos */
552 complain_overflow_signed, /* complain_on_overflow */
553 bfd_elf_generic_reloc, /* special_function */
554 AARCH64_R_STR (PREL16), /* name */
555 false, /* partial_inplace */
556 0, /* src_mask */
557 0xffff, /* dst_mask */
558 true), /* pcrel_offset */
560 /* Group relocations to create a 16, 32, 48 or 64 bit
561 unsigned data or abs address inline. */
563 /* MOVZ: ((S+A) >> 0) & 0xffff */
564 HOWTO (AARCH64_R (MOVW_UABS_G0), /* type */
565 0, /* rightshift */
566 4, /* size */
567 16, /* bitsize */
568 false, /* pc_relative */
569 0, /* bitpos */
570 complain_overflow_unsigned, /* complain_on_overflow */
571 bfd_elf_generic_reloc, /* special_function */
572 AARCH64_R_STR (MOVW_UABS_G0), /* name */
573 false, /* partial_inplace */
574 0, /* src_mask */
575 0xffff, /* dst_mask */
576 false), /* pcrel_offset */
578 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
579 HOWTO (AARCH64_R (MOVW_UABS_G0_NC), /* type */
580 0, /* rightshift */
581 4, /* size */
582 16, /* bitsize */
583 false, /* pc_relative */
584 0, /* bitpos */
585 complain_overflow_dont, /* complain_on_overflow */
586 bfd_elf_generic_reloc, /* special_function */
587 AARCH64_R_STR (MOVW_UABS_G0_NC), /* name */
588 false, /* partial_inplace */
589 0, /* src_mask */
590 0xffff, /* dst_mask */
591 false), /* pcrel_offset */
593 /* MOVZ: ((S+A) >> 16) & 0xffff */
594 HOWTO (AARCH64_R (MOVW_UABS_G1), /* type */
595 16, /* rightshift */
596 4, /* size */
597 16, /* bitsize */
598 false, /* pc_relative */
599 0, /* bitpos */
600 complain_overflow_unsigned, /* complain_on_overflow */
601 bfd_elf_generic_reloc, /* special_function */
602 AARCH64_R_STR (MOVW_UABS_G1), /* name */
603 false, /* partial_inplace */
604 0, /* src_mask */
605 0xffff, /* dst_mask */
606 false), /* pcrel_offset */
608 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
609 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC), /* type */
610 16, /* rightshift */
611 4, /* size */
612 16, /* bitsize */
613 false, /* pc_relative */
614 0, /* bitpos */
615 complain_overflow_dont, /* complain_on_overflow */
616 bfd_elf_generic_reloc, /* special_function */
617 AARCH64_R_STR (MOVW_UABS_G1_NC), /* name */
618 false, /* partial_inplace */
619 0, /* src_mask */
620 0xffff, /* dst_mask */
621 false), /* pcrel_offset */
623 /* MOVZ: ((S+A) >> 32) & 0xffff */
624 HOWTO64 (AARCH64_R (MOVW_UABS_G2), /* type */
625 32, /* rightshift */
626 4, /* size */
627 16, /* bitsize */
628 false, /* pc_relative */
629 0, /* bitpos */
630 complain_overflow_unsigned, /* complain_on_overflow */
631 bfd_elf_generic_reloc, /* special_function */
632 AARCH64_R_STR (MOVW_UABS_G2), /* name */
633 false, /* partial_inplace */
634 0, /* src_mask */
635 0xffff, /* dst_mask */
636 false), /* pcrel_offset */
638 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
639 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC), /* type */
640 32, /* rightshift */
641 4, /* size */
642 16, /* bitsize */
643 false, /* pc_relative */
644 0, /* bitpos */
645 complain_overflow_dont, /* complain_on_overflow */
646 bfd_elf_generic_reloc, /* special_function */
647 AARCH64_R_STR (MOVW_UABS_G2_NC), /* name */
648 false, /* partial_inplace */
649 0, /* src_mask */
650 0xffff, /* dst_mask */
651 false), /* pcrel_offset */
653 /* MOVZ: ((S+A) >> 48) & 0xffff */
654 HOWTO64 (AARCH64_R (MOVW_UABS_G3), /* type */
655 48, /* rightshift */
656 4, /* size */
657 16, /* bitsize */
658 false, /* pc_relative */
659 0, /* bitpos */
660 complain_overflow_unsigned, /* complain_on_overflow */
661 bfd_elf_generic_reloc, /* special_function */
662 AARCH64_R_STR (MOVW_UABS_G3), /* name */
663 false, /* partial_inplace */
664 0, /* src_mask */
665 0xffff, /* dst_mask */
666 false), /* pcrel_offset */
668 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
669 signed data or abs address inline. Will change instruction
670 to MOVN or MOVZ depending on sign of calculated value. */
672 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
673 HOWTO (AARCH64_R (MOVW_SABS_G0), /* type */
674 0, /* rightshift */
675 4, /* size */
676 17, /* bitsize */
677 false, /* pc_relative */
678 0, /* bitpos */
679 complain_overflow_signed, /* complain_on_overflow */
680 bfd_elf_generic_reloc, /* special_function */
681 AARCH64_R_STR (MOVW_SABS_G0), /* name */
682 false, /* partial_inplace */
683 0, /* src_mask */
684 0xffff, /* dst_mask */
685 false), /* pcrel_offset */
687 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
688 HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
689 16, /* rightshift */
690 4, /* size */
691 17, /* bitsize */
692 false, /* pc_relative */
693 0, /* bitpos */
694 complain_overflow_signed, /* complain_on_overflow */
695 bfd_elf_generic_reloc, /* special_function */
696 AARCH64_R_STR (MOVW_SABS_G1), /* name */
697 false, /* partial_inplace */
698 0, /* src_mask */
699 0xffff, /* dst_mask */
700 false), /* pcrel_offset */
702 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
703 HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
704 32, /* rightshift */
705 4, /* size */
706 17, /* bitsize */
707 false, /* pc_relative */
708 0, /* bitpos */
709 complain_overflow_signed, /* complain_on_overflow */
710 bfd_elf_generic_reloc, /* special_function */
711 AARCH64_R_STR (MOVW_SABS_G2), /* name */
712 false, /* partial_inplace */
713 0, /* src_mask */
714 0xffff, /* dst_mask */
715 false), /* pcrel_offset */
717 /* Group relocations to create a 16, 32, 48 or 64 bit
718 PC relative address inline. */
720 /* MOV[NZ]: ((S+A-P) >> 0) & 0xffff */
721 HOWTO (AARCH64_R (MOVW_PREL_G0), /* type */
722 0, /* rightshift */
723 4, /* size */
724 17, /* bitsize */
725 true, /* pc_relative */
726 0, /* bitpos */
727 complain_overflow_signed, /* complain_on_overflow */
728 bfd_elf_generic_reloc, /* special_function */
729 AARCH64_R_STR (MOVW_PREL_G0), /* name */
730 false, /* partial_inplace */
731 0, /* src_mask */
732 0xffff, /* dst_mask */
733 true), /* pcrel_offset */
735 /* MOVK: ((S+A-P) >> 0) & 0xffff [no overflow check] */
736 HOWTO (AARCH64_R (MOVW_PREL_G0_NC), /* type */
737 0, /* rightshift */
738 4, /* size */
739 16, /* bitsize */
740 true, /* pc_relative */
741 0, /* bitpos */
742 complain_overflow_dont, /* complain_on_overflow */
743 bfd_elf_generic_reloc, /* special_function */
744 AARCH64_R_STR (MOVW_PREL_G0_NC), /* name */
745 false, /* partial_inplace */
746 0, /* src_mask */
747 0xffff, /* dst_mask */
748 true), /* pcrel_offset */
750 /* MOV[NZ]: ((S+A-P) >> 16) & 0xffff */
751 HOWTO (AARCH64_R (MOVW_PREL_G1), /* type */
752 16, /* rightshift */
753 4, /* size */
754 17, /* bitsize */
755 true, /* pc_relative */
756 0, /* bitpos */
757 complain_overflow_signed, /* complain_on_overflow */
758 bfd_elf_generic_reloc, /* special_function */
759 AARCH64_R_STR (MOVW_PREL_G1), /* name */
760 false, /* partial_inplace */
761 0, /* src_mask */
762 0xffff, /* dst_mask */
763 true), /* pcrel_offset */
765 /* MOVK: ((S+A-P) >> 16) & 0xffff [no overflow check] */
766 HOWTO64 (AARCH64_R (MOVW_PREL_G1_NC), /* type */
767 16, /* rightshift */
768 4, /* size */
769 16, /* bitsize */
770 true, /* pc_relative */
771 0, /* bitpos */
772 complain_overflow_dont, /* complain_on_overflow */
773 bfd_elf_generic_reloc, /* special_function */
774 AARCH64_R_STR (MOVW_PREL_G1_NC), /* name */
775 false, /* partial_inplace */
776 0, /* src_mask */
777 0xffff, /* dst_mask */
778 true), /* pcrel_offset */
780 /* MOV[NZ]: ((S+A-P) >> 32) & 0xffff */
781 HOWTO64 (AARCH64_R (MOVW_PREL_G2), /* type */
782 32, /* rightshift */
783 4, /* size */
784 17, /* bitsize */
785 true, /* pc_relative */
786 0, /* bitpos */
787 complain_overflow_signed, /* complain_on_overflow */
788 bfd_elf_generic_reloc, /* special_function */
789 AARCH64_R_STR (MOVW_PREL_G2), /* name */
790 false, /* partial_inplace */
791 0, /* src_mask */
792 0xffff, /* dst_mask */
793 true), /* pcrel_offset */
795 /* MOVK: ((S+A-P) >> 32) & 0xffff [no overflow check] */
796 HOWTO64 (AARCH64_R (MOVW_PREL_G2_NC), /* type */
797 32, /* rightshift */
798 4, /* size */
799 16, /* bitsize */
800 true, /* pc_relative */
801 0, /* bitpos */
802 complain_overflow_dont, /* complain_on_overflow */
803 bfd_elf_generic_reloc, /* special_function */
804 AARCH64_R_STR (MOVW_PREL_G2_NC), /* name */
805 false, /* partial_inplace */
806 0, /* src_mask */
807 0xffff, /* dst_mask */
808 true), /* pcrel_offset */
810 /* MOV[NZ]: ((S+A-P) >> 48) & 0xffff */
811 HOWTO64 (AARCH64_R (MOVW_PREL_G3), /* type */
812 48, /* rightshift */
813 4, /* size */
814 16, /* bitsize */
815 true, /* pc_relative */
816 0, /* bitpos */
817 complain_overflow_dont, /* complain_on_overflow */
818 bfd_elf_generic_reloc, /* special_function */
819 AARCH64_R_STR (MOVW_PREL_G3), /* name */
820 false, /* partial_inplace */
821 0, /* src_mask */
822 0xffff, /* dst_mask */
823 true), /* pcrel_offset */
825 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
826 addresses: PG(x) is (x & ~0xfff). */
828 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
829 HOWTO (AARCH64_R (LD_PREL_LO19), /* type */
830 2, /* rightshift */
831 4, /* size */
832 19, /* bitsize */
833 true, /* pc_relative */
834 0, /* bitpos */
835 complain_overflow_signed, /* complain_on_overflow */
836 bfd_elf_generic_reloc, /* special_function */
837 AARCH64_R_STR (LD_PREL_LO19), /* name */
838 false, /* partial_inplace */
839 0, /* src_mask */
840 0x7ffff, /* dst_mask */
841 true), /* pcrel_offset */
843 /* ADR: (S+A-P) & 0x1fffff */
844 HOWTO (AARCH64_R (ADR_PREL_LO21), /* type */
845 0, /* rightshift */
846 4, /* size */
847 21, /* bitsize */
848 true, /* pc_relative */
849 0, /* bitpos */
850 complain_overflow_signed, /* complain_on_overflow */
851 bfd_elf_generic_reloc, /* special_function */
852 AARCH64_R_STR (ADR_PREL_LO21), /* name */
853 false, /* partial_inplace */
854 0, /* src_mask */
855 0x1fffff, /* dst_mask */
856 true), /* pcrel_offset */
858 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
859 HOWTO (AARCH64_R (ADR_PREL_PG_HI21), /* type */
860 12, /* rightshift */
861 4, /* size */
862 21, /* bitsize */
863 true, /* pc_relative */
864 0, /* bitpos */
865 complain_overflow_signed, /* complain_on_overflow */
866 bfd_elf_generic_reloc, /* special_function */
867 AARCH64_R_STR (ADR_PREL_PG_HI21), /* name */
868 false, /* partial_inplace */
869 0, /* src_mask */
870 0x1fffff, /* dst_mask */
871 true), /* pcrel_offset */
873 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
874 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC), /* type */
875 12, /* rightshift */
876 4, /* size */
877 21, /* bitsize */
878 true, /* pc_relative */
879 0, /* bitpos */
880 complain_overflow_dont, /* complain_on_overflow */
881 bfd_elf_generic_reloc, /* special_function */
882 AARCH64_R_STR (ADR_PREL_PG_HI21_NC), /* name */
883 false, /* partial_inplace */
884 0, /* src_mask */
885 0x1fffff, /* dst_mask */
886 true), /* pcrel_offset */
888 /* ADD: (S+A) & 0xfff [no overflow check] */
889 HOWTO (AARCH64_R (ADD_ABS_LO12_NC), /* type */
890 0, /* rightshift */
891 4, /* size */
892 12, /* bitsize */
893 false, /* pc_relative */
894 10, /* bitpos */
895 complain_overflow_dont, /* complain_on_overflow */
896 bfd_elf_generic_reloc, /* special_function */
897 AARCH64_R_STR (ADD_ABS_LO12_NC), /* name */
898 false, /* partial_inplace */
899 0, /* src_mask */
900 0x3ffc00, /* dst_mask */
901 false), /* pcrel_offset */
903 /* LD/ST8: (S+A) & 0xfff */
904 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC), /* type */
905 0, /* rightshift */
906 4, /* size */
907 12, /* bitsize */
908 false, /* pc_relative */
909 0, /* bitpos */
910 complain_overflow_dont, /* complain_on_overflow */
911 bfd_elf_generic_reloc, /* special_function */
912 AARCH64_R_STR (LDST8_ABS_LO12_NC), /* name */
913 false, /* partial_inplace */
914 0, /* src_mask */
915 0xfff, /* dst_mask */
916 false), /* pcrel_offset */
918 /* Relocations for control-flow instructions. */
920 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
921 HOWTO (AARCH64_R (TSTBR14), /* type */
922 2, /* rightshift */
923 4, /* size */
924 14, /* bitsize */
925 true, /* pc_relative */
926 0, /* bitpos */
927 complain_overflow_signed, /* complain_on_overflow */
928 bfd_elf_generic_reloc, /* special_function */
929 AARCH64_R_STR (TSTBR14), /* name */
930 false, /* partial_inplace */
931 0, /* src_mask */
932 0x3fff, /* dst_mask */
933 true), /* pcrel_offset */
935 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
936 HOWTO (AARCH64_R (CONDBR19), /* type */
937 2, /* rightshift */
938 4, /* size */
939 19, /* bitsize */
940 true, /* pc_relative */
941 0, /* bitpos */
942 complain_overflow_signed, /* complain_on_overflow */
943 bfd_elf_generic_reloc, /* special_function */
944 AARCH64_R_STR (CONDBR19), /* name */
945 false, /* partial_inplace */
946 0, /* src_mask */
947 0x7ffff, /* dst_mask */
948 true), /* pcrel_offset */
950 /* B: ((S+A-P) >> 2) & 0x3ffffff */
951 HOWTO (AARCH64_R (JUMP26), /* type */
952 2, /* rightshift */
953 4, /* size */
954 26, /* bitsize */
955 true, /* pc_relative */
956 0, /* bitpos */
957 complain_overflow_signed, /* complain_on_overflow */
958 bfd_elf_generic_reloc, /* special_function */
959 AARCH64_R_STR (JUMP26), /* name */
960 false, /* partial_inplace */
961 0, /* src_mask */
962 0x3ffffff, /* dst_mask */
963 true), /* pcrel_offset */
965 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
966 HOWTO (AARCH64_R (CALL26), /* type */
967 2, /* rightshift */
968 4, /* size */
969 26, /* bitsize */
970 true, /* pc_relative */
971 0, /* bitpos */
972 complain_overflow_signed, /* complain_on_overflow */
973 bfd_elf_generic_reloc, /* special_function */
974 AARCH64_R_STR (CALL26), /* name */
975 false, /* partial_inplace */
976 0, /* src_mask */
977 0x3ffffff, /* dst_mask */
978 true), /* pcrel_offset */
980 /* LD/ST16: (S+A) & 0xffe */
981 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */
982 1, /* rightshift */
983 4, /* size */
984 12, /* bitsize */
985 false, /* pc_relative */
986 0, /* bitpos */
987 complain_overflow_dont, /* complain_on_overflow */
988 bfd_elf_generic_reloc, /* special_function */
989 AARCH64_R_STR (LDST16_ABS_LO12_NC), /* name */
990 false, /* partial_inplace */
991 0, /* src_mask */
992 0xffe, /* dst_mask */
993 false), /* pcrel_offset */
995 /* LD/ST32: (S+A) & 0xffc */
996 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC), /* type */
997 2, /* rightshift */
998 4, /* size */
999 12, /* bitsize */
1000 false, /* pc_relative */
1001 0, /* bitpos */
1002 complain_overflow_dont, /* complain_on_overflow */
1003 bfd_elf_generic_reloc, /* special_function */
1004 AARCH64_R_STR (LDST32_ABS_LO12_NC), /* name */
1005 false, /* partial_inplace */
1006 0, /* src_mask */
1007 0xffc, /* dst_mask */
1008 false), /* pcrel_offset */
1010 /* LD/ST64: (S+A) & 0xff8 */
1011 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC), /* type */
1012 3, /* rightshift */
1013 4, /* size */
1014 12, /* bitsize */
1015 false, /* pc_relative */
1016 0, /* bitpos */
1017 complain_overflow_dont, /* complain_on_overflow */
1018 bfd_elf_generic_reloc, /* special_function */
1019 AARCH64_R_STR (LDST64_ABS_LO12_NC), /* name */
1020 false, /* partial_inplace */
1021 0, /* src_mask */
1022 0xff8, /* dst_mask */
1023 false), /* pcrel_offset */
1025 /* LD/ST128: (S+A) & 0xff0 */
1026 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC), /* type */
1027 4, /* rightshift */
1028 4, /* size */
1029 12, /* bitsize */
1030 false, /* pc_relative */
1031 0, /* bitpos */
1032 complain_overflow_dont, /* complain_on_overflow */
1033 bfd_elf_generic_reloc, /* special_function */
1034 AARCH64_R_STR (LDST128_ABS_LO12_NC), /* name */
1035 false, /* partial_inplace */
1036 0, /* src_mask */
1037 0xff0, /* dst_mask */
1038 false), /* pcrel_offset */
1040 /* Set a load-literal immediate field to bits
1041 0x1FFFFC of G(S)-P */
1042 HOWTO (AARCH64_R (GOT_LD_PREL19), /* type */
1043 2, /* rightshift */
1044 4, /* size */
1045 19, /* bitsize */
1046 true, /* pc_relative */
1047 0, /* bitpos */
1048 complain_overflow_signed, /* complain_on_overflow */
1049 bfd_elf_generic_reloc, /* special_function */
1050 AARCH64_R_STR (GOT_LD_PREL19), /* name */
1051 false, /* partial_inplace */
1052 0, /* src_mask */
1053 0xffffe0, /* dst_mask */
1054 true), /* pcrel_offset */
1056 /* Get to the page for the GOT entry for the symbol
1057 (G(S) - P) using an ADRP instruction. */
1058 HOWTO (AARCH64_R (ADR_GOT_PAGE), /* type */
1059 12, /* rightshift */
1060 4, /* size */
1061 21, /* bitsize */
1062 true, /* pc_relative */
1063 0, /* bitpos */
1064 complain_overflow_dont, /* complain_on_overflow */
1065 bfd_elf_generic_reloc, /* special_function */
1066 AARCH64_R_STR (ADR_GOT_PAGE), /* name */
1067 false, /* partial_inplace */
1068 0, /* src_mask */
1069 0x1fffff, /* dst_mask */
1070 true), /* pcrel_offset */
1072 /* LD64: GOT offset G(S) & 0xff8 */
1073 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC), /* type */
1074 3, /* rightshift */
1075 4, /* size */
1076 12, /* bitsize */
1077 false, /* pc_relative */
1078 0, /* bitpos */
1079 complain_overflow_dont, /* complain_on_overflow */
1080 bfd_elf_generic_reloc, /* special_function */
1081 AARCH64_R_STR (LD64_GOT_LO12_NC), /* name */
1082 false, /* partial_inplace */
1083 0, /* src_mask */
1084 0xff8, /* dst_mask */
1085 false), /* pcrel_offset */
1087 /* LD32: GOT offset G(S) & 0xffc */
1088 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC), /* type */
1089 2, /* rightshift */
1090 4, /* size */
1091 12, /* bitsize */
1092 false, /* pc_relative */
1093 0, /* bitpos */
1094 complain_overflow_dont, /* complain_on_overflow */
1095 bfd_elf_generic_reloc, /* special_function */
1096 AARCH64_R_STR (LD32_GOT_LO12_NC), /* name */
1097 false, /* partial_inplace */
1098 0, /* src_mask */
1099 0xffc, /* dst_mask */
1100 false), /* pcrel_offset */
1102 /* Lower 16 bits of GOT offset for the symbol. */
1103 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G0_NC), /* type */
1104 0, /* rightshift */
1105 4, /* size */
1106 16, /* bitsize */
1107 false, /* pc_relative */
1108 0, /* bitpos */
1109 complain_overflow_dont, /* complain_on_overflow */
1110 bfd_elf_generic_reloc, /* special_function */
1111 AARCH64_R_STR (MOVW_GOTOFF_G0_NC), /* name */
1112 false, /* partial_inplace */
1113 0, /* src_mask */
1114 0xffff, /* dst_mask */
1115 false), /* pcrel_offset */
1117 /* Higher 16 bits of GOT offset for the symbol. */
1118 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G1), /* type */
1119 16, /* rightshift */
1120 4, /* size */
1121 16, /* bitsize */
1122 false, /* pc_relative */
1123 0, /* bitpos */
1124 complain_overflow_unsigned, /* complain_on_overflow */
1125 bfd_elf_generic_reloc, /* special_function */
1126 AARCH64_R_STR (MOVW_GOTOFF_G1), /* name */
1127 false, /* partial_inplace */
1128 0, /* src_mask */
1129 0xffff, /* dst_mask */
1130 false), /* pcrel_offset */
1132 /* LD64: GOT offset for the symbol. */
1133 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15), /* type */
1134 3, /* rightshift */
1135 4, /* size */
1136 12, /* bitsize */
1137 false, /* pc_relative */
1138 0, /* bitpos */
1139 complain_overflow_unsigned, /* complain_on_overflow */
1140 bfd_elf_generic_reloc, /* special_function */
1141 AARCH64_R_STR (LD64_GOTOFF_LO15), /* name */
1142 false, /* partial_inplace */
1143 0, /* src_mask */
1144 0x7ff8, /* dst_mask */
1145 false), /* pcrel_offset */
1147 /* LD32: GOT offset to the page address of GOT table.
1148 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
1149 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14), /* type */
1150 2, /* rightshift */
1151 4, /* size */
1152 12, /* bitsize */
1153 false, /* pc_relative */
1154 0, /* bitpos */
1155 complain_overflow_unsigned, /* complain_on_overflow */
1156 bfd_elf_generic_reloc, /* special_function */
1157 AARCH64_R_STR (LD32_GOTPAGE_LO14), /* name */
1158 false, /* partial_inplace */
1159 0, /* src_mask */
1160 0x5ffc, /* dst_mask */
1161 false), /* pcrel_offset */
1163 /* LD64: GOT offset to the page address of GOT table.
1164 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
1165 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15), /* type */
1166 3, /* rightshift */
1167 4, /* size */
1168 12, /* bitsize */
1169 false, /* pc_relative */
1170 0, /* bitpos */
1171 complain_overflow_unsigned, /* complain_on_overflow */
1172 bfd_elf_generic_reloc, /* special_function */
1173 AARCH64_R_STR (LD64_GOTPAGE_LO15), /* name */
1174 false, /* partial_inplace */
1175 0, /* src_mask */
1176 0x7ff8, /* dst_mask */
1177 false), /* pcrel_offset */
1179 /* Get to the page for the GOT entry for the symbol
1180 (G(S) - P) using an ADRP instruction. */
1181 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21), /* type */
1182 12, /* rightshift */
1183 4, /* size */
1184 21, /* bitsize */
1185 true, /* pc_relative */
1186 0, /* bitpos */
1187 complain_overflow_dont, /* complain_on_overflow */
1188 bfd_elf_generic_reloc, /* special_function */
1189 AARCH64_R_STR (TLSGD_ADR_PAGE21), /* name */
1190 false, /* partial_inplace */
1191 0, /* src_mask */
1192 0x1fffff, /* dst_mask */
1193 true), /* pcrel_offset */
1195 HOWTO (AARCH64_R (TLSGD_ADR_PREL21), /* type */
1196 0, /* rightshift */
1197 4, /* size */
1198 21, /* bitsize */
1199 true, /* pc_relative */
1200 0, /* bitpos */
1201 complain_overflow_dont, /* complain_on_overflow */
1202 bfd_elf_generic_reloc, /* special_function */
1203 AARCH64_R_STR (TLSGD_ADR_PREL21), /* name */
1204 false, /* partial_inplace */
1205 0, /* src_mask */
1206 0x1fffff, /* dst_mask */
1207 true), /* pcrel_offset */
1209 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1210 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC), /* type */
1211 0, /* rightshift */
1212 4, /* size */
1213 12, /* bitsize */
1214 false, /* pc_relative */
1215 0, /* bitpos */
1216 complain_overflow_dont, /* complain_on_overflow */
1217 bfd_elf_generic_reloc, /* special_function */
1218 AARCH64_R_STR (TLSGD_ADD_LO12_NC), /* name */
1219 false, /* partial_inplace */
1220 0, /* src_mask */
1221 0xfff, /* dst_mask */
1222 false), /* pcrel_offset */
1224 /* Lower 16 bits of GOT offset to tls_index. */
1225 HOWTO64 (AARCH64_R (TLSGD_MOVW_G0_NC), /* type */
1226 0, /* rightshift */
1227 4, /* size */
1228 16, /* bitsize */
1229 false, /* pc_relative */
1230 0, /* bitpos */
1231 complain_overflow_dont, /* complain_on_overflow */
1232 bfd_elf_generic_reloc, /* special_function */
1233 AARCH64_R_STR (TLSGD_MOVW_G0_NC), /* name */
1234 false, /* partial_inplace */
1235 0, /* src_mask */
1236 0xffff, /* dst_mask */
1237 false), /* pcrel_offset */
1239 /* Higher 16 bits of GOT offset to tls_index. */
1240 HOWTO64 (AARCH64_R (TLSGD_MOVW_G1), /* type */
1241 16, /* rightshift */
1242 4, /* size */
1243 16, /* bitsize */
1244 false, /* pc_relative */
1245 0, /* bitpos */
1246 complain_overflow_unsigned, /* complain_on_overflow */
1247 bfd_elf_generic_reloc, /* special_function */
1248 AARCH64_R_STR (TLSGD_MOVW_G1), /* name */
1249 false, /* partial_inplace */
1250 0, /* src_mask */
1251 0xffff, /* dst_mask */
1252 false), /* pcrel_offset */
1254 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21), /* type */
1255 12, /* rightshift */
1256 4, /* size */
1257 21, /* bitsize */
1258 false, /* pc_relative */
1259 0, /* bitpos */
1260 complain_overflow_dont, /* complain_on_overflow */
1261 bfd_elf_generic_reloc, /* special_function */
1262 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21), /* name */
1263 false, /* partial_inplace */
1264 0, /* src_mask */
1265 0x1fffff, /* dst_mask */
1266 false), /* pcrel_offset */
1268 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC), /* type */
1269 3, /* rightshift */
1270 4, /* size */
1271 12, /* bitsize */
1272 false, /* pc_relative */
1273 0, /* bitpos */
1274 complain_overflow_dont, /* complain_on_overflow */
1275 bfd_elf_generic_reloc, /* special_function */
1276 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC), /* name */
1277 false, /* partial_inplace */
1278 0, /* src_mask */
1279 0xff8, /* dst_mask */
1280 false), /* pcrel_offset */
1282 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC), /* type */
1283 2, /* rightshift */
1284 4, /* size */
1285 12, /* bitsize */
1286 false, /* pc_relative */
1287 0, /* bitpos */
1288 complain_overflow_dont, /* complain_on_overflow */
1289 bfd_elf_generic_reloc, /* special_function */
1290 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC), /* name */
1291 false, /* partial_inplace */
1292 0, /* src_mask */
1293 0xffc, /* dst_mask */
1294 false), /* pcrel_offset */
1296 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19), /* type */
1297 2, /* rightshift */
1298 4, /* size */
1299 19, /* bitsize */
1300 false, /* pc_relative */
1301 0, /* bitpos */
1302 complain_overflow_dont, /* complain_on_overflow */
1303 bfd_elf_generic_reloc, /* special_function */
1304 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19), /* name */
1305 false, /* partial_inplace */
1306 0, /* src_mask */
1307 0x1ffffc, /* dst_mask */
1308 false), /* pcrel_offset */
1310 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC), /* type */
1311 0, /* rightshift */
1312 4, /* size */
1313 16, /* bitsize */
1314 false, /* pc_relative */
1315 0, /* bitpos */
1316 complain_overflow_dont, /* complain_on_overflow */
1317 bfd_elf_generic_reloc, /* special_function */
1318 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC), /* name */
1319 false, /* partial_inplace */
1320 0, /* src_mask */
1321 0xffff, /* dst_mask */
1322 false), /* pcrel_offset */
1324 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
1325 16, /* rightshift */
1326 4, /* size */
1327 16, /* bitsize */
1328 false, /* pc_relative */
1329 0, /* bitpos */
1330 complain_overflow_unsigned, /* complain_on_overflow */
1331 bfd_elf_generic_reloc, /* special_function */
1332 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1), /* name */
1333 false, /* partial_inplace */
1334 0, /* src_mask */
1335 0xffff, /* dst_mask */
1336 false), /* pcrel_offset */
1338 /* ADD: bit[23:12] of byte offset to module TLS base address. */
1339 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12), /* type */
1340 12, /* rightshift */
1341 4, /* size */
1342 12, /* bitsize */
1343 false, /* pc_relative */
1344 0, /* bitpos */
1345 complain_overflow_unsigned, /* complain_on_overflow */
1346 bfd_elf_generic_reloc, /* special_function */
1347 AARCH64_R_STR (TLSLD_ADD_DTPREL_HI12), /* name */
1348 false, /* partial_inplace */
1349 0, /* src_mask */
1350 0xfff, /* dst_mask */
1351 false), /* pcrel_offset */
1353 /* Unsigned 12 bit byte offset to module TLS base address. */
1354 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12), /* type */
1355 0, /* rightshift */
1356 4, /* size */
1357 12, /* bitsize */
1358 false, /* pc_relative */
1359 0, /* bitpos */
1360 complain_overflow_unsigned, /* complain_on_overflow */
1361 bfd_elf_generic_reloc, /* special_function */
1362 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12), /* name */
1363 false, /* partial_inplace */
1364 0, /* src_mask */
1365 0xfff, /* dst_mask */
1366 false), /* pcrel_offset */
1368 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1369 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC), /* type */
1370 0, /* rightshift */
1371 4, /* size */
1372 12, /* bitsize */
1373 false, /* pc_relative */
1374 0, /* bitpos */
1375 complain_overflow_dont, /* complain_on_overflow */
1376 bfd_elf_generic_reloc, /* special_function */
1377 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC), /* name */
1378 false, /* partial_inplace */
1379 0, /* src_mask */
1380 0xfff, /* dst_mask */
1381 false), /* pcrel_offset */
1383 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1384 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC), /* type */
1385 0, /* rightshift */
1386 4, /* size */
1387 12, /* bitsize */
1388 false, /* pc_relative */
1389 0, /* bitpos */
1390 complain_overflow_dont, /* complain_on_overflow */
1391 bfd_elf_generic_reloc, /* special_function */
1392 AARCH64_R_STR (TLSLD_ADD_LO12_NC), /* name */
1393 false, /* partial_inplace */
1394 0, /* src_mask */
1395 0xfff, /* dst_mask */
1396 false), /* pcrel_offset */
1398 /* Get to the page for the GOT entry for the symbol
1399 (G(S) - P) using an ADRP instruction. */
1400 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21), /* type */
1401 12, /* rightshift */
1402 4, /* size */
1403 21, /* bitsize */
1404 true, /* pc_relative */
1405 0, /* bitpos */
1406 complain_overflow_signed, /* complain_on_overflow */
1407 bfd_elf_generic_reloc, /* special_function */
1408 AARCH64_R_STR (TLSLD_ADR_PAGE21), /* name */
1409 false, /* partial_inplace */
1410 0, /* src_mask */
1411 0x1fffff, /* dst_mask */
1412 true), /* pcrel_offset */
1414 HOWTO (AARCH64_R (TLSLD_ADR_PREL21), /* type */
1415 0, /* rightshift */
1416 4, /* size */
1417 21, /* bitsize */
1418 true, /* pc_relative */
1419 0, /* bitpos */
1420 complain_overflow_signed, /* complain_on_overflow */
1421 bfd_elf_generic_reloc, /* special_function */
1422 AARCH64_R_STR (TLSLD_ADR_PREL21), /* name */
1423 false, /* partial_inplace */
1424 0, /* src_mask */
1425 0x1fffff, /* dst_mask */
1426 true), /* pcrel_offset */
1428 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1429 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12), /* type */
1430 1, /* rightshift */
1431 4, /* size */
1432 11, /* bitsize */
1433 false, /* pc_relative */
1434 10, /* bitpos */
1435 complain_overflow_unsigned, /* complain_on_overflow */
1436 bfd_elf_generic_reloc, /* special_function */
1437 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12), /* name */
1438 false, /* partial_inplace */
1439 0, /* src_mask */
1440 0x1ffc00, /* dst_mask */
1441 false), /* pcrel_offset */
1443 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, but no overflow check. */
1444 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12_NC), /* type */
1445 1, /* rightshift */
1446 4, /* size */
1447 11, /* bitsize */
1448 false, /* pc_relative */
1449 10, /* bitpos */
1450 complain_overflow_dont, /* complain_on_overflow */
1451 bfd_elf_generic_reloc, /* special_function */
1452 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12_NC), /* name */
1453 false, /* partial_inplace */
1454 0, /* src_mask */
1455 0x1ffc00, /* dst_mask */
1456 false), /* pcrel_offset */
1458 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1459 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12), /* type */
1460 2, /* rightshift */
1461 4, /* size */
1462 10, /* bitsize */
1463 false, /* pc_relative */
1464 10, /* bitpos */
1465 complain_overflow_unsigned, /* complain_on_overflow */
1466 bfd_elf_generic_reloc, /* special_function */
1467 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12), /* name */
1468 false, /* partial_inplace */
1469 0, /* src_mask */
1470 0x3ffc00, /* dst_mask */
1471 false), /* pcrel_offset */
1473 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no overflow check. */
1474 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12_NC), /* type */
1475 2, /* rightshift */
1476 4, /* size */
1477 10, /* bitsize */
1478 false, /* pc_relative */
1479 10, /* bitpos */
1480 complain_overflow_dont, /* complain_on_overflow */
1481 bfd_elf_generic_reloc, /* special_function */
1482 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12_NC), /* name */
1483 false, /* partial_inplace */
1484 0, /* src_mask */
1485 0xffc00, /* dst_mask */
1486 false), /* pcrel_offset */
1488 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1489 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12), /* type */
1490 3, /* rightshift */
1491 4, /* size */
1492 9, /* bitsize */
1493 false, /* pc_relative */
1494 10, /* bitpos */
1495 complain_overflow_unsigned, /* complain_on_overflow */
1496 bfd_elf_generic_reloc, /* special_function */
1497 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12), /* name */
1498 false, /* partial_inplace */
1499 0, /* src_mask */
1500 0x3ffc00, /* dst_mask */
1501 false), /* pcrel_offset */
1503 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, but no overflow check. */
1504 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12_NC), /* type */
1505 3, /* rightshift */
1506 4, /* size */
1507 9, /* bitsize */
1508 false, /* pc_relative */
1509 10, /* bitpos */
1510 complain_overflow_dont, /* complain_on_overflow */
1511 bfd_elf_generic_reloc, /* special_function */
1512 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12_NC), /* name */
1513 false, /* partial_inplace */
1514 0, /* src_mask */
1515 0x7fc00, /* dst_mask */
1516 false), /* pcrel_offset */
1518 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1519 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12), /* type */
1520 0, /* rightshift */
1521 4, /* size */
1522 12, /* bitsize */
1523 false, /* pc_relative */
1524 10, /* bitpos */
1525 complain_overflow_unsigned, /* complain_on_overflow */
1526 bfd_elf_generic_reloc, /* special_function */
1527 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12), /* name */
1528 false, /* partial_inplace */
1529 0, /* src_mask */
1530 0x3ffc00, /* dst_mask */
1531 false), /* pcrel_offset */
1533 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, but no overflow check. */
1534 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12_NC), /* type */
1535 0, /* rightshift */
1536 4, /* size */
1537 12, /* bitsize */
1538 false, /* pc_relative */
1539 10, /* bitpos */
1540 complain_overflow_dont, /* complain_on_overflow */
1541 bfd_elf_generic_reloc, /* special_function */
1542 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12_NC), /* name */
1543 false, /* partial_inplace */
1544 0, /* src_mask */
1545 0x3ffc00, /* dst_mask */
1546 false), /* pcrel_offset */
1548 /* MOVZ: bit[15:0] of byte offset to module TLS base address. */
1549 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0), /* type */
1550 0, /* rightshift */
1551 4, /* size */
1552 16, /* bitsize */
1553 false, /* pc_relative */
1554 0, /* bitpos */
1555 complain_overflow_unsigned, /* complain_on_overflow */
1556 bfd_elf_generic_reloc, /* special_function */
1557 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0), /* name */
1558 false, /* partial_inplace */
1559 0, /* src_mask */
1560 0xffff, /* dst_mask */
1561 false), /* pcrel_offset */
1563 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */
1564 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0_NC), /* type */
1565 0, /* rightshift */
1566 4, /* size */
1567 16, /* bitsize */
1568 false, /* pc_relative */
1569 0, /* bitpos */
1570 complain_overflow_dont, /* complain_on_overflow */
1571 bfd_elf_generic_reloc, /* special_function */
1572 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0_NC), /* name */
1573 false, /* partial_inplace */
1574 0, /* src_mask */
1575 0xffff, /* dst_mask */
1576 false), /* pcrel_offset */
1578 /* MOVZ: bit[31:16] of byte offset to module TLS base address. */
1579 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G1), /* type */
1580 16, /* rightshift */
1581 4, /* size */
1582 16, /* bitsize */
1583 false, /* pc_relative */
1584 0, /* bitpos */
1585 complain_overflow_unsigned, /* complain_on_overflow */
1586 bfd_elf_generic_reloc, /* special_function */
1587 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1), /* name */
1588 false, /* partial_inplace */
1589 0, /* src_mask */
1590 0xffff, /* dst_mask */
1591 false), /* pcrel_offset */
1593 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */
1594 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G1_NC), /* type */
1595 16, /* rightshift */
1596 4, /* size */
1597 16, /* bitsize */
1598 false, /* pc_relative */
1599 0, /* bitpos */
1600 complain_overflow_dont, /* complain_on_overflow */
1601 bfd_elf_generic_reloc, /* special_function */
1602 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1_NC), /* name */
1603 false, /* partial_inplace */
1604 0, /* src_mask */
1605 0xffff, /* dst_mask */
1606 false), /* pcrel_offset */
1608 /* MOVZ: bit[47:32] of byte offset to module TLS base address. */
1609 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G2), /* type */
1610 32, /* rightshift */
1611 4, /* size */
1612 16, /* bitsize */
1613 false, /* pc_relative */
1614 0, /* bitpos */
1615 complain_overflow_unsigned, /* complain_on_overflow */
1616 bfd_elf_generic_reloc, /* special_function */
1617 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G2), /* name */
1618 false, /* partial_inplace */
1619 0, /* src_mask */
1620 0xffff, /* dst_mask */
1621 false), /* pcrel_offset */
1623 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
1624 32, /* rightshift */
1625 4, /* size */
1626 16, /* bitsize */
1627 false, /* pc_relative */
1628 0, /* bitpos */
1629 complain_overflow_unsigned, /* complain_on_overflow */
1630 bfd_elf_generic_reloc, /* special_function */
1631 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2), /* name */
1632 false, /* partial_inplace */
1633 0, /* src_mask */
1634 0xffff, /* dst_mask */
1635 false), /* pcrel_offset */
1637 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1), /* type */
1638 16, /* rightshift */
1639 4, /* size */
1640 16, /* bitsize */
1641 false, /* pc_relative */
1642 0, /* bitpos */
1643 complain_overflow_dont, /* complain_on_overflow */
1644 bfd_elf_generic_reloc, /* special_function */
1645 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1), /* name */
1646 false, /* partial_inplace */
1647 0, /* src_mask */
1648 0xffff, /* dst_mask */
1649 false), /* pcrel_offset */
1651 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC), /* type */
1652 16, /* rightshift */
1653 4, /* size */
1654 16, /* bitsize */
1655 false, /* pc_relative */
1656 0, /* bitpos */
1657 complain_overflow_dont, /* complain_on_overflow */
1658 bfd_elf_generic_reloc, /* special_function */
1659 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC), /* name */
1660 false, /* partial_inplace */
1661 0, /* src_mask */
1662 0xffff, /* dst_mask */
1663 false), /* pcrel_offset */
1665 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0), /* type */
1666 0, /* rightshift */
1667 4, /* size */
1668 16, /* bitsize */
1669 false, /* pc_relative */
1670 0, /* bitpos */
1671 complain_overflow_dont, /* complain_on_overflow */
1672 bfd_elf_generic_reloc, /* special_function */
1673 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0), /* name */
1674 false, /* partial_inplace */
1675 0, /* src_mask */
1676 0xffff, /* dst_mask */
1677 false), /* pcrel_offset */
1679 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC), /* type */
1680 0, /* rightshift */
1681 4, /* size */
1682 16, /* bitsize */
1683 false, /* pc_relative */
1684 0, /* bitpos */
1685 complain_overflow_dont, /* complain_on_overflow */
1686 bfd_elf_generic_reloc, /* special_function */
1687 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC), /* name */
1688 false, /* partial_inplace */
1689 0, /* src_mask */
1690 0xffff, /* dst_mask */
1691 false), /* pcrel_offset */
1693 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12), /* type */
1694 12, /* rightshift */
1695 4, /* size */
1696 12, /* bitsize */
1697 false, /* pc_relative */
1698 0, /* bitpos */
1699 complain_overflow_unsigned, /* complain_on_overflow */
1700 bfd_elf_generic_reloc, /* special_function */
1701 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12), /* name */
1702 false, /* partial_inplace */
1703 0, /* src_mask */
1704 0xfff, /* dst_mask */
1705 false), /* pcrel_offset */
1707 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12), /* type */
1708 0, /* rightshift */
1709 4, /* size */
1710 12, /* bitsize */
1711 false, /* pc_relative */
1712 0, /* bitpos */
1713 complain_overflow_unsigned, /* complain_on_overflow */
1714 bfd_elf_generic_reloc, /* special_function */
1715 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12), /* name */
1716 false, /* partial_inplace */
1717 0, /* src_mask */
1718 0xfff, /* dst_mask */
1719 false), /* pcrel_offset */
1721 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC), /* type */
1722 0, /* rightshift */
1723 4, /* size */
1724 12, /* bitsize */
1725 false, /* pc_relative */
1726 0, /* bitpos */
1727 complain_overflow_dont, /* complain_on_overflow */
1728 bfd_elf_generic_reloc, /* special_function */
1729 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC), /* name */
1730 false, /* partial_inplace */
1731 0, /* src_mask */
1732 0xfff, /* dst_mask */
1733 false), /* pcrel_offset */
1735 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1736 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12), /* type */
1737 1, /* rightshift */
1738 4, /* size */
1739 11, /* bitsize */
1740 false, /* pc_relative */
1741 10, /* bitpos */
1742 complain_overflow_unsigned, /* complain_on_overflow */
1743 bfd_elf_generic_reloc, /* special_function */
1744 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12), /* name */
1745 false, /* partial_inplace */
1746 0, /* src_mask */
1747 0x1ffc00, /* dst_mask */
1748 false), /* pcrel_offset */
1750 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check. */
1751 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12_NC), /* type */
1752 1, /* rightshift */
1753 4, /* size */
1754 11, /* bitsize */
1755 false, /* pc_relative */
1756 10, /* bitpos */
1757 complain_overflow_dont, /* complain_on_overflow */
1758 bfd_elf_generic_reloc, /* special_function */
1759 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12_NC), /* name */
1760 false, /* partial_inplace */
1761 0, /* src_mask */
1762 0x1ffc00, /* dst_mask */
1763 false), /* pcrel_offset */
1765 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1766 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12), /* type */
1767 2, /* rightshift */
1768 4, /* size */
1769 10, /* bitsize */
1770 false, /* pc_relative */
1771 10, /* bitpos */
1772 complain_overflow_unsigned, /* complain_on_overflow */
1773 bfd_elf_generic_reloc, /* special_function */
1774 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12), /* name */
1775 false, /* partial_inplace */
1776 0, /* src_mask */
1777 0xffc00, /* dst_mask */
1778 false), /* pcrel_offset */
1780 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check. */
1781 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12_NC), /* type */
1782 2, /* rightshift */
1783 4, /* size */
1784 10, /* bitsize */
1785 false, /* pc_relative */
1786 10, /* bitpos */
1787 complain_overflow_dont, /* complain_on_overflow */
1788 bfd_elf_generic_reloc, /* special_function */
1789 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12_NC), /* name */
1790 false, /* partial_inplace */
1791 0, /* src_mask */
1792 0xffc00, /* dst_mask */
1793 false), /* pcrel_offset */
1795 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1796 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12), /* type */
1797 3, /* rightshift */
1798 4, /* size */
1799 9, /* bitsize */
1800 false, /* pc_relative */
1801 10, /* bitpos */
1802 complain_overflow_unsigned, /* complain_on_overflow */
1803 bfd_elf_generic_reloc, /* special_function */
1804 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12), /* name */
1805 false, /* partial_inplace */
1806 0, /* src_mask */
1807 0x7fc00, /* dst_mask */
1808 false), /* pcrel_offset */
1810 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check. */
1811 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12_NC), /* type */
1812 3, /* rightshift */
1813 4, /* size */
1814 9, /* bitsize */
1815 false, /* pc_relative */
1816 10, /* bitpos */
1817 complain_overflow_dont, /* complain_on_overflow */
1818 bfd_elf_generic_reloc, /* special_function */
1819 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12_NC), /* name */
1820 false, /* partial_inplace */
1821 0, /* src_mask */
1822 0x7fc00, /* dst_mask */
1823 false), /* pcrel_offset */
1825 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1826 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12), /* type */
1827 0, /* rightshift */
1828 4, /* size */
1829 12, /* bitsize */
1830 false, /* pc_relative */
1831 10, /* bitpos */
1832 complain_overflow_unsigned, /* complain_on_overflow */
1833 bfd_elf_generic_reloc, /* special_function */
1834 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12), /* name */
1835 false, /* partial_inplace */
1836 0, /* src_mask */
1837 0x3ffc00, /* dst_mask */
1838 false), /* pcrel_offset */
1840 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check. */
1841 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12_NC), /* type */
1842 0, /* rightshift */
1843 4, /* size */
1844 12, /* bitsize */
1845 false, /* pc_relative */
1846 10, /* bitpos */
1847 complain_overflow_dont, /* complain_on_overflow */
1848 bfd_elf_generic_reloc, /* special_function */
1849 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12_NC), /* name */
1850 false, /* partial_inplace */
1851 0, /* src_mask */
1852 0x3ffc00, /* dst_mask */
1853 false), /* pcrel_offset */
1855 HOWTO (AARCH64_R (TLSDESC_LD_PREL19), /* type */
1856 2, /* rightshift */
1857 4, /* size */
1858 19, /* bitsize */
1859 true, /* pc_relative */
1860 0, /* bitpos */
1861 complain_overflow_dont, /* complain_on_overflow */
1862 bfd_elf_generic_reloc, /* special_function */
1863 AARCH64_R_STR (TLSDESC_LD_PREL19), /* name */
1864 false, /* partial_inplace */
1865 0, /* src_mask */
1866 0x0ffffe0, /* dst_mask */
1867 true), /* pcrel_offset */
1869 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21), /* type */
1870 0, /* rightshift */
1871 4, /* size */
1872 21, /* bitsize */
1873 true, /* pc_relative */
1874 0, /* bitpos */
1875 complain_overflow_dont, /* complain_on_overflow */
1876 bfd_elf_generic_reloc, /* special_function */
1877 AARCH64_R_STR (TLSDESC_ADR_PREL21), /* name */
1878 false, /* partial_inplace */
1879 0, /* src_mask */
1880 0x1fffff, /* dst_mask */
1881 true), /* pcrel_offset */
1883 /* Get to the page for the GOT entry for the symbol
1884 (G(S) - P) using an ADRP instruction. */
1885 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21), /* type */
1886 12, /* rightshift */
1887 4, /* size */
1888 21, /* bitsize */
1889 true, /* pc_relative */
1890 0, /* bitpos */
1891 complain_overflow_dont, /* complain_on_overflow */
1892 bfd_elf_generic_reloc, /* special_function */
1893 AARCH64_R_STR (TLSDESC_ADR_PAGE21), /* name */
1894 false, /* partial_inplace */
1895 0, /* src_mask */
1896 0x1fffff, /* dst_mask */
1897 true), /* pcrel_offset */
1899 /* LD64: GOT offset G(S) & 0xff8. */
1900 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12), /* type */
1901 3, /* rightshift */
1902 4, /* size */
1903 12, /* bitsize */
1904 false, /* pc_relative */
1905 0, /* bitpos */
1906 complain_overflow_dont, /* complain_on_overflow */
1907 bfd_elf_generic_reloc, /* special_function */
1908 AARCH64_R_STR (TLSDESC_LD64_LO12), /* name */
1909 false, /* partial_inplace */
1910 0, /* src_mask */
1911 0xff8, /* dst_mask */
1912 false), /* pcrel_offset */
1914 /* LD32: GOT offset G(S) & 0xffc. */
1915 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC), /* type */
1916 2, /* rightshift */
1917 4, /* size */
1918 12, /* bitsize */
1919 false, /* pc_relative */
1920 0, /* bitpos */
1921 complain_overflow_dont, /* complain_on_overflow */
1922 bfd_elf_generic_reloc, /* special_function */
1923 AARCH64_R_STR (TLSDESC_LD32_LO12_NC), /* name */
1924 false, /* partial_inplace */
1925 0, /* src_mask */
1926 0xffc, /* dst_mask */
1927 false), /* pcrel_offset */
1929 /* ADD: GOT offset G(S) & 0xfff. */
1930 HOWTO (AARCH64_R (TLSDESC_ADD_LO12), /* type */
1931 0, /* rightshift */
1932 4, /* size */
1933 12, /* bitsize */
1934 false, /* pc_relative */
1935 0, /* bitpos */
1936 complain_overflow_dont,/* complain_on_overflow */
1937 bfd_elf_generic_reloc, /* special_function */
1938 AARCH64_R_STR (TLSDESC_ADD_LO12), /* name */
1939 false, /* partial_inplace */
1940 0, /* src_mask */
1941 0xfff, /* dst_mask */
1942 false), /* pcrel_offset */
1944 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1), /* type */
1945 16, /* rightshift */
1946 4, /* size */
1947 12, /* bitsize */
1948 false, /* pc_relative */
1949 0, /* bitpos */
1950 complain_overflow_unsigned, /* complain_on_overflow */
1951 bfd_elf_generic_reloc, /* special_function */
1952 AARCH64_R_STR (TLSDESC_OFF_G1), /* name */
1953 false, /* partial_inplace */
1954 0, /* src_mask */
1955 0xffff, /* dst_mask */
1956 false), /* pcrel_offset */
1958 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC), /* type */
1959 0, /* rightshift */
1960 4, /* size */
1961 12, /* bitsize */
1962 false, /* pc_relative */
1963 0, /* bitpos */
1964 complain_overflow_dont, /* complain_on_overflow */
1965 bfd_elf_generic_reloc, /* special_function */
1966 AARCH64_R_STR (TLSDESC_OFF_G0_NC), /* name */
1967 false, /* partial_inplace */
1968 0, /* src_mask */
1969 0xffff, /* dst_mask */
1970 false), /* pcrel_offset */
1972 HOWTO64 (AARCH64_R (TLSDESC_LDR), /* type */
1973 0, /* rightshift */
1974 4, /* size */
1975 12, /* bitsize */
1976 false, /* pc_relative */
1977 0, /* bitpos */
1978 complain_overflow_dont, /* complain_on_overflow */
1979 bfd_elf_generic_reloc, /* special_function */
1980 AARCH64_R_STR (TLSDESC_LDR), /* name */
1981 false, /* partial_inplace */
1982 0x0, /* src_mask */
1983 0x0, /* dst_mask */
1984 false), /* pcrel_offset */
1986 HOWTO64 (AARCH64_R (TLSDESC_ADD), /* type */
1987 0, /* rightshift */
1988 4, /* size */
1989 12, /* bitsize */
1990 false, /* pc_relative */
1991 0, /* bitpos */
1992 complain_overflow_dont, /* complain_on_overflow */
1993 bfd_elf_generic_reloc, /* special_function */
1994 AARCH64_R_STR (TLSDESC_ADD), /* name */
1995 false, /* partial_inplace */
1996 0x0, /* src_mask */
1997 0x0, /* dst_mask */
1998 false), /* pcrel_offset */
2000 HOWTO (AARCH64_R (TLSDESC_CALL), /* type */
2001 0, /* rightshift */
2002 4, /* size */
2003 0, /* bitsize */
2004 false, /* pc_relative */
2005 0, /* bitpos */
2006 complain_overflow_dont, /* complain_on_overflow */
2007 bfd_elf_generic_reloc, /* special_function */
2008 AARCH64_R_STR (TLSDESC_CALL), /* name */
2009 false, /* partial_inplace */
2010 0x0, /* src_mask */
2011 0x0, /* dst_mask */
2012 false), /* pcrel_offset */
2014 HOWTO (AARCH64_R (COPY), /* type */
2015 0, /* rightshift */
2016 4, /* size */
2017 64, /* bitsize */
2018 false, /* pc_relative */
2019 0, /* bitpos */
2020 complain_overflow_bitfield, /* complain_on_overflow */
2021 bfd_elf_generic_reloc, /* special_function */
2022 AARCH64_R_STR (COPY), /* name */
2023 true, /* partial_inplace */
2024 0, /* src_mask */
2025 0xffffffff, /* dst_mask */
2026 false), /* pcrel_offset */
2028 HOWTO (AARCH64_R (GLOB_DAT), /* type */
2029 0, /* rightshift */
2030 4, /* size */
2031 64, /* bitsize */
2032 false, /* pc_relative */
2033 0, /* bitpos */
2034 complain_overflow_bitfield, /* complain_on_overflow */
2035 bfd_elf_generic_reloc, /* special_function */
2036 AARCH64_R_STR (GLOB_DAT), /* name */
2037 true, /* partial_inplace */
2038 0, /* src_mask */
2039 0xffffffff, /* dst_mask */
2040 false), /* pcrel_offset */
2042 HOWTO (AARCH64_R (JUMP_SLOT), /* type */
2043 0, /* rightshift */
2044 4, /* size */
2045 64, /* bitsize */
2046 false, /* pc_relative */
2047 0, /* bitpos */
2048 complain_overflow_bitfield, /* complain_on_overflow */
2049 bfd_elf_generic_reloc, /* special_function */
2050 AARCH64_R_STR (JUMP_SLOT), /* name */
2051 true, /* partial_inplace */
2052 0, /* src_mask */
2053 0xffffffff, /* dst_mask */
2054 false), /* pcrel_offset */
2056 HOWTO (AARCH64_R (RELATIVE), /* type */
2057 0, /* rightshift */
2058 4, /* size */
2059 64, /* bitsize */
2060 false, /* pc_relative */
2061 0, /* bitpos */
2062 complain_overflow_bitfield, /* complain_on_overflow */
2063 bfd_elf_generic_reloc, /* special_function */
2064 AARCH64_R_STR (RELATIVE), /* name */
2065 true, /* partial_inplace */
2066 0, /* src_mask */
2067 ALL_ONES, /* dst_mask */
2068 false), /* pcrel_offset */
2070 HOWTO (AARCH64_R (TLS_DTPMOD), /* type */
2071 0, /* rightshift */
2072 4, /* size */
2073 64, /* bitsize */
2074 false, /* pc_relative */
2075 0, /* bitpos */
2076 complain_overflow_dont, /* complain_on_overflow */
2077 bfd_elf_generic_reloc, /* special_function */
2078 #if ARCH_SIZE == 64
2079 AARCH64_R_STR (TLS_DTPMOD64), /* name */
2080 #else
2081 AARCH64_R_STR (TLS_DTPMOD), /* name */
2082 #endif
2083 false, /* partial_inplace */
2084 0, /* src_mask */
2085 ALL_ONES, /* dst_mask */
2086 false), /* pc_reloffset */
2088 HOWTO (AARCH64_R (TLS_DTPREL), /* type */
2089 0, /* rightshift */
2090 4, /* size */
2091 64, /* bitsize */
2092 false, /* pc_relative */
2093 0, /* bitpos */
2094 complain_overflow_dont, /* complain_on_overflow */
2095 bfd_elf_generic_reloc, /* special_function */
2096 #if ARCH_SIZE == 64
2097 AARCH64_R_STR (TLS_DTPREL64), /* name */
2098 #else
2099 AARCH64_R_STR (TLS_DTPREL), /* name */
2100 #endif
2101 false, /* partial_inplace */
2102 0, /* src_mask */
2103 ALL_ONES, /* dst_mask */
2104 false), /* pcrel_offset */
2106 HOWTO (AARCH64_R (TLS_TPREL), /* type */
2107 0, /* rightshift */
2108 4, /* size */
2109 64, /* bitsize */
2110 false, /* pc_relative */
2111 0, /* bitpos */
2112 complain_overflow_dont, /* complain_on_overflow */
2113 bfd_elf_generic_reloc, /* special_function */
2114 #if ARCH_SIZE == 64
2115 AARCH64_R_STR (TLS_TPREL64), /* name */
2116 #else
2117 AARCH64_R_STR (TLS_TPREL), /* name */
2118 #endif
2119 false, /* partial_inplace */
2120 0, /* src_mask */
2121 ALL_ONES, /* dst_mask */
2122 false), /* pcrel_offset */
2124 HOWTO (AARCH64_R (TLSDESC), /* type */
2125 0, /* rightshift */
2126 4, /* size */
2127 64, /* bitsize */
2128 false, /* pc_relative */
2129 0, /* bitpos */
2130 complain_overflow_dont, /* complain_on_overflow */
2131 bfd_elf_generic_reloc, /* special_function */
2132 AARCH64_R_STR (TLSDESC), /* name */
2133 false, /* partial_inplace */
2134 0, /* src_mask */
2135 ALL_ONES, /* dst_mask */
2136 false), /* pcrel_offset */
2138 HOWTO (AARCH64_R (IRELATIVE), /* type */
2139 0, /* rightshift */
2140 4, /* size */
2141 64, /* bitsize */
2142 false, /* pc_relative */
2143 0, /* bitpos */
2144 complain_overflow_bitfield, /* complain_on_overflow */
2145 bfd_elf_generic_reloc, /* special_function */
2146 AARCH64_R_STR (IRELATIVE), /* name */
2147 false, /* partial_inplace */
2148 0, /* src_mask */
2149 ALL_ONES, /* dst_mask */
2150 false), /* pcrel_offset */
2152 EMPTY_HOWTO (0),
2155 static reloc_howto_type elfNN_aarch64_howto_none =
2156 HOWTO (R_AARCH64_NONE, /* type */
2157 0, /* rightshift */
2158 0, /* size */
2159 0, /* bitsize */
2160 false, /* pc_relative */
2161 0, /* bitpos */
2162 complain_overflow_dont,/* complain_on_overflow */
2163 bfd_elf_generic_reloc, /* special_function */
2164 "R_AARCH64_NONE", /* name */
2165 false, /* partial_inplace */
2166 0, /* src_mask */
2167 0, /* dst_mask */
2168 false); /* pcrel_offset */
2170 /* Given HOWTO, return the bfd internal relocation enumerator. */
2172 static bfd_reloc_code_real_type
2173 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type *howto)
2175 const int size
2176 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table);
2177 const ptrdiff_t offset
2178 = howto - elfNN_aarch64_howto_table;
2180 if (offset > 0 && offset < size - 1)
2181 return BFD_RELOC_AARCH64_RELOC_START + offset;
2183 if (howto == &elfNN_aarch64_howto_none)
2184 return BFD_RELOC_AARCH64_NONE;
2186 return BFD_RELOC_AARCH64_RELOC_START;
2189 /* Given R_TYPE, return the bfd internal relocation enumerator. */
2191 static bfd_reloc_code_real_type
2192 elfNN_aarch64_bfd_reloc_from_type (bfd *abfd, unsigned int r_type)
2194 static bool initialized_p = false;
2195 /* Indexed by R_TYPE, values are offsets in the howto_table. */
2196 static unsigned int offsets[R_AARCH64_end];
2198 if (!initialized_p)
2200 unsigned int i;
2202 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
2203 if (elfNN_aarch64_howto_table[i].type != 0)
2204 offsets[elfNN_aarch64_howto_table[i].type] = i;
2206 initialized_p = true;
2209 if (r_type == R_AARCH64_NONE || r_type == R_AARCH64_NULL)
2210 return BFD_RELOC_AARCH64_NONE;
2212 /* PR 17512: file: b371e70a. */
2213 if (r_type >= R_AARCH64_end)
2215 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
2216 abfd, r_type);
2217 bfd_set_error (bfd_error_bad_value);
2218 return BFD_RELOC_AARCH64_NONE;
2221 return BFD_RELOC_AARCH64_RELOC_START + offsets[r_type];
2224 struct elf_aarch64_reloc_map
2226 bfd_reloc_code_real_type from;
2227 bfd_reloc_code_real_type to;
2230 /* Map bfd generic reloc to AArch64-specific reloc. */
2231 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map[] =
2233 {BFD_RELOC_NONE, BFD_RELOC_AARCH64_NONE},
2235 /* Basic data relocations. */
2236 {BFD_RELOC_CTOR, BFD_RELOC_AARCH64_NN},
2237 {BFD_RELOC_64, BFD_RELOC_AARCH64_64},
2238 {BFD_RELOC_32, BFD_RELOC_AARCH64_32},
2239 {BFD_RELOC_16, BFD_RELOC_AARCH64_16},
2240 {BFD_RELOC_64_PCREL, BFD_RELOC_AARCH64_64_PCREL},
2241 {BFD_RELOC_32_PCREL, BFD_RELOC_AARCH64_32_PCREL},
2242 {BFD_RELOC_16_PCREL, BFD_RELOC_AARCH64_16_PCREL},
2245 /* Given the bfd internal relocation enumerator in CODE, return the
2246 corresponding howto entry. */
2248 static reloc_howto_type *
2249 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
2251 unsigned int i;
2253 /* Convert bfd generic reloc to AArch64-specific reloc. */
2254 if (code < BFD_RELOC_AARCH64_RELOC_START
2255 || code > BFD_RELOC_AARCH64_RELOC_END)
2256 for (i = 0; i < ARRAY_SIZE (elf_aarch64_reloc_map); i++)
2257 if (elf_aarch64_reloc_map[i].from == code)
2259 code = elf_aarch64_reloc_map[i].to;
2260 break;
2263 if (code > BFD_RELOC_AARCH64_RELOC_START
2264 && code < BFD_RELOC_AARCH64_RELOC_END)
2265 if (elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START].type)
2266 return &elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START];
2268 if (code == BFD_RELOC_AARCH64_NONE)
2269 return &elfNN_aarch64_howto_none;
2271 return NULL;
2274 static reloc_howto_type *
2275 elfNN_aarch64_howto_from_type (bfd *abfd, unsigned int r_type)
2277 bfd_reloc_code_real_type val;
2278 reloc_howto_type *howto;
2280 #if ARCH_SIZE == 32
2281 if (r_type > 256)
2283 bfd_set_error (bfd_error_bad_value);
2284 return NULL;
2286 #endif
2288 if (r_type == R_AARCH64_NONE)
2289 return &elfNN_aarch64_howto_none;
2291 val = elfNN_aarch64_bfd_reloc_from_type (abfd, r_type);
2292 howto = elfNN_aarch64_howto_from_bfd_reloc (val);
2294 if (howto != NULL)
2295 return howto;
2297 bfd_set_error (bfd_error_bad_value);
2298 return NULL;
2301 static bool
2302 elfNN_aarch64_info_to_howto (bfd *abfd, arelent *bfd_reloc,
2303 Elf_Internal_Rela *elf_reloc)
2305 unsigned int r_type;
2307 r_type = ELFNN_R_TYPE (elf_reloc->r_info);
2308 bfd_reloc->howto = elfNN_aarch64_howto_from_type (abfd, r_type);
2310 if (bfd_reloc->howto == NULL)
2312 /* xgettext:c-format */
2313 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
2314 return false;
2316 return true;
2319 static reloc_howto_type *
2320 elfNN_aarch64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2321 bfd_reloc_code_real_type code)
2323 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (code);
2325 if (howto != NULL)
2326 return howto;
2328 bfd_set_error (bfd_error_bad_value);
2329 return NULL;
2332 static reloc_howto_type *
2333 elfNN_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2334 const char *r_name)
2336 unsigned int i;
2338 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
2339 if (elfNN_aarch64_howto_table[i].name != NULL
2340 && strcasecmp (elfNN_aarch64_howto_table[i].name, r_name) == 0)
2341 return &elfNN_aarch64_howto_table[i];
2343 return NULL;
2346 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
2347 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
2348 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
2349 #define TARGET_BIG_NAME "elfNN-bigaarch64"
2351 /* The linker script knows the section names for placement.
2352 The entry_names are used to do simple name mangling on the stubs.
2353 Given a function name, and its type, the stub can be found. The
2354 name can be changed. The only requirement is the %s be present. */
2355 #define STUB_ENTRY_NAME "__%s_veneer"
2357 /* Stub name for a BTI landing stub. */
2358 #define BTI_STUB_ENTRY_NAME "__%s_bti_veneer"
2360 /* The name of the dynamic interpreter. This is put in the .interp
2361 section. */
2362 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
2364 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
2365 (((1 << 25) - 1) << 2)
2366 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
2367 (-((1 << 25) << 2))
2369 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
2370 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
2372 static int
2373 aarch64_valid_for_adrp_p (bfd_vma value, bfd_vma place)
2375 bfd_signed_vma offset = (bfd_signed_vma) (PG (value) - PG (place)) >> 12;
2376 return offset <= AARCH64_MAX_ADRP_IMM && offset >= AARCH64_MIN_ADRP_IMM;
2379 static int
2380 aarch64_valid_branch_p (bfd_vma value, bfd_vma place)
2382 bfd_signed_vma offset = (bfd_signed_vma) (value - place);
2383 return (offset <= AARCH64_MAX_FWD_BRANCH_OFFSET
2384 && offset >= AARCH64_MAX_BWD_BRANCH_OFFSET);
2387 static const uint32_t aarch64_adrp_branch_stub [] =
2389 0x90000010, /* adrp ip0, X */
2390 /* R_AARCH64_ADR_HI21_PCREL(X) */
2391 0x91000210, /* add ip0, ip0, :lo12:X */
2392 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2393 0xd61f0200, /* br ip0 */
2396 static const uint32_t aarch64_long_branch_stub[] =
2398 #if ARCH_SIZE == 64
2399 0x58000090, /* ldr ip0, 1f */
2400 #else
2401 0x18000090, /* ldr wip0, 1f */
2402 #endif
2403 0x10000011, /* adr ip1, #0 */
2404 0x8b110210, /* add ip0, ip0, ip1 */
2405 0xd61f0200, /* br ip0 */
2406 0x00000000, /* 1: .xword or .word
2407 R_AARCH64_PRELNN(X) + 12
2409 0x00000000,
2412 static const uint32_t aarch64_bti_direct_branch_stub[] =
2414 0xd503245f, /* bti c */
2415 0x14000000, /* b <label> */
2418 static const uint32_t aarch64_erratum_835769_stub[] =
2420 0x00000000, /* Placeholder for multiply accumulate. */
2421 0x14000000, /* b <label> */
2424 static const uint32_t aarch64_erratum_843419_stub[] =
2426 0x00000000, /* Placeholder for LDR instruction. */
2427 0x14000000, /* b <label> */
2430 /* Section name for stubs is the associated section name plus this
2431 string. */
2432 #define STUB_SUFFIX ".stub"
2434 enum elf_aarch64_stub_type
2436 aarch64_stub_none,
2437 aarch64_stub_adrp_branch,
2438 aarch64_stub_long_branch,
2439 aarch64_stub_bti_direct_branch,
2440 aarch64_stub_erratum_835769_veneer,
2441 aarch64_stub_erratum_843419_veneer,
2444 struct elf_aarch64_stub_hash_entry
2446 /* Base hash table entry structure. */
2447 struct bfd_hash_entry root;
2449 /* The stub section. */
2450 asection *stub_sec;
2452 /* Offset within stub_sec of the beginning of this stub. */
2453 bfd_vma stub_offset;
2455 /* Given the symbol's value and its section we can determine its final
2456 value when building the stubs (so the stub knows where to jump). */
2457 bfd_vma target_value;
2458 asection *target_section;
2460 enum elf_aarch64_stub_type stub_type;
2462 /* The symbol table entry, if any, that this was derived from. */
2463 struct elf_aarch64_link_hash_entry *h;
2465 /* Destination symbol type */
2466 unsigned char st_type;
2468 /* The target is also a stub. */
2469 bool double_stub;
2471 /* Where this stub is being called from, or, in the case of combined
2472 stub sections, the first input section in the group. */
2473 asection *id_sec;
2475 /* The name for the local symbol at the start of this stub. The
2476 stub name in the hash table has to be unique; this does not, so
2477 it can be friendlier. */
2478 char *output_name;
2480 /* The instruction which caused this stub to be generated (only valid for
2481 erratum 835769 workaround stubs at present). */
2482 uint32_t veneered_insn;
2484 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
2485 bfd_vma adrp_offset;
2488 /* Used to build a map of a section. This is required for mixed-endian
2489 code/data. */
2491 typedef struct elf_elf_section_map
2493 bfd_vma vma;
2494 char type;
2496 elf_aarch64_section_map;
2499 typedef struct _aarch64_elf_section_data
2501 struct bfd_elf_section_data elf;
2502 unsigned int mapcount;
2503 unsigned int mapsize;
2504 elf_aarch64_section_map *map;
2506 _aarch64_elf_section_data;
2508 #define elf_aarch64_section_data(sec) \
2509 ((_aarch64_elf_section_data *) elf_section_data (sec))
2511 /* The size of the thread control block which is defined to be two pointers. */
2512 #define TCB_SIZE (ARCH_SIZE/8)*2
2514 struct elf_aarch64_local_symbol
2516 unsigned int got_type;
2517 bfd_signed_vma got_refcount;
2518 bfd_vma got_offset;
2520 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2521 offset is from the end of the jump table and reserved entries
2522 within the PLTGOT.
2524 The magic value (bfd_vma) -1 indicates that an offset has not be
2525 allocated. */
2526 bfd_vma tlsdesc_got_jump_table_offset;
2529 struct elf_aarch64_obj_tdata
2531 struct elf_obj_tdata root;
2533 /* local symbol descriptors */
2534 struct elf_aarch64_local_symbol *locals;
2536 /* Zero to warn when linking objects with incompatible enum sizes. */
2537 int no_enum_size_warning;
2539 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
2540 int no_wchar_size_warning;
2542 /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties. */
2543 uint32_t gnu_and_prop;
2545 /* Zero to warn when linking objects with incompatible
2546 GNU_PROPERTY_AARCH64_FEATURE_1_BTI. */
2547 int no_bti_warn;
2549 /* PLT type based on security. */
2550 aarch64_plt_type plt_type;
2553 #define elf_aarch64_tdata(bfd) \
2554 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
2556 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
2558 #define is_aarch64_elf(bfd) \
2559 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2560 && elf_tdata (bfd) != NULL \
2561 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2563 static bool
2564 elfNN_aarch64_mkobject (bfd *abfd)
2566 return bfd_elf_allocate_object (abfd, sizeof (struct elf_aarch64_obj_tdata),
2567 AARCH64_ELF_DATA);
2570 #define elf_aarch64_hash_entry(ent) \
2571 ((struct elf_aarch64_link_hash_entry *)(ent))
2573 #define GOT_UNKNOWN 0
2574 #define GOT_NORMAL 1
2575 #define GOT_TLS_GD 2
2576 #define GOT_TLS_IE 4
2577 #define GOT_TLSDESC_GD 8
2579 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
2581 /* AArch64 ELF linker hash entry. */
2582 struct elf_aarch64_link_hash_entry
2584 struct elf_link_hash_entry root;
2586 /* Since PLT entries have variable size, we need to record the
2587 index into .got.plt instead of recomputing it from the PLT
2588 offset. */
2589 bfd_signed_vma plt_got_offset;
2591 /* Bit mask representing the type of GOT entry(s) if any required by
2592 this symbol. */
2593 unsigned int got_type;
2595 /* TRUE if symbol is defined as a protected symbol. */
2596 unsigned int def_protected : 1;
2598 /* A pointer to the most recently used stub hash entry against this
2599 symbol. */
2600 struct elf_aarch64_stub_hash_entry *stub_cache;
2602 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
2603 is from the end of the jump table and reserved entries within the PLTGOT.
2605 The magic value (bfd_vma) -1 indicates that an offset has not
2606 be allocated. */
2607 bfd_vma tlsdesc_got_jump_table_offset;
2610 static unsigned int
2611 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry *h,
2612 bfd *abfd,
2613 unsigned long r_symndx)
2615 if (h)
2616 return elf_aarch64_hash_entry (h)->got_type;
2618 if (! elf_aarch64_locals (abfd))
2619 return GOT_UNKNOWN;
2621 return elf_aarch64_locals (abfd)[r_symndx].got_type;
2624 /* Get the AArch64 elf linker hash table from a link_info structure. */
2625 #define elf_aarch64_hash_table(info) \
2626 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
2628 #define aarch64_stub_hash_lookup(table, string, create, copy) \
2629 ((struct elf_aarch64_stub_hash_entry *) \
2630 bfd_hash_lookup ((table), (string), (create), (copy)))
2632 /* AArch64 ELF linker hash table. */
2633 struct elf_aarch64_link_hash_table
2635 /* The main hash table. */
2636 struct elf_link_hash_table root;
2638 /* Nonzero to force PIC branch veneers. */
2639 int pic_veneer;
2641 /* Fix erratum 835769. */
2642 int fix_erratum_835769;
2644 /* Fix erratum 843419. */
2645 erratum_84319_opts fix_erratum_843419;
2647 /* Don't apply link-time values for dynamic relocations. */
2648 int no_apply_dynamic_relocs;
2650 /* The number of bytes in the initial entry in the PLT. */
2651 bfd_size_type plt_header_size;
2653 /* The bytes of the initial PLT entry. */
2654 const bfd_byte *plt0_entry;
2656 /* The number of bytes in the subsequent PLT entries. */
2657 bfd_size_type plt_entry_size;
2659 /* The bytes of the subsequent PLT entry. */
2660 const bfd_byte *plt_entry;
2662 /* For convenience in allocate_dynrelocs. */
2663 bfd *obfd;
2665 /* The amount of space used by the reserved portion of the sgotplt
2666 section, plus whatever space is used by the jump slots. */
2667 bfd_vma sgotplt_jump_table_size;
2669 /* The stub hash table. */
2670 struct bfd_hash_table stub_hash_table;
2672 /* Linker stub bfd. */
2673 bfd *stub_bfd;
2675 /* Linker call-backs. */
2676 asection *(*add_stub_section) (const char *, asection *);
2677 void (*layout_sections_again) (void);
2679 /* Array to keep track of which stub sections have been created, and
2680 information on stub grouping. */
2681 struct map_stub
2683 /* This is the section to which stubs in the group will be
2684 attached. */
2685 asection *link_sec;
2686 /* The stub section. */
2687 asection *stub_sec;
2688 } *stub_group;
2690 /* Assorted information used by elfNN_aarch64_size_stubs. */
2691 unsigned int bfd_count;
2692 unsigned int top_index;
2693 asection **input_list;
2695 /* True when two stubs are added where one targets the other, happens
2696 when BTI stubs are inserted and then the stub layout must not change
2697 during elfNN_aarch64_build_stubs. */
2698 bool has_double_stub;
2700 /* JUMP_SLOT relocs for variant PCS symbols may be present. */
2701 int variant_pcs;
2703 /* The number of bytes in the PLT enty for the TLS descriptor. */
2704 bfd_size_type tlsdesc_plt_entry_size;
2706 /* Used by local STT_GNU_IFUNC symbols. */
2707 htab_t loc_hash_table;
2708 void * loc_hash_memory;
2710 /* Array of relative relocs to be emitted in DT_RELR format. */
2711 bfd_size_type relr_alloc;
2712 bfd_size_type relr_count;
2713 struct relr_entry
2715 asection *sec;
2716 bfd_vma off;
2717 } *relr;
2718 /* Sorted output addresses of above relative relocs. */
2719 bfd_vma *relr_sorted;
2720 /* Layout recomputation count. */
2721 bfd_size_type relr_layout_iter;
2724 /* Create an entry in an AArch64 ELF linker hash table. */
2726 static struct bfd_hash_entry *
2727 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
2728 struct bfd_hash_table *table,
2729 const char *string)
2731 struct elf_aarch64_link_hash_entry *ret =
2732 (struct elf_aarch64_link_hash_entry *) entry;
2734 /* Allocate the structure if it has not already been allocated by a
2735 subclass. */
2736 if (ret == NULL)
2737 ret = bfd_hash_allocate (table,
2738 sizeof (struct elf_aarch64_link_hash_entry));
2739 if (ret == NULL)
2740 return (struct bfd_hash_entry *) ret;
2742 /* Call the allocation method of the superclass. */
2743 ret = ((struct elf_aarch64_link_hash_entry *)
2744 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2745 table, string));
2746 if (ret != NULL)
2748 ret->got_type = GOT_UNKNOWN;
2749 ret->def_protected = 0;
2750 ret->plt_got_offset = (bfd_vma) - 1;
2751 ret->stub_cache = NULL;
2752 ret->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
2755 return (struct bfd_hash_entry *) ret;
2758 /* Initialize an entry in the stub hash table. */
2760 static struct bfd_hash_entry *
2761 stub_hash_newfunc (struct bfd_hash_entry *entry,
2762 struct bfd_hash_table *table, const char *string)
2764 /* Allocate the structure if it has not already been allocated by a
2765 subclass. */
2766 if (entry == NULL)
2768 entry = bfd_hash_allocate (table,
2769 sizeof (struct
2770 elf_aarch64_stub_hash_entry));
2771 if (entry == NULL)
2772 return entry;
2775 /* Call the allocation method of the superclass. */
2776 entry = bfd_hash_newfunc (entry, table, string);
2777 if (entry != NULL)
2779 struct elf_aarch64_stub_hash_entry *eh;
2781 /* Initialize the local fields. */
2782 eh = (struct elf_aarch64_stub_hash_entry *) entry;
2783 memset (&eh->stub_sec, 0,
2784 (sizeof (struct elf_aarch64_stub_hash_entry)
2785 - offsetof (struct elf_aarch64_stub_hash_entry, stub_sec)));
2788 return entry;
2791 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
2792 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2793 as global symbol. We reuse indx and dynstr_index for local symbol
2794 hash since they aren't used by global symbols in this backend. */
2796 static hashval_t
2797 elfNN_aarch64_local_htab_hash (const void *ptr)
2799 struct elf_link_hash_entry *h
2800 = (struct elf_link_hash_entry *) ptr;
2801 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
2804 /* Compare local hash entries. */
2806 static int
2807 elfNN_aarch64_local_htab_eq (const void *ptr1, const void *ptr2)
2809 struct elf_link_hash_entry *h1
2810 = (struct elf_link_hash_entry *) ptr1;
2811 struct elf_link_hash_entry *h2
2812 = (struct elf_link_hash_entry *) ptr2;
2814 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
2817 /* Find and/or create a hash entry for local symbol. */
2819 static struct elf_link_hash_entry *
2820 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table *htab,
2821 bfd *abfd, const Elf_Internal_Rela *rel,
2822 bool create)
2824 struct elf_aarch64_link_hash_entry e, *ret;
2825 asection *sec = abfd->sections;
2826 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
2827 ELFNN_R_SYM (rel->r_info));
2828 void **slot;
2830 e.root.indx = sec->id;
2831 e.root.dynstr_index = ELFNN_R_SYM (rel->r_info);
2832 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
2833 create ? INSERT : NO_INSERT);
2835 if (!slot)
2836 return NULL;
2838 if (*slot)
2840 ret = (struct elf_aarch64_link_hash_entry *) *slot;
2841 return &ret->root;
2844 ret = (struct elf_aarch64_link_hash_entry *)
2845 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
2846 sizeof (struct elf_aarch64_link_hash_entry));
2847 if (ret)
2849 memset (ret, 0, sizeof (*ret));
2850 ret->root.indx = sec->id;
2851 ret->root.dynstr_index = ELFNN_R_SYM (rel->r_info);
2852 ret->root.dynindx = -1;
2853 *slot = ret;
2855 return &ret->root;
2858 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2860 static void
2861 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
2862 struct elf_link_hash_entry *dir,
2863 struct elf_link_hash_entry *ind)
2865 struct elf_aarch64_link_hash_entry *edir, *eind;
2867 edir = (struct elf_aarch64_link_hash_entry *) dir;
2868 eind = (struct elf_aarch64_link_hash_entry *) ind;
2870 if (ind->root.type == bfd_link_hash_indirect)
2872 /* Copy over PLT info. */
2873 if (dir->got.refcount <= 0)
2875 edir->got_type = eind->got_type;
2876 eind->got_type = GOT_UNKNOWN;
2880 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2883 /* Merge non-visibility st_other attributes. */
2885 static void
2886 elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry *h,
2887 unsigned int st_other,
2888 bool definition,
2889 bool dynamic ATTRIBUTE_UNUSED)
2891 if (definition)
2893 struct elf_aarch64_link_hash_entry *eh
2894 = (struct elf_aarch64_link_hash_entry *)h;
2895 eh->def_protected = ELF_ST_VISIBILITY (st_other) == STV_PROTECTED;
2898 unsigned int isym_sto = st_other & ~ELF_ST_VISIBILITY (-1);
2899 unsigned int h_sto = h->other & ~ELF_ST_VISIBILITY (-1);
2901 if (isym_sto == h_sto)
2902 return;
2904 if (isym_sto & ~STO_AARCH64_VARIANT_PCS)
2905 /* Not fatal, this callback cannot fail. */
2906 _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"),
2907 h->root.root.string, isym_sto);
2909 /* Note: Ideally we would warn about any attribute mismatch, but
2910 this api does not allow that without substantial changes. */
2911 if (isym_sto & STO_AARCH64_VARIANT_PCS)
2912 h->other |= STO_AARCH64_VARIANT_PCS;
2915 /* Destroy an AArch64 elf linker hash table. */
2917 static void
2918 elfNN_aarch64_link_hash_table_free (bfd *obfd)
2920 struct elf_aarch64_link_hash_table *ret
2921 = (struct elf_aarch64_link_hash_table *) obfd->link.hash;
2923 if (ret->loc_hash_table)
2924 htab_delete (ret->loc_hash_table);
2925 if (ret->loc_hash_memory)
2926 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
2928 bfd_hash_table_free (&ret->stub_hash_table);
2929 _bfd_elf_link_hash_table_free (obfd);
2932 /* Create an AArch64 elf linker hash table. */
2934 static struct bfd_link_hash_table *
2935 elfNN_aarch64_link_hash_table_create (bfd *abfd)
2937 struct elf_aarch64_link_hash_table *ret;
2938 size_t amt = sizeof (struct elf_aarch64_link_hash_table);
2940 ret = bfd_zmalloc (amt);
2941 if (ret == NULL)
2942 return NULL;
2944 if (!_bfd_elf_link_hash_table_init
2945 (&ret->root, abfd, elfNN_aarch64_link_hash_newfunc,
2946 sizeof (struct elf_aarch64_link_hash_entry), AARCH64_ELF_DATA))
2948 free (ret);
2949 return NULL;
2952 ret->plt_header_size = PLT_ENTRY_SIZE;
2953 ret->plt0_entry = elfNN_aarch64_small_plt0_entry;
2954 ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
2955 ret->plt_entry = elfNN_aarch64_small_plt_entry;
2956 ret->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
2957 ret->obfd = abfd;
2958 ret->root.tlsdesc_got = (bfd_vma) - 1;
2960 if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
2961 sizeof (struct elf_aarch64_stub_hash_entry)))
2963 _bfd_elf_link_hash_table_free (abfd);
2964 return NULL;
2967 ret->loc_hash_table = htab_try_create (1024,
2968 elfNN_aarch64_local_htab_hash,
2969 elfNN_aarch64_local_htab_eq,
2970 NULL);
2971 ret->loc_hash_memory = objalloc_create ();
2972 if (!ret->loc_hash_table || !ret->loc_hash_memory)
2974 elfNN_aarch64_link_hash_table_free (abfd);
2975 return NULL;
2977 ret->root.root.hash_table_free = elfNN_aarch64_link_hash_table_free;
2979 return &ret->root.root;
2982 /* Perform relocation R_TYPE. Returns TRUE upon success, FALSE otherwise. */
2984 static bool
2985 aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
2986 bfd_vma offset, bfd_vma value)
2988 reloc_howto_type *howto;
2989 bfd_vma place;
2991 howto = elfNN_aarch64_howto_from_type (input_bfd, r_type);
2992 place = (input_section->output_section->vma + input_section->output_offset
2993 + offset);
2995 r_type = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
2996 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, r_type, place,
2997 value, 0, false);
2998 return _bfd_aarch64_elf_put_addend (input_bfd,
2999 input_section->contents + offset, r_type,
3000 howto, value) == bfd_reloc_ok;
3003 /* Determine the type of stub needed, if any, for a call. */
3005 static enum elf_aarch64_stub_type
3006 aarch64_type_of_stub (asection *input_sec,
3007 const Elf_Internal_Rela *rel,
3008 asection *sym_sec,
3009 unsigned char st_type,
3010 bfd_vma destination)
3012 bfd_vma location;
3013 bfd_signed_vma branch_offset;
3014 unsigned int r_type;
3015 enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
3017 if (st_type != STT_FUNC
3018 && (sym_sec == input_sec))
3019 return stub_type;
3021 /* Determine where the call point is. */
3022 location = (input_sec->output_offset
3023 + input_sec->output_section->vma + rel->r_offset);
3025 branch_offset = (bfd_signed_vma) (destination - location);
3027 r_type = ELFNN_R_TYPE (rel->r_info);
3029 /* We don't want to redirect any old unconditional jump in this way,
3030 only one which is being used for a sibcall, where it is
3031 acceptable for the IP0 and IP1 registers to be clobbered. */
3032 if ((r_type == AARCH64_R (CALL26) || r_type == AARCH64_R (JUMP26))
3033 && (branch_offset > AARCH64_MAX_FWD_BRANCH_OFFSET
3034 || branch_offset < AARCH64_MAX_BWD_BRANCH_OFFSET))
3036 stub_type = aarch64_stub_long_branch;
3039 return stub_type;
3042 /* Build a name for an entry in the stub hash table. */
3044 static char *
3045 elfNN_aarch64_stub_name (const asection *input_section,
3046 const asection *sym_sec,
3047 const struct elf_aarch64_link_hash_entry *hash,
3048 const Elf_Internal_Rela *rel)
3050 char *stub_name;
3051 bfd_size_type len;
3053 if (hash)
3055 len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
3056 stub_name = bfd_malloc (len);
3057 if (stub_name != NULL)
3058 snprintf (stub_name, len, "%08x_%s+%" PRIx64,
3059 (unsigned int) input_section->id,
3060 hash->root.root.root.string,
3061 (uint64_t) rel->r_addend);
3063 else
3065 len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
3066 stub_name = bfd_malloc (len);
3067 if (stub_name != NULL)
3068 snprintf (stub_name, len, "%08x_%x:%x+%" PRIx64,
3069 (unsigned int) input_section->id,
3070 (unsigned int) sym_sec->id,
3071 (unsigned int) ELFNN_R_SYM (rel->r_info),
3072 (uint64_t) rel->r_addend);
3075 return stub_name;
3078 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
3079 executable PLT slots where the executable never takes the address of those
3080 functions, the function symbols are not added to the hash table. */
3082 static bool
3083 elf_aarch64_hash_symbol (struct elf_link_hash_entry *h)
3085 if (h->plt.offset != (bfd_vma) -1
3086 && !h->def_regular
3087 && !h->pointer_equality_needed)
3088 return false;
3090 return _bfd_elf_hash_symbol (h);
3094 /* Look up an entry in the stub hash. Stub entries are cached because
3095 creating the stub name takes a bit of time. */
3097 static struct elf_aarch64_stub_hash_entry *
3098 elfNN_aarch64_get_stub_entry (const asection *input_section,
3099 const asection *sym_sec,
3100 struct elf_link_hash_entry *hash,
3101 const Elf_Internal_Rela *rel,
3102 struct elf_aarch64_link_hash_table *htab)
3104 struct elf_aarch64_stub_hash_entry *stub_entry;
3105 struct elf_aarch64_link_hash_entry *h =
3106 (struct elf_aarch64_link_hash_entry *) hash;
3107 const asection *id_sec;
3109 if ((input_section->flags & SEC_CODE) == 0)
3110 return NULL;
3112 /* If this input section is part of a group of sections sharing one
3113 stub section, then use the id of the first section in the group.
3114 Stub names need to include a section id, as there may well be
3115 more than one stub used to reach say, printf, and we need to
3116 distinguish between them. */
3117 id_sec = htab->stub_group[input_section->id].link_sec;
3119 if (h != NULL && h->stub_cache != NULL
3120 && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
3122 stub_entry = h->stub_cache;
3124 else
3126 char *stub_name;
3128 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, h, rel);
3129 if (stub_name == NULL)
3130 return NULL;
3132 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
3133 stub_name, false, false);
3134 if (h != NULL)
3135 h->stub_cache = stub_entry;
3137 free (stub_name);
3140 return stub_entry;
3144 /* Create a stub section. */
3146 static asection *
3147 _bfd_aarch64_create_stub_section (asection *section,
3148 struct elf_aarch64_link_hash_table *htab)
3150 size_t namelen;
3151 bfd_size_type len;
3152 char *s_name;
3154 namelen = strlen (section->name);
3155 len = namelen + sizeof (STUB_SUFFIX);
3156 s_name = bfd_alloc (htab->stub_bfd, len);
3157 if (s_name == NULL)
3158 return NULL;
3160 memcpy (s_name, section->name, namelen);
3161 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
3162 return (*htab->add_stub_section) (s_name, section);
3166 /* Find or create a stub section for a link section.
3168 Fix or create the stub section used to collect stubs attached to
3169 the specified link section. */
3171 static asection *
3172 _bfd_aarch64_get_stub_for_link_section (asection *link_section,
3173 struct elf_aarch64_link_hash_table *htab)
3175 if (htab->stub_group[link_section->id].stub_sec == NULL)
3176 htab->stub_group[link_section->id].stub_sec
3177 = _bfd_aarch64_create_stub_section (link_section, htab);
3178 return htab->stub_group[link_section->id].stub_sec;
3182 /* Find or create a stub section in the stub group for an input
3183 section. */
3185 static asection *
3186 _bfd_aarch64_create_or_find_stub_sec (asection *section,
3187 struct elf_aarch64_link_hash_table *htab)
3189 asection *link_sec = htab->stub_group[section->id].link_sec;
3190 return _bfd_aarch64_get_stub_for_link_section (link_sec, htab);
3194 /* Add a new stub entry in the stub group associated with an input
3195 section to the stub hash. Not all fields of the new stub entry are
3196 initialised. */
3198 static struct elf_aarch64_stub_hash_entry *
3199 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name,
3200 asection *section,
3201 struct elf_aarch64_link_hash_table *htab)
3203 asection *link_sec;
3204 asection *stub_sec;
3205 struct elf_aarch64_stub_hash_entry *stub_entry;
3207 link_sec = htab->stub_group[section->id].link_sec;
3208 stub_sec = _bfd_aarch64_create_or_find_stub_sec (section, htab);
3210 /* Enter this entry into the linker stub hash table. */
3211 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3212 true, false);
3213 if (stub_entry == NULL)
3215 /* xgettext:c-format */
3216 _bfd_error_handler (_("%pB: cannot create stub entry %s"),
3217 section->owner, stub_name);
3218 return NULL;
3221 stub_entry->stub_sec = stub_sec;
3222 stub_entry->stub_offset = 0;
3223 stub_entry->id_sec = link_sec;
3225 return stub_entry;
3228 /* Add a new stub entry in the final stub section to the stub hash.
3229 Not all fields of the new stub entry are initialised. */
3231 static struct elf_aarch64_stub_hash_entry *
3232 _bfd_aarch64_add_stub_entry_after (const char *stub_name,
3233 asection *link_section,
3234 struct elf_aarch64_link_hash_table *htab)
3236 asection *stub_sec;
3237 struct elf_aarch64_stub_hash_entry *stub_entry;
3239 stub_sec = NULL;
3240 /* Only create the actual stub if we will end up needing it. */
3241 if (htab->fix_erratum_843419 & ERRAT_ADRP)
3242 stub_sec = _bfd_aarch64_get_stub_for_link_section (link_section, htab);
3243 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3244 true, false);
3245 if (stub_entry == NULL)
3247 _bfd_error_handler (_("cannot create stub entry %s"), stub_name);
3248 return NULL;
3251 stub_entry->stub_sec = stub_sec;
3252 stub_entry->stub_offset = 0;
3253 stub_entry->id_sec = link_section;
3255 return stub_entry;
3259 static bool
3260 aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
3261 void *in_arg)
3263 struct elf_aarch64_stub_hash_entry *stub_entry;
3264 asection *stub_sec;
3265 bfd *stub_bfd;
3266 bfd_byte *loc;
3267 bfd_vma sym_value;
3268 bfd_vma veneered_insn_loc;
3269 bfd_vma veneer_entry_loc;
3270 bfd_signed_vma branch_offset = 0;
3271 unsigned int template_size;
3272 unsigned int pad_size = 0;
3273 const uint32_t *template;
3274 unsigned int i;
3275 struct bfd_link_info *info;
3276 struct elf_aarch64_link_hash_table *htab;
3278 /* Massage our args to the form they really have. */
3279 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
3281 info = (struct bfd_link_info *) in_arg;
3282 htab = elf_aarch64_hash_table (info);
3284 /* Fail if the target section could not be assigned to an output
3285 section. The user should fix his linker script. */
3286 if (stub_entry->target_section->output_section == NULL
3287 && info->non_contiguous_regions)
3288 info->callbacks->einfo (_("%F%P: Could not assign `%pA' to an output section. "
3289 "Retry without "
3290 "--enable-non-contiguous-regions.\n"),
3291 stub_entry->target_section);
3293 stub_sec = stub_entry->stub_sec;
3295 /* The layout must not change when a stub may be the target of another. */
3296 if (htab->has_double_stub)
3297 BFD_ASSERT (stub_entry->stub_offset == stub_sec->size);
3299 /* Make a note of the offset within the stubs for this entry. */
3300 stub_entry->stub_offset = stub_sec->size;
3301 loc = stub_sec->contents + stub_entry->stub_offset;
3303 stub_bfd = stub_sec->owner;
3305 /* This is the address of the stub destination. */
3306 sym_value = (stub_entry->target_value
3307 + stub_entry->target_section->output_offset
3308 + stub_entry->target_section->output_section->vma);
3310 if (stub_entry->stub_type == aarch64_stub_long_branch)
3312 bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
3313 + stub_sec->output_offset);
3315 /* See if we can relax the stub. */
3316 if (aarch64_valid_for_adrp_p (sym_value, place))
3318 stub_entry->stub_type = aarch64_stub_adrp_branch;
3320 /* Avoid the relaxation changing the layout. */
3321 if (htab->has_double_stub)
3322 pad_size = sizeof (aarch64_long_branch_stub)
3323 - sizeof (aarch64_adrp_branch_stub);
3327 switch (stub_entry->stub_type)
3329 case aarch64_stub_adrp_branch:
3330 template = aarch64_adrp_branch_stub;
3331 template_size = sizeof (aarch64_adrp_branch_stub);
3332 break;
3333 case aarch64_stub_long_branch:
3334 template = aarch64_long_branch_stub;
3335 template_size = sizeof (aarch64_long_branch_stub);
3336 break;
3337 case aarch64_stub_bti_direct_branch:
3338 template = aarch64_bti_direct_branch_stub;
3339 template_size = sizeof (aarch64_bti_direct_branch_stub);
3340 break;
3341 case aarch64_stub_erratum_835769_veneer:
3342 template = aarch64_erratum_835769_stub;
3343 template_size = sizeof (aarch64_erratum_835769_stub);
3344 break;
3345 case aarch64_stub_erratum_843419_veneer:
3346 template = aarch64_erratum_843419_stub;
3347 template_size = sizeof (aarch64_erratum_843419_stub);
3348 break;
3349 default:
3350 abort ();
3353 for (i = 0; i < (template_size / sizeof template[0]); i++)
3355 bfd_putl32 (template[i], loc);
3356 loc += 4;
3359 template_size += pad_size;
3360 template_size = (template_size + 7) & ~7;
3361 stub_sec->size += template_size;
3363 switch (stub_entry->stub_type)
3365 case aarch64_stub_adrp_branch:
3366 if (!aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
3367 stub_entry->stub_offset, sym_value))
3368 /* The stub would not have been relaxed if the offset was out
3369 of range. */
3370 BFD_FAIL ();
3372 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC), stub_bfd, stub_sec,
3373 stub_entry->stub_offset + 4, sym_value))
3374 BFD_FAIL ();
3375 break;
3377 case aarch64_stub_long_branch:
3378 /* We want the value relative to the address 12 bytes back from the
3379 value itself. */
3380 if (!aarch64_relocate (AARCH64_R (PRELNN), stub_bfd, stub_sec,
3381 stub_entry->stub_offset + 16, sym_value + 12))
3382 BFD_FAIL ();
3383 break;
3385 case aarch64_stub_bti_direct_branch:
3386 if (!aarch64_relocate (AARCH64_R (JUMP26), stub_bfd, stub_sec,
3387 stub_entry->stub_offset + 4, sym_value))
3388 BFD_FAIL ();
3389 break;
3391 case aarch64_stub_erratum_835769_veneer:
3392 veneered_insn_loc = stub_entry->target_section->output_section->vma
3393 + stub_entry->target_section->output_offset
3394 + stub_entry->target_value;
3395 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
3396 + stub_entry->stub_sec->output_offset
3397 + stub_entry->stub_offset;
3398 branch_offset = veneered_insn_loc - veneer_entry_loc;
3399 branch_offset >>= 2;
3400 branch_offset &= 0x3ffffff;
3401 bfd_putl32 (stub_entry->veneered_insn,
3402 stub_sec->contents + stub_entry->stub_offset);
3403 bfd_putl32 (template[1] | branch_offset,
3404 stub_sec->contents + stub_entry->stub_offset + 4);
3405 break;
3407 case aarch64_stub_erratum_843419_veneer:
3408 if (!aarch64_relocate (AARCH64_R (JUMP26), stub_bfd, stub_sec,
3409 stub_entry->stub_offset + 4, sym_value + 4))
3410 BFD_FAIL ();
3411 break;
3413 default:
3414 abort ();
3417 return true;
3420 /* As above, but don't actually build the stub. Just bump offset so
3421 we know stub section sizes and record the offset for each stub so
3422 a stub can target another stub (needed for BTI direct branch stub). */
3424 static bool
3425 aarch64_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
3427 struct elf_aarch64_stub_hash_entry *stub_entry;
3428 struct elf_aarch64_link_hash_table *htab;
3429 int size;
3431 /* Massage our args to the form they really have. */
3432 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
3433 htab = (struct elf_aarch64_link_hash_table *) in_arg;
3435 switch (stub_entry->stub_type)
3437 case aarch64_stub_adrp_branch:
3438 size = sizeof (aarch64_adrp_branch_stub);
3439 break;
3440 case aarch64_stub_long_branch:
3441 size = sizeof (aarch64_long_branch_stub);
3442 break;
3443 case aarch64_stub_bti_direct_branch:
3444 size = sizeof (aarch64_bti_direct_branch_stub);
3445 break;
3446 case aarch64_stub_erratum_835769_veneer:
3447 size = sizeof (aarch64_erratum_835769_stub);
3448 break;
3449 case aarch64_stub_erratum_843419_veneer:
3451 if (htab->fix_erratum_843419 == ERRAT_ADR)
3452 return true;
3453 size = sizeof (aarch64_erratum_843419_stub);
3455 break;
3456 default:
3457 abort ();
3460 size = (size + 7) & ~7;
3461 stub_entry->stub_offset = stub_entry->stub_sec->size;
3462 stub_entry->stub_sec->size += size;
3463 return true;
3466 /* Output is BTI compatible. */
3468 static bool
3469 elf_aarch64_bti_p (bfd *output_bfd)
3471 uint32_t prop = elf_aarch64_tdata (output_bfd)->gnu_and_prop;
3472 return prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
3475 /* External entry points for sizing and building linker stubs. */
3477 /* Set up various things so that we can make a list of input sections
3478 for each output section included in the link. Returns -1 on error,
3479 0 when no stubs will be needed, and 1 on success. */
3482 elfNN_aarch64_setup_section_lists (bfd *output_bfd,
3483 struct bfd_link_info *info)
3485 bfd *input_bfd;
3486 unsigned int bfd_count;
3487 unsigned int top_id, top_index;
3488 asection *section;
3489 asection **input_list, **list;
3490 size_t amt;
3491 struct elf_aarch64_link_hash_table *htab =
3492 elf_aarch64_hash_table (info);
3494 if (!is_elf_hash_table (&htab->root.root))
3495 return 0;
3497 /* Count the number of input BFDs and find the top input section id. */
3498 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
3499 input_bfd != NULL; input_bfd = input_bfd->link.next)
3501 bfd_count += 1;
3502 for (section = input_bfd->sections;
3503 section != NULL; section = section->next)
3505 if (top_id < section->id)
3506 top_id = section->id;
3509 htab->bfd_count = bfd_count;
3511 amt = sizeof (struct map_stub) * (top_id + 1);
3512 htab->stub_group = bfd_zmalloc (amt);
3513 if (htab->stub_group == NULL)
3514 return -1;
3516 /* We can't use output_bfd->section_count here to find the top output
3517 section index as some sections may have been removed, and
3518 _bfd_strip_section_from_output doesn't renumber the indices. */
3519 for (section = output_bfd->sections, top_index = 0;
3520 section != NULL; section = section->next)
3522 if (top_index < section->index)
3523 top_index = section->index;
3526 htab->top_index = top_index;
3527 amt = sizeof (asection *) * (top_index + 1);
3528 input_list = bfd_malloc (amt);
3529 htab->input_list = input_list;
3530 if (input_list == NULL)
3531 return -1;
3533 /* For sections we aren't interested in, mark their entries with a
3534 value we can check later. */
3535 list = input_list + top_index;
3537 *list = bfd_abs_section_ptr;
3538 while (list-- != input_list);
3540 for (section = output_bfd->sections;
3541 section != NULL; section = section->next)
3543 if ((section->flags & SEC_CODE) != 0)
3544 input_list[section->index] = NULL;
3547 return 1;
3550 /* Used by elfNN_aarch64_next_input_section and group_sections. */
3551 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
3553 /* The linker repeatedly calls this function for each input section,
3554 in the order that input sections are linked into output sections.
3555 Build lists of input sections to determine groupings between which
3556 we may insert linker stubs. */
3558 void
3559 elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec)
3561 struct elf_aarch64_link_hash_table *htab =
3562 elf_aarch64_hash_table (info);
3564 if (isec->output_section->index <= htab->top_index)
3566 asection **list = htab->input_list + isec->output_section->index;
3568 if (*list != bfd_abs_section_ptr && (isec->flags & SEC_CODE) != 0)
3570 /* Steal the link_sec pointer for our list. */
3571 /* This happens to make the list in reverse order,
3572 which is what we want. */
3573 PREV_SEC (isec) = *list;
3574 *list = isec;
3579 /* See whether we can group stub sections together. Grouping stub
3580 sections may result in fewer stubs. More importantly, we need to
3581 put all .init* and .fini* stubs at the beginning of the .init or
3582 .fini output sections respectively, because glibc splits the
3583 _init and _fini functions into multiple parts. Putting a stub in
3584 the middle of a function is not a good idea. */
3586 static void
3587 group_sections (struct elf_aarch64_link_hash_table *htab,
3588 bfd_size_type stub_group_size,
3589 bool stubs_always_after_branch)
3591 asection **list = htab->input_list;
3595 asection *tail = *list;
3596 asection *head;
3598 if (tail == bfd_abs_section_ptr)
3599 continue;
3601 /* Reverse the list: we must avoid placing stubs at the
3602 beginning of the section because the beginning of the text
3603 section may be required for an interrupt vector in bare metal
3604 code. */
3605 #define NEXT_SEC PREV_SEC
3606 head = NULL;
3607 while (tail != NULL)
3609 /* Pop from tail. */
3610 asection *item = tail;
3611 tail = PREV_SEC (item);
3613 /* Push on head. */
3614 NEXT_SEC (item) = head;
3615 head = item;
3618 while (head != NULL)
3620 asection *curr;
3621 asection *next;
3622 bfd_vma stub_group_start = head->output_offset;
3623 bfd_vma end_of_next;
3625 curr = head;
3626 while (NEXT_SEC (curr) != NULL)
3628 next = NEXT_SEC (curr);
3629 end_of_next = next->output_offset + next->size;
3630 if (end_of_next - stub_group_start >= stub_group_size)
3631 /* End of NEXT is too far from start, so stop. */
3632 break;
3633 /* Add NEXT to the group. */
3634 curr = next;
3637 /* OK, the size from the start to the start of CURR is less
3638 than stub_group_size and thus can be handled by one stub
3639 section. (Or the head section is itself larger than
3640 stub_group_size, in which case we may be toast.)
3641 We should really be keeping track of the total size of
3642 stubs added here, as stubs contribute to the final output
3643 section size. */
3646 next = NEXT_SEC (head);
3647 /* Set up this stub group. */
3648 htab->stub_group[head->id].link_sec = curr;
3650 while (head != curr && (head = next) != NULL);
3652 /* But wait, there's more! Input sections up to stub_group_size
3653 bytes after the stub section can be handled by it too. */
3654 if (!stubs_always_after_branch)
3656 stub_group_start = curr->output_offset + curr->size;
3658 while (next != NULL)
3660 end_of_next = next->output_offset + next->size;
3661 if (end_of_next - stub_group_start >= stub_group_size)
3662 /* End of NEXT is too far from stubs, so stop. */
3663 break;
3664 /* Add NEXT to the stub group. */
3665 head = next;
3666 next = NEXT_SEC (head);
3667 htab->stub_group[head->id].link_sec = curr;
3670 head = next;
3673 while (list++ != htab->input_list + htab->top_index);
3675 free (htab->input_list);
3678 #undef PREV_SEC
3679 #undef PREV_SEC
3681 #define AARCH64_HINT(insn) (((insn) & 0xfffff01f) == 0xd503201f)
3682 #define AARCH64_PACIASP 0xd503233f
3683 #define AARCH64_PACIBSP 0xd503237f
3684 #define AARCH64_BTI_C 0xd503245f
3685 #define AARCH64_BTI_J 0xd503249f
3686 #define AARCH64_BTI_JC 0xd50324df
3688 /* True if the inserted stub does not break BTI compatibility. */
3690 static bool
3691 aarch64_bti_stub_p (struct bfd_link_info *info,
3692 struct elf_aarch64_stub_hash_entry *stub_entry)
3694 /* Stubs without indirect branch are BTI compatible. */
3695 if (stub_entry->stub_type != aarch64_stub_adrp_branch
3696 && stub_entry->stub_type != aarch64_stub_long_branch)
3697 return true;
3699 /* Return true if the target instruction is compatible with BR x16. */
3701 struct elf_aarch64_link_hash_table *globals = elf_aarch64_hash_table (info);
3702 asection *section = stub_entry->target_section;
3703 bfd_byte loc[4];
3704 file_ptr off = stub_entry->target_value;
3705 bfd_size_type count = sizeof (loc);
3707 /* PLT code is not generated yet, so treat it specially.
3708 Note: Checking elf_aarch64_obj_tdata.plt_type & PLT_BTI is not
3709 enough because it only implies BTI in the PLT0 and tlsdesc PLT
3710 entries. Normal PLT entries don't have BTI in a shared library
3711 (because such PLT is normally not called indirectly and adding
3712 the BTI when a stub targets a PLT would change the PLT layout
3713 and it's too late for that here). */
3714 if (section == globals->root.splt)
3715 memcpy (loc, globals->plt_entry, count);
3716 else if (!bfd_get_section_contents (section->owner, section, loc, off, count))
3717 return false;
3719 uint32_t insn = bfd_getl32 (loc);
3720 if (!AARCH64_HINT (insn))
3721 return false;
3722 return insn == AARCH64_BTI_C
3723 || insn == AARCH64_PACIASP
3724 || insn == AARCH64_BTI_JC
3725 || insn == AARCH64_BTI_J
3726 || insn == AARCH64_PACIBSP;
3729 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
3731 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
3732 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
3733 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
3734 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
3735 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
3736 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
3738 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
3739 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
3740 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
3741 #define AARCH64_ZR 0x1f
3743 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
3744 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
3746 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
3747 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
3748 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
3749 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
3750 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
3751 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
3752 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
3753 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
3754 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
3755 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
3756 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
3757 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
3758 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
3759 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
3760 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
3761 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
3762 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
3763 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
3765 /* Classify an INSN if it is indeed a load/store.
3767 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
3769 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
3770 is set equal to RT.
3772 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned. */
3774 static bool
3775 aarch64_mem_op_p (uint32_t insn, unsigned int *rt, unsigned int *rt2,
3776 bool *pair, bool *load)
3778 uint32_t opcode;
3779 unsigned int r;
3780 uint32_t opc = 0;
3781 uint32_t v = 0;
3782 uint32_t opc_v = 0;
3784 /* Bail out quickly if INSN doesn't fall into the load-store
3785 encoding space. */
3786 if (!AARCH64_LDST (insn))
3787 return false;
3789 *pair = false;
3790 *load = false;
3791 if (AARCH64_LDST_EX (insn))
3793 *rt = AARCH64_RT (insn);
3794 *rt2 = *rt;
3795 if (AARCH64_BIT (insn, 21) == 1)
3797 *pair = true;
3798 *rt2 = AARCH64_RT2 (insn);
3800 *load = AARCH64_LD (insn);
3801 return true;
3803 else if (AARCH64_LDST_NAP (insn)
3804 || AARCH64_LDSTP_PI (insn)
3805 || AARCH64_LDSTP_O (insn)
3806 || AARCH64_LDSTP_PRE (insn))
3808 *pair = true;
3809 *rt = AARCH64_RT (insn);
3810 *rt2 = AARCH64_RT2 (insn);
3811 *load = AARCH64_LD (insn);
3812 return true;
3814 else if (AARCH64_LDST_PCREL (insn)
3815 || AARCH64_LDST_UI (insn)
3816 || AARCH64_LDST_PIIMM (insn)
3817 || AARCH64_LDST_U (insn)
3818 || AARCH64_LDST_PREIMM (insn)
3819 || AARCH64_LDST_RO (insn)
3820 || AARCH64_LDST_UIMM (insn))
3822 *rt = AARCH64_RT (insn);
3823 *rt2 = *rt;
3824 if (AARCH64_LDST_PCREL (insn))
3825 *load = true;
3826 opc = AARCH64_BITS (insn, 22, 2);
3827 v = AARCH64_BIT (insn, 26);
3828 opc_v = opc | (v << 2);
3829 *load = (opc_v == 1 || opc_v == 2 || opc_v == 3
3830 || opc_v == 5 || opc_v == 7);
3831 return true;
3833 else if (AARCH64_LDST_SIMD_M (insn)
3834 || AARCH64_LDST_SIMD_M_PI (insn))
3836 *rt = AARCH64_RT (insn);
3837 *load = AARCH64_BIT (insn, 22);
3838 opcode = (insn >> 12) & 0xf;
3839 switch (opcode)
3841 case 0:
3842 case 2:
3843 *rt2 = *rt + 3;
3844 break;
3846 case 4:
3847 case 6:
3848 *rt2 = *rt + 2;
3849 break;
3851 case 7:
3852 *rt2 = *rt;
3853 break;
3855 case 8:
3856 case 10:
3857 *rt2 = *rt + 1;
3858 break;
3860 default:
3861 return false;
3863 return true;
3865 else if (AARCH64_LDST_SIMD_S (insn)
3866 || AARCH64_LDST_SIMD_S_PI (insn))
3868 *rt = AARCH64_RT (insn);
3869 r = (insn >> 21) & 1;
3870 *load = AARCH64_BIT (insn, 22);
3871 opcode = (insn >> 13) & 0x7;
3872 switch (opcode)
3874 case 0:
3875 case 2:
3876 case 4:
3877 *rt2 = *rt + r;
3878 break;
3880 case 1:
3881 case 3:
3882 case 5:
3883 *rt2 = *rt + (r == 0 ? 2 : 3);
3884 break;
3886 case 6:
3887 *rt2 = *rt + r;
3888 break;
3890 case 7:
3891 *rt2 = *rt + (r == 0 ? 2 : 3);
3892 break;
3894 default:
3895 return false;
3897 return true;
3900 return false;
3903 /* Return TRUE if INSN is multiply-accumulate. */
3905 static bool
3906 aarch64_mlxl_p (uint32_t insn)
3908 uint32_t op31 = AARCH64_OP31 (insn);
3910 if (AARCH64_MAC (insn)
3911 && (op31 == 0 || op31 == 1 || op31 == 5)
3912 /* Exclude MUL instructions which are encoded as a multiple accumulate
3913 with RA = XZR. */
3914 && AARCH64_RA (insn) != AARCH64_ZR)
3915 return true;
3917 return false;
3920 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3921 it is possible for a 64-bit multiply-accumulate instruction to generate an
3922 incorrect result. The details are quite complex and hard to
3923 determine statically, since branches in the code may exist in some
3924 circumstances, but all cases end with a memory (load, store, or
3925 prefetch) instruction followed immediately by the multiply-accumulate
3926 operation. We employ a linker patching technique, by moving the potentially
3927 affected multiply-accumulate instruction into a patch region and replacing
3928 the original instruction with a branch to the patch. This function checks
3929 if INSN_1 is the memory operation followed by a multiply-accumulate
3930 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3931 if INSN_1 and INSN_2 are safe. */
3933 static bool
3934 aarch64_erratum_sequence (uint32_t insn_1, uint32_t insn_2)
3936 uint32_t rt;
3937 uint32_t rt2;
3938 uint32_t rn;
3939 uint32_t rm;
3940 uint32_t ra;
3941 bool pair;
3942 bool load;
3944 if (aarch64_mlxl_p (insn_2)
3945 && aarch64_mem_op_p (insn_1, &rt, &rt2, &pair, &load))
3947 /* Any SIMD memory op is independent of the subsequent MLA
3948 by definition of the erratum. */
3949 if (AARCH64_BIT (insn_1, 26))
3950 return true;
3952 /* If not SIMD, check for integer memory ops and MLA relationship. */
3953 rn = AARCH64_RN (insn_2);
3954 ra = AARCH64_RA (insn_2);
3955 rm = AARCH64_RM (insn_2);
3957 /* If this is a load and there's a true(RAW) dependency, we are safe
3958 and this is not an erratum sequence. */
3959 if (load &&
3960 (rt == rn || rt == rm || rt == ra
3961 || (pair && (rt2 == rn || rt2 == rm || rt2 == ra))))
3962 return false;
3964 /* We conservatively put out stubs for all other cases (including
3965 writebacks). */
3966 return true;
3969 return false;
3972 /* Used to order a list of mapping symbols by address. */
3974 static int
3975 elf_aarch64_compare_mapping (const void *a, const void *b)
3977 const elf_aarch64_section_map *amap = (const elf_aarch64_section_map *) a;
3978 const elf_aarch64_section_map *bmap = (const elf_aarch64_section_map *) b;
3980 if (amap->vma > bmap->vma)
3981 return 1;
3982 else if (amap->vma < bmap->vma)
3983 return -1;
3984 else if (amap->type > bmap->type)
3985 /* Ensure results do not depend on the host qsort for objects with
3986 multiple mapping symbols at the same address by sorting on type
3987 after vma. */
3988 return 1;
3989 else if (amap->type < bmap->type)
3990 return -1;
3991 else
3992 return 0;
3996 static char *
3997 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes)
3999 char *stub_name = (char *) bfd_malloc
4000 (strlen ("__erratum_835769_veneer_") + 16);
4001 if (stub_name != NULL)
4002 sprintf (stub_name,"__erratum_835769_veneer_%d", num_fixes);
4003 return stub_name;
4006 /* Scan for Cortex-A53 erratum 835769 sequence.
4008 Return TRUE else FALSE on abnormal termination. */
4010 static bool
4011 _bfd_aarch64_erratum_835769_scan (bfd *input_bfd,
4012 struct bfd_link_info *info,
4013 unsigned int *num_fixes_p)
4015 asection *section;
4016 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
4017 unsigned int num_fixes = *num_fixes_p;
4019 if (htab == NULL)
4020 return true;
4022 for (section = input_bfd->sections;
4023 section != NULL;
4024 section = section->next)
4026 bfd_byte *contents = NULL;
4027 struct _aarch64_elf_section_data *sec_data;
4028 unsigned int span;
4030 if (elf_section_type (section) != SHT_PROGBITS
4031 || (elf_section_flags (section) & SHF_EXECINSTR) == 0
4032 || (section->flags & SEC_EXCLUDE) != 0
4033 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
4034 || (section->output_section == bfd_abs_section_ptr))
4035 continue;
4037 if (elf_section_data (section)->this_hdr.contents != NULL)
4038 contents = elf_section_data (section)->this_hdr.contents;
4039 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
4040 return false;
4042 sec_data = elf_aarch64_section_data (section);
4044 if (sec_data->mapcount)
4045 qsort (sec_data->map, sec_data->mapcount,
4046 sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
4048 for (span = 0; span < sec_data->mapcount; span++)
4050 unsigned int span_start = sec_data->map[span].vma;
4051 unsigned int span_end = ((span == sec_data->mapcount - 1)
4052 ? sec_data->map[0].vma + section->size
4053 : sec_data->map[span + 1].vma);
4054 unsigned int i;
4055 char span_type = sec_data->map[span].type;
4057 if (span_type == 'd')
4058 continue;
4060 for (i = span_start; i + 4 < span_end; i += 4)
4062 uint32_t insn_1 = bfd_getl32 (contents + i);
4063 uint32_t insn_2 = bfd_getl32 (contents + i + 4);
4065 if (aarch64_erratum_sequence (insn_1, insn_2))
4067 struct elf_aarch64_stub_hash_entry *stub_entry;
4068 char *stub_name = _bfd_aarch64_erratum_835769_stub_name (num_fixes);
4069 if (! stub_name)
4070 return false;
4072 stub_entry = _bfd_aarch64_add_stub_entry_in_group (stub_name,
4073 section,
4074 htab);
4075 if (! stub_entry)
4076 return false;
4078 stub_entry->stub_type = aarch64_stub_erratum_835769_veneer;
4079 stub_entry->target_section = section;
4080 stub_entry->target_value = i + 4;
4081 stub_entry->veneered_insn = insn_2;
4082 stub_entry->output_name = stub_name;
4083 num_fixes++;
4087 if (elf_section_data (section)->this_hdr.contents == NULL)
4088 free (contents);
4091 *num_fixes_p = num_fixes;
4093 return true;
4097 /* Test if instruction INSN is ADRP. */
4099 static bool
4100 _bfd_aarch64_adrp_p (uint32_t insn)
4102 return ((insn & AARCH64_ADRP_OP_MASK) == AARCH64_ADRP_OP);
4106 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
4108 static bool
4109 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1, uint32_t insn_2,
4110 uint32_t insn_3)
4112 uint32_t rt;
4113 uint32_t rt2;
4114 bool pair;
4115 bool load;
4117 return (aarch64_mem_op_p (insn_2, &rt, &rt2, &pair, &load)
4118 && (!pair
4119 || (pair && !load))
4120 && AARCH64_LDST_UIMM (insn_3)
4121 && AARCH64_RN (insn_3) == AARCH64_RD (insn_1));
4125 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
4127 Return TRUE if section CONTENTS at offset I contains one of the
4128 erratum 843419 sequences, otherwise return FALSE. If a sequence is
4129 seen set P_VENEER_I to the offset of the final LOAD/STORE
4130 instruction in the sequence.
4133 static bool
4134 _bfd_aarch64_erratum_843419_p (bfd_byte *contents, bfd_vma vma,
4135 bfd_vma i, bfd_vma span_end,
4136 bfd_vma *p_veneer_i)
4138 uint32_t insn_1 = bfd_getl32 (contents + i);
4140 if (!_bfd_aarch64_adrp_p (insn_1))
4141 return false;
4143 if (span_end < i + 12)
4144 return false;
4146 uint32_t insn_2 = bfd_getl32 (contents + i + 4);
4147 uint32_t insn_3 = bfd_getl32 (contents + i + 8);
4149 if ((vma & 0xfff) != 0xff8 && (vma & 0xfff) != 0xffc)
4150 return false;
4152 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1, insn_2, insn_3))
4154 *p_veneer_i = i + 8;
4155 return true;
4158 if (span_end < i + 16)
4159 return false;
4161 uint32_t insn_4 = bfd_getl32 (contents + i + 12);
4163 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1, insn_2, insn_4))
4165 *p_veneer_i = i + 12;
4166 return true;
4169 return false;
4173 /* Resize all stub sections. */
4175 static void
4176 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table *htab)
4178 asection *section;
4180 /* OK, we've added some stubs. Find out the new size of the
4181 stub sections. */
4182 for (section = htab->stub_bfd->sections;
4183 section != NULL; section = section->next)
4185 /* Ignore non-stub sections. */
4186 if (!strstr (section->name, STUB_SUFFIX))
4187 continue;
4189 /* Add space for a branch. Add 8 bytes to keep section 8 byte aligned,
4190 as long branch stubs contain a 64-bit address. */
4191 section->size = 8;
4194 bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
4196 for (section = htab->stub_bfd->sections;
4197 section != NULL; section = section->next)
4199 if (!strstr (section->name, STUB_SUFFIX))
4200 continue;
4202 /* Empty stub section. */
4203 if (section->size == 8)
4204 section->size = 0;
4206 /* Ensure all stub sections have a size which is a multiple of
4207 4096. This is important in order to ensure that the insertion
4208 of stub sections does not in itself move existing code around
4209 in such a way that new errata sequences are created. We only do this
4210 when the ADRP workaround is enabled. If only the ADR workaround is
4211 enabled then the stubs workaround won't ever be used. */
4212 if (htab->fix_erratum_843419 & ERRAT_ADRP)
4213 if (section->size)
4214 section->size = BFD_ALIGN (section->size, 0x1000);
4218 /* Construct an erratum 843419 workaround stub name. */
4220 static char *
4221 _bfd_aarch64_erratum_843419_stub_name (asection *input_section,
4222 bfd_vma offset)
4224 const bfd_size_type len = 8 + 4 + 1 + 8 + 1 + 16 + 1;
4225 char *stub_name = bfd_malloc (len);
4227 if (stub_name != NULL)
4228 snprintf (stub_name, len, "e843419@%04x_%08x_%" PRIx64,
4229 input_section->owner->id,
4230 input_section->id,
4231 (uint64_t) offset);
4232 return stub_name;
4235 /* Build a stub_entry structure describing an 843419 fixup.
4237 The stub_entry constructed is populated with the bit pattern INSN
4238 of the instruction located at OFFSET within input SECTION.
4240 Returns TRUE on success. */
4242 static bool
4243 _bfd_aarch64_erratum_843419_fixup (uint32_t insn,
4244 bfd_vma adrp_offset,
4245 bfd_vma ldst_offset,
4246 asection *section,
4247 struct bfd_link_info *info)
4249 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
4250 char *stub_name;
4251 struct elf_aarch64_stub_hash_entry *stub_entry;
4253 stub_name = _bfd_aarch64_erratum_843419_stub_name (section, ldst_offset);
4254 if (stub_name == NULL)
4255 return false;
4256 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
4257 false, false);
4258 if (stub_entry)
4260 free (stub_name);
4261 return true;
4264 /* We always place an 843419 workaround veneer in the stub section
4265 attached to the input section in which an erratum sequence has
4266 been found. This ensures that later in the link process (in
4267 elfNN_aarch64_write_section) when we copy the veneered
4268 instruction from the input section into the stub section the
4269 copied instruction will have had any relocations applied to it.
4270 If we placed workaround veneers in any other stub section then we
4271 could not assume that all relocations have been processed on the
4272 corresponding input section at the point we output the stub
4273 section. */
4275 stub_entry = _bfd_aarch64_add_stub_entry_after (stub_name, section, htab);
4276 if (stub_entry == NULL)
4278 free (stub_name);
4279 return false;
4282 stub_entry->adrp_offset = adrp_offset;
4283 stub_entry->target_value = ldst_offset;
4284 stub_entry->target_section = section;
4285 stub_entry->stub_type = aarch64_stub_erratum_843419_veneer;
4286 stub_entry->veneered_insn = insn;
4287 stub_entry->output_name = stub_name;
4289 return true;
4293 /* Scan an input section looking for the signature of erratum 843419.
4295 Scans input SECTION in INPUT_BFD looking for erratum 843419
4296 signatures, for each signature found a stub_entry is created
4297 describing the location of the erratum for subsequent fixup.
4299 Return TRUE on successful scan, FALSE on failure to scan.
4302 static bool
4303 _bfd_aarch64_erratum_843419_scan (bfd *input_bfd, asection *section,
4304 struct bfd_link_info *info)
4306 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
4308 if (htab == NULL)
4309 return true;
4311 if (elf_section_type (section) != SHT_PROGBITS
4312 || (elf_section_flags (section) & SHF_EXECINSTR) == 0
4313 || (section->flags & SEC_EXCLUDE) != 0
4314 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
4315 || (section->output_section == bfd_abs_section_ptr))
4316 return true;
4320 bfd_byte *contents = NULL;
4321 struct _aarch64_elf_section_data *sec_data;
4322 unsigned int span;
4324 if (elf_section_data (section)->this_hdr.contents != NULL)
4325 contents = elf_section_data (section)->this_hdr.contents;
4326 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
4327 return false;
4329 sec_data = elf_aarch64_section_data (section);
4331 if (sec_data->mapcount)
4332 qsort (sec_data->map, sec_data->mapcount,
4333 sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
4335 for (span = 0; span < sec_data->mapcount; span++)
4337 unsigned int span_start = sec_data->map[span].vma;
4338 unsigned int span_end = ((span == sec_data->mapcount - 1)
4339 ? sec_data->map[0].vma + section->size
4340 : sec_data->map[span + 1].vma);
4341 unsigned int i;
4342 char span_type = sec_data->map[span].type;
4344 if (span_type == 'd')
4345 continue;
4347 for (i = span_start; i + 8 < span_end; i += 4)
4349 bfd_vma vma = (section->output_section->vma
4350 + section->output_offset
4351 + i);
4352 bfd_vma veneer_i;
4354 if (_bfd_aarch64_erratum_843419_p
4355 (contents, vma, i, span_end, &veneer_i))
4357 uint32_t insn = bfd_getl32 (contents + veneer_i);
4359 if (!_bfd_aarch64_erratum_843419_fixup (insn, i, veneer_i,
4360 section, info))
4361 return false;
4366 if (elf_section_data (section)->this_hdr.contents == NULL)
4367 free (contents);
4369 while (0);
4371 return true;
4375 /* Add stub entries for calls.
4377 The basic idea here is to examine all the relocations looking for
4378 PC-relative calls to a target that is unreachable with a "bl"
4379 instruction. */
4381 static bool
4382 _bfd_aarch64_add_call_stub_entries (bool *stub_changed, bfd *output_bfd,
4383 struct bfd_link_info *info)
4385 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
4386 bool need_bti = elf_aarch64_bti_p (output_bfd);
4387 bfd *input_bfd;
4389 for (input_bfd = info->input_bfds; input_bfd != NULL;
4390 input_bfd = input_bfd->link.next)
4392 Elf_Internal_Shdr *symtab_hdr;
4393 asection *section;
4394 Elf_Internal_Sym *local_syms = NULL;
4396 if (!is_aarch64_elf (input_bfd)
4397 || (input_bfd->flags & BFD_LINKER_CREATED) != 0)
4398 continue;
4400 /* We'll need the symbol table in a second. */
4401 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4402 if (symtab_hdr->sh_info == 0)
4403 continue;
4405 /* Walk over each section attached to the input bfd. */
4406 for (section = input_bfd->sections;
4407 section != NULL; section = section->next)
4409 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
4411 /* If there aren't any relocs, then there's nothing more to do. */
4412 if ((section->flags & SEC_RELOC) == 0
4413 || section->reloc_count == 0
4414 || (section->flags & SEC_CODE) == 0)
4415 continue;
4417 /* If this section is a link-once section that will be
4418 discarded, then don't create any stubs. */
4419 if (section->output_section == NULL
4420 || section->output_section->owner != output_bfd)
4421 continue;
4423 /* Get the relocs. */
4424 internal_relocs
4425 = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
4426 NULL, info->keep_memory);
4427 if (internal_relocs == NULL)
4428 goto error_ret_free_local;
4430 /* Now examine each relocation. */
4431 irela = internal_relocs;
4432 irelaend = irela + section->reloc_count;
4433 for (; irela < irelaend; irela++)
4435 unsigned int r_type, r_indx;
4436 enum elf_aarch64_stub_type stub_type;
4437 struct elf_aarch64_stub_hash_entry *stub_entry;
4438 struct elf_aarch64_stub_hash_entry *stub_entry_bti;
4439 asection *sym_sec;
4440 bfd_vma sym_value;
4441 bfd_vma destination;
4442 struct elf_aarch64_link_hash_entry *hash;
4443 const char *sym_name;
4444 char *stub_name;
4445 char *stub_name_bti;
4446 const asection *id_sec;
4447 const asection *id_sec_bti;
4448 unsigned char st_type;
4449 bfd_size_type len;
4451 r_type = ELFNN_R_TYPE (irela->r_info);
4452 r_indx = ELFNN_R_SYM (irela->r_info);
4454 if (r_type >= (unsigned int) R_AARCH64_end)
4456 bfd_set_error (bfd_error_bad_value);
4457 error_ret_free_internal:
4458 if (elf_section_data (section)->relocs == NULL)
4459 free (internal_relocs);
4460 goto error_ret_free_local;
4463 /* Only look for stubs on unconditional branch and
4464 branch and link instructions. */
4465 if (r_type != (unsigned int) AARCH64_R (CALL26)
4466 && r_type != (unsigned int) AARCH64_R (JUMP26))
4467 continue;
4469 /* Now determine the call target, its name, value,
4470 section. */
4471 sym_sec = NULL;
4472 sym_value = 0;
4473 destination = 0;
4474 hash = NULL;
4475 sym_name = NULL;
4476 if (r_indx < symtab_hdr->sh_info)
4478 /* It's a local symbol. */
4479 Elf_Internal_Sym *sym;
4480 Elf_Internal_Shdr *hdr;
4482 if (local_syms == NULL)
4484 local_syms
4485 = (Elf_Internal_Sym *) symtab_hdr->contents;
4486 if (local_syms == NULL)
4487 local_syms
4488 = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
4489 symtab_hdr->sh_info, 0,
4490 NULL, NULL, NULL);
4491 if (local_syms == NULL)
4492 goto error_ret_free_internal;
4495 sym = local_syms + r_indx;
4496 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
4497 sym_sec = hdr->bfd_section;
4498 if (!sym_sec)
4499 /* This is an undefined symbol. It can never
4500 be resolved. */
4501 continue;
4503 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
4504 sym_value = sym->st_value;
4505 destination = (sym_value + irela->r_addend
4506 + sym_sec->output_offset
4507 + sym_sec->output_section->vma);
4508 st_type = ELF_ST_TYPE (sym->st_info);
4509 sym_name
4510 = bfd_elf_string_from_elf_section (input_bfd,
4511 symtab_hdr->sh_link,
4512 sym->st_name);
4514 else
4516 int e_indx;
4518 e_indx = r_indx - symtab_hdr->sh_info;
4519 hash = ((struct elf_aarch64_link_hash_entry *)
4520 elf_sym_hashes (input_bfd)[e_indx]);
4522 while (hash->root.root.type == bfd_link_hash_indirect
4523 || hash->root.root.type == bfd_link_hash_warning)
4524 hash = ((struct elf_aarch64_link_hash_entry *)
4525 hash->root.root.u.i.link);
4527 if (hash->root.root.type == bfd_link_hash_defined
4528 || hash->root.root.type == bfd_link_hash_defweak)
4530 struct elf_aarch64_link_hash_table *globals =
4531 elf_aarch64_hash_table (info);
4532 sym_sec = hash->root.root.u.def.section;
4533 sym_value = hash->root.root.u.def.value;
4534 /* For a destination in a shared library,
4535 use the PLT stub as target address to
4536 decide whether a branch stub is
4537 needed. */
4538 if (globals->root.splt != NULL && hash != NULL
4539 && hash->root.plt.offset != (bfd_vma) - 1)
4541 sym_sec = globals->root.splt;
4542 sym_value = hash->root.plt.offset;
4543 if (sym_sec->output_section != NULL)
4544 destination = (sym_value
4545 + sym_sec->output_offset
4546 + sym_sec->output_section->vma);
4548 else if (sym_sec->output_section != NULL)
4549 destination = (sym_value + irela->r_addend
4550 + sym_sec->output_offset
4551 + sym_sec->output_section->vma);
4553 else if (hash->root.root.type == bfd_link_hash_undefined
4554 || (hash->root.root.type
4555 == bfd_link_hash_undefweak))
4557 /* For a shared library, use the PLT stub as
4558 target address to decide whether a long
4559 branch stub is needed.
4560 For absolute code, they cannot be handled. */
4561 struct elf_aarch64_link_hash_table *globals =
4562 elf_aarch64_hash_table (info);
4564 if (globals->root.splt != NULL && hash != NULL
4565 && hash->root.plt.offset != (bfd_vma) - 1)
4567 sym_sec = globals->root.splt;
4568 sym_value = hash->root.plt.offset;
4569 if (sym_sec->output_section != NULL)
4570 destination = (sym_value
4571 + sym_sec->output_offset
4572 + sym_sec->output_section->vma);
4574 else
4575 continue;
4577 else
4579 bfd_set_error (bfd_error_bad_value);
4580 goto error_ret_free_internal;
4582 st_type = ELF_ST_TYPE (hash->root.type);
4583 sym_name = hash->root.root.root.string;
4586 /* Determine what (if any) linker stub is needed. */
4587 stub_type = aarch64_type_of_stub (section, irela, sym_sec,
4588 st_type, destination);
4589 if (stub_type == aarch64_stub_none)
4590 continue;
4592 /* Support for grouping stub sections. */
4593 id_sec = htab->stub_group[section->id].link_sec;
4595 /* Get the name of this stub. */
4596 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash,
4597 irela);
4598 if (!stub_name)
4599 goto error_ret_free_internal;
4601 stub_entry =
4602 aarch64_stub_hash_lookup (&htab->stub_hash_table,
4603 stub_name, false, false);
4604 if (stub_entry != NULL)
4606 /* The proper stub has already been created. */
4607 free (stub_name);
4609 /* Always update this stub's target since it may have
4610 changed after layout. */
4611 stub_entry->target_value = sym_value + irela->r_addend;
4613 if (stub_entry->double_stub)
4615 /* Update the target of both stubs. */
4617 id_sec_bti = htab->stub_group[sym_sec->id].link_sec;
4618 stub_name_bti =
4619 elfNN_aarch64_stub_name (id_sec_bti, sym_sec, hash,
4620 irela);
4621 if (!stub_name_bti)
4622 goto error_ret_free_internal;
4623 stub_entry_bti =
4624 aarch64_stub_hash_lookup (&htab->stub_hash_table,
4625 stub_name_bti, false, false);
4626 BFD_ASSERT (stub_entry_bti != NULL);
4627 free (stub_name_bti);
4628 stub_entry_bti->target_value = stub_entry->target_value;
4629 stub_entry->target_value = stub_entry_bti->stub_offset;
4631 continue;
4634 stub_entry = _bfd_aarch64_add_stub_entry_in_group
4635 (stub_name, section, htab);
4636 if (stub_entry == NULL)
4638 free (stub_name);
4639 goto error_ret_free_internal;
4642 stub_entry->target_value = sym_value + irela->r_addend;
4643 stub_entry->target_section = sym_sec;
4644 stub_entry->stub_type = stub_type;
4645 stub_entry->h = hash;
4646 stub_entry->st_type = st_type;
4648 if (sym_name == NULL)
4649 sym_name = "unnamed";
4650 len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
4651 stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
4652 if (stub_entry->output_name == NULL)
4654 free (stub_name);
4655 goto error_ret_free_internal;
4658 snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
4659 sym_name);
4661 /* A stub with indirect jump may break BTI compatibility, so
4662 insert another stub with direct jump near the target then. */
4663 if (need_bti && !aarch64_bti_stub_p (info, stub_entry))
4665 id_sec_bti = htab->stub_group[sym_sec->id].link_sec;
4667 /* If the stub with indirect jump and the BTI stub are in
4668 the same stub group: change the indirect jump stub into
4669 a BTI stub since a direct branch can reach the target.
4670 The BTI landing pad is still needed in case another
4671 stub indirectly jumps to it. */
4672 if (id_sec_bti == id_sec)
4674 stub_entry->stub_type = aarch64_stub_bti_direct_branch;
4675 goto skip_double_stub;
4678 stub_entry->double_stub = true;
4679 htab->has_double_stub = true;
4681 stub_name_bti =
4682 elfNN_aarch64_stub_name (id_sec_bti, sym_sec, hash, irela);
4683 if (!stub_name_bti)
4685 free (stub_name);
4686 goto error_ret_free_internal;
4689 stub_entry_bti =
4690 aarch64_stub_hash_lookup (&htab->stub_hash_table,
4691 stub_name_bti, false, false);
4692 if (stub_entry_bti != NULL)
4693 BFD_ASSERT (stub_entry_bti->stub_type
4694 == aarch64_stub_bti_direct_branch);
4695 else
4697 stub_entry_bti =
4698 _bfd_aarch64_add_stub_entry_in_group (stub_name_bti,
4699 sym_sec, htab);
4700 if (stub_entry_bti == NULL)
4702 free (stub_name);
4703 free (stub_name_bti);
4704 goto error_ret_free_internal;
4707 stub_entry_bti->target_value =
4708 sym_value + irela->r_addend;
4709 stub_entry_bti->target_section = sym_sec;
4710 stub_entry_bti->stub_type =
4711 aarch64_stub_bti_direct_branch;
4712 stub_entry_bti->h = hash;
4713 stub_entry_bti->st_type = st_type;
4715 len = sizeof (BTI_STUB_ENTRY_NAME) + strlen (sym_name);
4716 stub_entry_bti->output_name = bfd_alloc (htab->stub_bfd,
4717 len);
4718 if (stub_entry_bti->output_name == NULL)
4720 free (stub_name);
4721 free (stub_name_bti);
4722 goto error_ret_free_internal;
4724 snprintf (stub_entry_bti->output_name, len,
4725 BTI_STUB_ENTRY_NAME, sym_name);
4728 /* Update the indirect call stub to target the BTI stub. */
4729 stub_entry->target_value = 0;
4730 stub_entry->target_section = stub_entry_bti->stub_sec;
4731 stub_entry->stub_type = stub_type;
4732 stub_entry->h = NULL;
4733 stub_entry->st_type = STT_FUNC;
4735 skip_double_stub:
4736 *stub_changed = true;
4739 /* We're done with the internal relocs, free them. */
4740 if (elf_section_data (section)->relocs == NULL)
4741 free (internal_relocs);
4744 return true;
4745 error_ret_free_local:
4746 return false;
4750 /* Determine and set the size of the stub section for a final link. */
4752 bool
4753 elfNN_aarch64_size_stubs (bfd *output_bfd,
4754 bfd *stub_bfd,
4755 struct bfd_link_info *info,
4756 bfd_signed_vma group_size,
4757 asection * (*add_stub_section) (const char *,
4758 asection *),
4759 void (*layout_sections_again) (void))
4761 bfd_size_type stub_group_size;
4762 bool stubs_always_before_branch;
4763 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
4764 unsigned int num_erratum_835769_fixes = 0;
4766 /* Propagate mach to stub bfd, because it may not have been
4767 finalized when we created stub_bfd. */
4768 bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
4769 bfd_get_mach (output_bfd));
4771 /* Stash our params away. */
4772 htab->stub_bfd = stub_bfd;
4773 htab->add_stub_section = add_stub_section;
4774 htab->layout_sections_again = layout_sections_again;
4775 stubs_always_before_branch = group_size < 0;
4776 if (group_size < 0)
4777 stub_group_size = -group_size;
4778 else
4779 stub_group_size = group_size;
4781 if (stub_group_size == 1)
4783 /* Default values. */
4784 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
4785 stub_group_size = 127 * 1024 * 1024;
4788 group_sections (htab, stub_group_size, stubs_always_before_branch);
4790 (*htab->layout_sections_again) ();
4792 if (htab->fix_erratum_835769)
4794 bfd *input_bfd;
4796 for (input_bfd = info->input_bfds;
4797 input_bfd != NULL; input_bfd = input_bfd->link.next)
4799 if (!is_aarch64_elf (input_bfd)
4800 || (input_bfd->flags & BFD_LINKER_CREATED) != 0)
4801 continue;
4803 if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info,
4804 &num_erratum_835769_fixes))
4805 return false;
4808 _bfd_aarch64_resize_stubs (htab);
4809 (*htab->layout_sections_again) ();
4812 if (htab->fix_erratum_843419 != ERRAT_NONE)
4814 bfd *input_bfd;
4816 for (input_bfd = info->input_bfds;
4817 input_bfd != NULL;
4818 input_bfd = input_bfd->link.next)
4820 asection *section;
4822 if (!is_aarch64_elf (input_bfd)
4823 || (input_bfd->flags & BFD_LINKER_CREATED) != 0)
4824 continue;
4826 for (section = input_bfd->sections;
4827 section != NULL;
4828 section = section->next)
4829 if (!_bfd_aarch64_erratum_843419_scan (input_bfd, section, info))
4830 return false;
4833 _bfd_aarch64_resize_stubs (htab);
4834 (*htab->layout_sections_again) ();
4837 for (;;)
4839 bool stub_changed = false;
4841 if (!_bfd_aarch64_add_call_stub_entries (&stub_changed, output_bfd, info))
4842 return false;
4844 if (!stub_changed)
4845 return true;
4847 _bfd_aarch64_resize_stubs (htab);
4848 (*htab->layout_sections_again) ();
4852 /* Build all the stubs associated with the current output file. The
4853 stubs are kept in a hash table attached to the main linker hash
4854 table. We also set up the .plt entries for statically linked PIC
4855 functions here. This function is called via aarch64_elf_finish in the
4856 linker. */
4858 bool
4859 elfNN_aarch64_build_stubs (struct bfd_link_info *info)
4861 asection *stub_sec;
4862 struct bfd_hash_table *table;
4863 struct elf_aarch64_link_hash_table *htab;
4865 htab = elf_aarch64_hash_table (info);
4867 for (stub_sec = htab->stub_bfd->sections;
4868 stub_sec != NULL; stub_sec = stub_sec->next)
4870 bfd_size_type size;
4872 /* Ignore non-stub sections. */
4873 if (!strstr (stub_sec->name, STUB_SUFFIX))
4874 continue;
4876 /* Allocate memory to hold the linker stubs. */
4877 size = stub_sec->size;
4878 stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
4879 if (stub_sec->contents == NULL && size != 0)
4880 return false;
4881 stub_sec->size = 0;
4883 /* Add a branch around the stub section, and a nop, to keep it 8 byte
4884 aligned, as long branch stubs contain a 64-bit address. */
4885 bfd_putl32 (0x14000000 | (size >> 2), stub_sec->contents);
4886 bfd_putl32 (INSN_NOP, stub_sec->contents + 4);
4887 stub_sec->size += 8;
4890 /* Build the stubs as directed by the stub hash table. */
4891 table = &htab->stub_hash_table;
4892 bfd_hash_traverse (table, aarch64_build_one_stub, info);
4894 return true;
4898 /* Add an entry to the code/data map for section SEC. */
4900 static void
4901 elfNN_aarch64_section_map_add (asection *sec, char type, bfd_vma vma)
4903 struct _aarch64_elf_section_data *sec_data =
4904 elf_aarch64_section_data (sec);
4905 unsigned int newidx;
4907 if (sec_data->map == NULL)
4909 sec_data->map = bfd_malloc (sizeof (elf_aarch64_section_map));
4910 sec_data->mapcount = 0;
4911 sec_data->mapsize = 1;
4914 newidx = sec_data->mapcount++;
4916 if (sec_data->mapcount > sec_data->mapsize)
4918 sec_data->mapsize *= 2;
4919 sec_data->map = bfd_realloc_or_free
4920 (sec_data->map, sec_data->mapsize * sizeof (elf_aarch64_section_map));
4923 if (sec_data->map)
4925 sec_data->map[newidx].vma = vma;
4926 sec_data->map[newidx].type = type;
4931 /* Initialise maps of insn/data for input BFDs. */
4932 void
4933 bfd_elfNN_aarch64_init_maps (bfd *abfd)
4935 Elf_Internal_Sym *isymbuf;
4936 Elf_Internal_Shdr *hdr;
4937 unsigned int i, localsyms;
4939 /* Make sure that we are dealing with an AArch64 elf binary. */
4940 if (!is_aarch64_elf (abfd))
4941 return;
4943 if ((abfd->flags & DYNAMIC) != 0)
4944 return;
4946 hdr = &elf_symtab_hdr (abfd);
4947 localsyms = hdr->sh_info;
4949 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
4950 should contain the number of local symbols, which should come before any
4951 global symbols. Mapping symbols are always local. */
4952 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL);
4954 /* No internal symbols read? Skip this BFD. */
4955 if (isymbuf == NULL)
4956 return;
4958 for (i = 0; i < localsyms; i++)
4960 Elf_Internal_Sym *isym = &isymbuf[i];
4961 asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
4962 const char *name;
4964 if (sec != NULL && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
4966 name = bfd_elf_string_from_elf_section (abfd,
4967 hdr->sh_link,
4968 isym->st_name);
4970 if (bfd_is_aarch64_special_symbol_name
4971 (name, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP))
4972 elfNN_aarch64_section_map_add (sec, name[1], isym->st_value);
4977 static void
4978 setup_plt_values (struct bfd_link_info *link_info,
4979 aarch64_plt_type plt_type)
4981 struct elf_aarch64_link_hash_table *globals;
4982 globals = elf_aarch64_hash_table (link_info);
4984 if (plt_type == PLT_BTI_PAC)
4986 globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
4988 /* Only in ET_EXEC we need PLTn with BTI. */
4989 if (bfd_link_pde (link_info))
4991 globals->plt_entry_size = PLT_BTI_PAC_SMALL_ENTRY_SIZE;
4992 globals->plt_entry = elfNN_aarch64_small_plt_bti_pac_entry;
4994 else
4996 globals->plt_entry_size = PLT_PAC_SMALL_ENTRY_SIZE;
4997 globals->plt_entry = elfNN_aarch64_small_plt_pac_entry;
5000 else if (plt_type == PLT_BTI)
5002 globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
5004 /* Only in ET_EXEC we need PLTn with BTI. */
5005 if (bfd_link_pde (link_info))
5007 globals->plt_entry_size = PLT_BTI_SMALL_ENTRY_SIZE;
5008 globals->plt_entry = elfNN_aarch64_small_plt_bti_entry;
5011 else if (plt_type == PLT_PAC)
5013 globals->plt_entry_size = PLT_PAC_SMALL_ENTRY_SIZE;
5014 globals->plt_entry = elfNN_aarch64_small_plt_pac_entry;
5018 /* Set option values needed during linking. */
5019 void
5020 bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
5021 struct bfd_link_info *link_info,
5022 int no_enum_warn,
5023 int no_wchar_warn, int pic_veneer,
5024 int fix_erratum_835769,
5025 erratum_84319_opts fix_erratum_843419,
5026 int no_apply_dynamic_relocs,
5027 aarch64_bti_pac_info bp_info)
5029 struct elf_aarch64_link_hash_table *globals;
5031 globals = elf_aarch64_hash_table (link_info);
5032 globals->pic_veneer = pic_veneer;
5033 globals->fix_erratum_835769 = fix_erratum_835769;
5034 /* If the default options are used, then ERRAT_ADR will be set by default
5035 which will enable the ADRP->ADR workaround for the erratum 843419
5036 workaround. */
5037 globals->fix_erratum_843419 = fix_erratum_843419;
5038 globals->no_apply_dynamic_relocs = no_apply_dynamic_relocs;
5040 BFD_ASSERT (is_aarch64_elf (output_bfd));
5041 elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
5042 elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
5044 switch (bp_info.bti_type)
5046 case BTI_WARN:
5047 elf_aarch64_tdata (output_bfd)->no_bti_warn = 0;
5048 elf_aarch64_tdata (output_bfd)->gnu_and_prop
5049 |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
5050 break;
5052 default:
5053 break;
5055 elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type;
5056 setup_plt_values (link_info, bp_info.plt_type);
5059 static bfd_vma
5060 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
5061 struct elf_aarch64_link_hash_table
5062 *globals, struct bfd_link_info *info,
5063 bfd_vma value, bfd *output_bfd,
5064 bool *unresolved_reloc_p)
5066 bfd_vma off = (bfd_vma) - 1;
5067 asection *basegot = globals->root.sgot;
5068 bool dyn = globals->root.dynamic_sections_created;
5070 if (h != NULL)
5072 BFD_ASSERT (basegot != NULL);
5073 off = h->got.offset;
5074 BFD_ASSERT (off != (bfd_vma) - 1);
5075 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
5076 || (bfd_link_pic (info)
5077 && SYMBOL_REFERENCES_LOCAL (info, h))
5078 || (ELF_ST_VISIBILITY (h->other)
5079 && h->root.type == bfd_link_hash_undefweak))
5081 /* This is actually a static link, or it is a -Bsymbolic link
5082 and the symbol is defined locally. We must initialize this
5083 entry in the global offset table. Since the offset must
5084 always be a multiple of 8 (4 in the case of ILP32), we use
5085 the least significant bit to record whether we have
5086 initialized it already.
5087 When doing a dynamic link, we create a .rel(a).got relocation
5088 entry to initialize the value. This is done in the
5089 finish_dynamic_symbol routine. */
5090 if ((off & 1) != 0)
5091 off &= ~1;
5092 else
5094 bfd_put_NN (output_bfd, value, basegot->contents + off);
5095 h->got.offset |= 1;
5098 else
5099 *unresolved_reloc_p = false;
5101 off = off + basegot->output_section->vma + basegot->output_offset;
5104 return off;
5107 /* Change R_TYPE to a more efficient access model where possible,
5108 return the new reloc type. */
5110 static bfd_reloc_code_real_type
5111 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
5112 struct elf_link_hash_entry *h,
5113 struct bfd_link_info *info)
5115 bool local_exec = bfd_link_executable (info)
5116 && SYMBOL_REFERENCES_LOCAL (info, h);
5118 switch (r_type)
5120 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
5121 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
5122 return (local_exec
5123 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5124 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
5126 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
5127 return (local_exec
5128 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5129 : r_type);
5131 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
5132 return (local_exec
5133 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5134 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
5136 case BFD_RELOC_AARCH64_TLSDESC_LDR:
5137 return (local_exec
5138 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5139 : BFD_RELOC_AARCH64_NONE);
5141 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
5142 return (local_exec
5143 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5144 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
5146 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
5147 return (local_exec
5148 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5149 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
5151 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
5152 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
5153 return (local_exec
5154 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5155 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
5157 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5158 return local_exec ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
5160 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
5161 return local_exec ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
5163 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
5164 return r_type;
5166 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
5167 return (local_exec
5168 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
5169 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
5171 case BFD_RELOC_AARCH64_TLSDESC_ADD:
5172 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
5173 case BFD_RELOC_AARCH64_TLSDESC_CALL:
5174 /* Instructions with these relocations will become NOPs. */
5175 return BFD_RELOC_AARCH64_NONE;
5177 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
5178 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
5179 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
5180 return local_exec ? BFD_RELOC_AARCH64_NONE : r_type;
5182 #if ARCH_SIZE == 64
5183 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
5184 return local_exec
5185 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5186 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
5188 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
5189 return local_exec
5190 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5191 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
5192 #endif
5194 default:
5195 break;
5198 return r_type;
5201 static unsigned int
5202 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
5204 switch (r_type)
5206 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
5207 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
5208 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
5209 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
5210 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
5211 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
5212 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
5213 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
5214 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
5215 return GOT_NORMAL;
5217 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
5218 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
5219 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
5220 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
5221 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
5222 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
5223 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
5224 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
5225 return GOT_TLS_GD;
5227 case BFD_RELOC_AARCH64_TLSDESC_ADD:
5228 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
5229 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
5230 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
5231 case BFD_RELOC_AARCH64_TLSDESC_CALL:
5232 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
5233 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
5234 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
5235 case BFD_RELOC_AARCH64_TLSDESC_LDR:
5236 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
5237 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
5238 return GOT_TLSDESC_GD;
5240 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5241 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
5242 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
5243 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
5244 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
5245 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
5246 return GOT_TLS_IE;
5248 default:
5249 break;
5251 return GOT_UNKNOWN;
5254 static bool
5255 aarch64_can_relax_tls (bfd *input_bfd,
5256 struct bfd_link_info *info,
5257 bfd_reloc_code_real_type r_type,
5258 struct elf_link_hash_entry *h,
5259 unsigned long r_symndx)
5261 unsigned int symbol_got_type;
5262 unsigned int reloc_got_type;
5264 if (! IS_AARCH64_TLS_RELAX_RELOC (r_type))
5265 return false;
5267 symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
5268 reloc_got_type = aarch64_reloc_got_type (r_type);
5270 if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
5271 return true;
5273 if (!bfd_link_executable (info))
5274 return false;
5276 if (h && h->root.type == bfd_link_hash_undefweak)
5277 return false;
5279 return true;
5282 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
5283 enumerator. */
5285 static bfd_reloc_code_real_type
5286 aarch64_tls_transition (bfd *input_bfd,
5287 struct bfd_link_info *info,
5288 unsigned int r_type,
5289 struct elf_link_hash_entry *h,
5290 unsigned long r_symndx)
5292 bfd_reloc_code_real_type bfd_r_type
5293 = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
5295 if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
5296 return bfd_r_type;
5298 return aarch64_tls_transition_without_check (bfd_r_type, h, info);
5301 /* Return the base VMA address which should be subtracted from real addresses
5302 when resolving R_AARCH64_TLS_DTPREL relocation. */
5304 static bfd_vma
5305 dtpoff_base (struct bfd_link_info *info)
5307 /* If tls_sec is NULL, we should have signalled an error already. */
5308 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
5309 return elf_hash_table (info)->tls_sec->vma;
5312 /* Return the base VMA address which should be subtracted from real addresses
5313 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
5315 static bfd_vma
5316 tpoff_base (struct bfd_link_info *info)
5318 struct elf_link_hash_table *htab = elf_hash_table (info);
5320 /* If tls_sec is NULL, we should have signalled an error already. */
5321 BFD_ASSERT (htab->tls_sec != NULL);
5323 bfd_vma base = align_power ((bfd_vma) TCB_SIZE,
5324 htab->tls_sec->alignment_power);
5325 return htab->tls_sec->vma - base;
5328 static bfd_vma *
5329 symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
5330 unsigned long r_symndx)
5332 /* Calculate the address of the GOT entry for symbol
5333 referred to in h. */
5334 if (h != NULL)
5335 return &h->got.offset;
5336 else
5338 /* local symbol */
5339 struct elf_aarch64_local_symbol *l;
5341 l = elf_aarch64_locals (input_bfd);
5342 return &l[r_symndx].got_offset;
5346 static void
5347 symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
5348 unsigned long r_symndx)
5350 bfd_vma *p;
5351 p = symbol_got_offset_ref (input_bfd, h, r_symndx);
5352 *p |= 1;
5355 static int
5356 symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
5357 unsigned long r_symndx)
5359 bfd_vma value;
5360 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
5361 return value & 1;
5364 static bfd_vma
5365 symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
5366 unsigned long r_symndx)
5368 bfd_vma value;
5369 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
5370 value &= ~1;
5371 return value;
5374 static bfd_vma *
5375 symbol_tlsdesc_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
5376 unsigned long r_symndx)
5378 /* Calculate the address of the GOT entry for symbol
5379 referred to in h. */
5380 if (h != NULL)
5382 struct elf_aarch64_link_hash_entry *eh;
5383 eh = (struct elf_aarch64_link_hash_entry *) h;
5384 return &eh->tlsdesc_got_jump_table_offset;
5386 else
5388 /* local symbol */
5389 struct elf_aarch64_local_symbol *l;
5391 l = elf_aarch64_locals (input_bfd);
5392 return &l[r_symndx].tlsdesc_got_jump_table_offset;
5396 static void
5397 symbol_tlsdesc_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
5398 unsigned long r_symndx)
5400 bfd_vma *p;
5401 p = symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
5402 *p |= 1;
5405 static int
5406 symbol_tlsdesc_got_offset_mark_p (bfd *input_bfd,
5407 struct elf_link_hash_entry *h,
5408 unsigned long r_symndx)
5410 bfd_vma value;
5411 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
5412 return value & 1;
5415 static bfd_vma
5416 symbol_tlsdesc_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
5417 unsigned long r_symndx)
5419 bfd_vma value;
5420 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
5421 value &= ~1;
5422 return value;
5425 /* Data for make_branch_to_erratum_835769_stub(). */
5427 struct erratum_835769_branch_to_stub_data
5429 struct bfd_link_info *info;
5430 asection *output_section;
5431 bfd_byte *contents;
5434 /* Helper to insert branches to erratum 835769 stubs in the right
5435 places for a particular section. */
5437 static bool
5438 make_branch_to_erratum_835769_stub (struct bfd_hash_entry *gen_entry,
5439 void *in_arg)
5441 struct elf_aarch64_stub_hash_entry *stub_entry;
5442 struct erratum_835769_branch_to_stub_data *data;
5443 bfd_byte *contents;
5444 unsigned long branch_insn = 0;
5445 bfd_vma veneered_insn_loc, veneer_entry_loc;
5446 bfd_signed_vma branch_offset;
5447 unsigned int target;
5448 bfd *abfd;
5450 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
5451 data = (struct erratum_835769_branch_to_stub_data *) in_arg;
5453 if (stub_entry->target_section != data->output_section
5454 || stub_entry->stub_type != aarch64_stub_erratum_835769_veneer)
5455 return true;
5457 contents = data->contents;
5458 veneered_insn_loc = stub_entry->target_section->output_section->vma
5459 + stub_entry->target_section->output_offset
5460 + stub_entry->target_value;
5461 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
5462 + stub_entry->stub_sec->output_offset
5463 + stub_entry->stub_offset;
5464 branch_offset = veneer_entry_loc - veneered_insn_loc;
5466 abfd = stub_entry->target_section->owner;
5467 if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
5468 _bfd_error_handler
5469 (_("%pB: error: erratum 835769 stub out "
5470 "of range (input file too large)"), abfd);
5472 target = stub_entry->target_value;
5473 branch_insn = 0x14000000;
5474 branch_offset >>= 2;
5475 branch_offset &= 0x3ffffff;
5476 branch_insn |= branch_offset;
5477 bfd_putl32 (branch_insn, &contents[target]);
5479 return true;
5483 static bool
5484 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
5485 void *in_arg)
5487 struct elf_aarch64_stub_hash_entry *stub_entry
5488 = (struct elf_aarch64_stub_hash_entry *) gen_entry;
5489 struct erratum_835769_branch_to_stub_data *data
5490 = (struct erratum_835769_branch_to_stub_data *) in_arg;
5491 struct bfd_link_info *info;
5492 struct elf_aarch64_link_hash_table *htab;
5493 bfd_byte *contents;
5494 asection *section;
5495 bfd *abfd;
5496 bfd_vma place;
5497 uint32_t insn;
5499 info = data->info;
5500 contents = data->contents;
5501 section = data->output_section;
5503 htab = elf_aarch64_hash_table (info);
5505 if (stub_entry->target_section != section
5506 || stub_entry->stub_type != aarch64_stub_erratum_843419_veneer)
5507 return true;
5509 BFD_ASSERT (((htab->fix_erratum_843419 & ERRAT_ADRP) && stub_entry->stub_sec)
5510 || (htab->fix_erratum_843419 & ERRAT_ADR));
5512 /* Only update the stub section if we have one. We should always have one if
5513 we're allowed to use the ADRP errata workaround, otherwise it is not
5514 required. */
5515 if (stub_entry->stub_sec)
5517 insn = bfd_getl32 (contents + stub_entry->target_value);
5518 bfd_putl32 (insn,
5519 stub_entry->stub_sec->contents + stub_entry->stub_offset);
5522 place = (section->output_section->vma + section->output_offset
5523 + stub_entry->adrp_offset);
5524 insn = bfd_getl32 (contents + stub_entry->adrp_offset);
5526 if (!_bfd_aarch64_adrp_p (insn))
5527 abort ();
5529 bfd_signed_vma imm =
5530 (_bfd_aarch64_sign_extend
5531 ((bfd_vma) _bfd_aarch64_decode_adrp_imm (insn) << 12, 33)
5532 - (place & 0xfff));
5534 if ((htab->fix_erratum_843419 & ERRAT_ADR)
5535 && (imm >= AARCH64_MIN_ADRP_IMM && imm <= AARCH64_MAX_ADRP_IMM))
5537 insn = (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP, imm)
5538 | AARCH64_RT (insn));
5539 bfd_putl32 (insn, contents + stub_entry->adrp_offset);
5540 /* Stub is not needed, don't map it out. */
5541 stub_entry->stub_type = aarch64_stub_none;
5543 else if (htab->fix_erratum_843419 & ERRAT_ADRP)
5545 bfd_vma veneered_insn_loc;
5546 bfd_vma veneer_entry_loc;
5547 bfd_signed_vma branch_offset;
5548 uint32_t branch_insn;
5550 veneered_insn_loc = stub_entry->target_section->output_section->vma
5551 + stub_entry->target_section->output_offset
5552 + stub_entry->target_value;
5553 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
5554 + stub_entry->stub_sec->output_offset
5555 + stub_entry->stub_offset;
5556 branch_offset = veneer_entry_loc - veneered_insn_loc;
5558 abfd = stub_entry->target_section->owner;
5559 if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
5560 _bfd_error_handler
5561 (_("%pB: error: erratum 843419 stub out "
5562 "of range (input file too large)"), abfd);
5564 branch_insn = 0x14000000;
5565 branch_offset >>= 2;
5566 branch_offset &= 0x3ffffff;
5567 branch_insn |= branch_offset;
5568 bfd_putl32 (branch_insn, contents + stub_entry->target_value);
5570 else
5572 abfd = stub_entry->target_section->owner;
5573 _bfd_error_handler
5574 (_("%pB: error: erratum 843419 immediate 0x%" PRIx64
5575 " out of range for ADR (input file too large) and "
5576 "--fix-cortex-a53-843419=adr used. Run the linker with "
5577 "--fix-cortex-a53-843419=full instead"),
5578 abfd, (uint64_t) (bfd_vma) imm);
5579 bfd_set_error (bfd_error_bad_value);
5580 /* This function is called inside a hashtable traversal and the error
5581 handlers called above turn into non-fatal errors. Which means this
5582 case ld returns an exit code 0 and also produces a broken object file.
5583 To prevent this, issue a hard abort. */
5584 BFD_FAIL ();
5586 return true;
5590 static bool
5591 elfNN_aarch64_write_section (bfd *output_bfd ATTRIBUTE_UNUSED,
5592 struct bfd_link_info *link_info,
5593 asection *sec,
5594 bfd_byte *contents)
5597 struct elf_aarch64_link_hash_table *globals =
5598 elf_aarch64_hash_table (link_info);
5600 if (globals == NULL)
5601 return false;
5603 /* Fix code to point to erratum 835769 stubs. */
5604 if (globals->fix_erratum_835769)
5606 struct erratum_835769_branch_to_stub_data data;
5608 data.info = link_info;
5609 data.output_section = sec;
5610 data.contents = contents;
5611 bfd_hash_traverse (&globals->stub_hash_table,
5612 make_branch_to_erratum_835769_stub, &data);
5615 if (globals->fix_erratum_843419)
5617 struct erratum_835769_branch_to_stub_data data;
5619 data.info = link_info;
5620 data.output_section = sec;
5621 data.contents = contents;
5622 bfd_hash_traverse (&globals->stub_hash_table,
5623 _bfd_aarch64_erratum_843419_branch_to_stub, &data);
5626 return false;
5629 /* Return TRUE if RELOC is a relocation against the base of GOT table. */
5631 static bool
5632 aarch64_relocation_aginst_gp_p (bfd_reloc_code_real_type reloc)
5634 return (reloc == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
5635 || reloc == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5636 || reloc == BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
5637 || reloc == BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
5638 || reloc == BFD_RELOC_AARCH64_MOVW_GOTOFF_G1);
5641 /* Perform a relocation as part of a final link. The input relocation type
5642 should be TLS relaxed. */
5644 static bfd_reloc_status_type
5645 elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
5646 bfd *input_bfd,
5647 bfd *output_bfd,
5648 asection *input_section,
5649 bfd_byte *contents,
5650 Elf_Internal_Rela *rel,
5651 bfd_vma value,
5652 struct bfd_link_info *info,
5653 asection *sym_sec,
5654 struct elf_link_hash_entry *h,
5655 bool *unresolved_reloc_p,
5656 bool save_addend,
5657 bfd_vma *saved_addend,
5658 Elf_Internal_Sym *sym)
5660 Elf_Internal_Shdr *symtab_hdr;
5661 unsigned int r_type = howto->type;
5662 bfd_reloc_code_real_type bfd_r_type
5663 = elfNN_aarch64_bfd_reloc_from_howto (howto);
5664 unsigned long r_symndx;
5665 bfd_byte *hit_data = contents + rel->r_offset;
5666 bfd_vma place, off, got_entry_addr = 0;
5667 bfd_signed_vma signed_addend;
5668 struct elf_aarch64_link_hash_table *globals;
5669 bool weak_undef_p;
5670 bool relative_reloc;
5671 asection *base_got;
5672 bfd_vma orig_value = value;
5673 bool resolved_to_zero;
5674 bool abs_symbol_p;
5676 globals = elf_aarch64_hash_table (info);
5678 symtab_hdr = &elf_symtab_hdr (input_bfd);
5680 BFD_ASSERT (is_aarch64_elf (input_bfd));
5682 r_symndx = ELFNN_R_SYM (rel->r_info);
5684 place = input_section->output_section->vma
5685 + input_section->output_offset + rel->r_offset;
5687 /* Get addend, accumulating the addend for consecutive relocs
5688 which refer to the same offset. */
5689 signed_addend = saved_addend ? *saved_addend : 0;
5690 signed_addend += rel->r_addend;
5692 weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
5693 : bfd_is_und_section (sym_sec));
5694 abs_symbol_p = h != NULL && bfd_is_abs_symbol (&h->root);
5697 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
5698 it here if it is defined in a non-shared object. */
5699 if (h != NULL
5700 && h->type == STT_GNU_IFUNC
5701 && h->def_regular)
5703 asection *plt;
5704 const char *name;
5705 bfd_vma addend = 0;
5707 if ((input_section->flags & SEC_ALLOC) == 0)
5709 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
5710 STT_GNU_IFUNC symbol as STT_FUNC. */
5711 if (elf_section_type (input_section) == SHT_NOTE)
5712 goto skip_ifunc;
5714 /* Dynamic relocs are not propagated for SEC_DEBUGGING
5715 sections because such sections are not SEC_ALLOC and
5716 thus ld.so will not process them. */
5717 if ((input_section->flags & SEC_DEBUGGING) != 0)
5718 return bfd_reloc_ok;
5720 if (h->root.root.string)
5721 name = h->root.root.string;
5722 else
5723 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, NULL);
5724 _bfd_error_handler
5725 /* xgettext:c-format */
5726 (_("%pB(%pA+%#" PRIx64 "): "
5727 "unresolvable %s relocation against symbol `%s'"),
5728 input_bfd, input_section, (uint64_t) rel->r_offset,
5729 howto->name, name);
5730 bfd_set_error (bfd_error_bad_value);
5731 return bfd_reloc_notsupported;
5733 else if (h->plt.offset == (bfd_vma) -1)
5734 goto bad_ifunc_reloc;
5736 /* STT_GNU_IFUNC symbol must go through PLT. */
5737 plt = globals->root.splt ? globals->root.splt : globals->root.iplt;
5738 value = (plt->output_section->vma + plt->output_offset + h->plt.offset);
5740 switch (bfd_r_type)
5742 default:
5743 bad_ifunc_reloc:
5744 if (h->root.root.string)
5745 name = h->root.root.string;
5746 else
5747 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5748 NULL);
5749 _bfd_error_handler
5750 /* xgettext:c-format */
5751 (_("%pB: relocation %s against STT_GNU_IFUNC "
5752 "symbol `%s' isn't handled by %s"), input_bfd,
5753 howto->name, name, __func__);
5754 bfd_set_error (bfd_error_bad_value);
5755 return bfd_reloc_notsupported;
5757 case BFD_RELOC_AARCH64_NN:
5758 if (rel->r_addend != 0)
5760 if (h->root.root.string)
5761 name = h->root.root.string;
5762 else
5763 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
5764 sym, NULL);
5765 _bfd_error_handler
5766 /* xgettext:c-format */
5767 (_("%pB: relocation %s against STT_GNU_IFUNC "
5768 "symbol `%s' has non-zero addend: %" PRId64),
5769 input_bfd, howto->name, name, (int64_t) rel->r_addend);
5770 bfd_set_error (bfd_error_bad_value);
5771 return bfd_reloc_notsupported;
5774 /* Generate dynamic relocation only when there is a
5775 non-GOT reference in a shared object. */
5776 if (bfd_link_pic (info) && h->non_got_ref)
5778 Elf_Internal_Rela outrel;
5779 asection *sreloc;
5781 /* Need a dynamic relocation to get the real function
5782 address. */
5783 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
5784 info,
5785 input_section,
5786 rel->r_offset);
5787 if (outrel.r_offset == (bfd_vma) -1
5788 || outrel.r_offset == (bfd_vma) -2)
5789 abort ();
5791 outrel.r_offset += (input_section->output_section->vma
5792 + input_section->output_offset);
5794 if (h->dynindx == -1
5795 || h->forced_local
5796 || bfd_link_executable (info))
5798 /* This symbol is resolved locally. */
5799 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
5800 outrel.r_addend = (h->root.u.def.value
5801 + h->root.u.def.section->output_section->vma
5802 + h->root.u.def.section->output_offset);
5804 else
5806 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
5807 outrel.r_addend = 0;
5810 sreloc = globals->root.irelifunc;
5811 elf_append_rela (output_bfd, sreloc, &outrel);
5813 /* If this reloc is against an external symbol, we
5814 do not want to fiddle with the addend. Otherwise,
5815 we need to include the symbol value so that it
5816 becomes an addend for the dynamic reloc. For an
5817 internal symbol, we have updated addend. */
5818 return bfd_reloc_ok;
5820 /* FALLTHROUGH */
5821 case BFD_RELOC_AARCH64_CALL26:
5822 case BFD_RELOC_AARCH64_JUMP26:
5823 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
5824 place, value,
5825 signed_addend,
5826 weak_undef_p);
5827 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
5828 howto, value);
5829 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
5830 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
5831 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
5832 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
5833 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
5834 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
5835 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
5836 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
5837 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
5838 base_got = globals->root.sgot;
5839 off = h->got.offset;
5841 if (base_got == NULL)
5842 abort ();
5844 if (off == (bfd_vma) -1)
5846 bfd_vma plt_index;
5848 /* We can't use h->got.offset here to save state, or
5849 even just remember the offset, as finish_dynamic_symbol
5850 would use that as offset into .got. */
5852 if (globals->root.splt != NULL)
5854 plt_index = ((h->plt.offset - globals->plt_header_size) /
5855 globals->plt_entry_size);
5856 off = (plt_index + 3) * GOT_ENTRY_SIZE;
5857 base_got = globals->root.sgotplt;
5859 else
5861 plt_index = h->plt.offset / globals->plt_entry_size;
5862 off = plt_index * GOT_ENTRY_SIZE;
5863 base_got = globals->root.igotplt;
5866 if (h->dynindx == -1
5867 || h->forced_local
5868 || info->symbolic)
5870 /* This references the local definition. We must
5871 initialize this entry in the global offset table.
5872 Since the offset must always be a multiple of 8,
5873 we use the least significant bit to record
5874 whether we have initialized it already.
5876 When doing a dynamic link, we create a .rela.got
5877 relocation entry to initialize the value. This
5878 is done in the finish_dynamic_symbol routine. */
5879 if ((off & 1) != 0)
5880 off &= ~1;
5881 else
5883 bfd_put_NN (output_bfd, value,
5884 base_got->contents + off);
5885 /* Note that this is harmless as -1 | 1 still is -1. */
5886 h->got.offset |= 1;
5889 value = (base_got->output_section->vma
5890 + base_got->output_offset + off);
5892 else
5893 value = aarch64_calculate_got_entry_vma (h, globals, info,
5894 value, output_bfd,
5895 unresolved_reloc_p);
5897 if (aarch64_relocation_aginst_gp_p (bfd_r_type))
5898 addend = (globals->root.sgot->output_section->vma
5899 + globals->root.sgot->output_offset);
5901 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
5902 place, value,
5903 addend, weak_undef_p);
5904 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
5905 case BFD_RELOC_AARCH64_ADD_LO12:
5906 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
5907 break;
5911 skip_ifunc:
5912 resolved_to_zero = (h != NULL
5913 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
5915 switch (bfd_r_type)
5917 case BFD_RELOC_AARCH64_NONE:
5918 case BFD_RELOC_AARCH64_TLSDESC_ADD:
5919 case BFD_RELOC_AARCH64_TLSDESC_CALL:
5920 case BFD_RELOC_AARCH64_TLSDESC_LDR:
5921 *unresolved_reloc_p = false;
5922 return bfd_reloc_ok;
5924 case BFD_RELOC_AARCH64_NN:
5926 /* When generating a shared library or PIE, these relocations
5927 are copied into the output file to be resolved at run time. */
5928 if ((bfd_link_pic (info)
5929 && (input_section->flags & SEC_ALLOC)
5930 && (h == NULL
5931 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5932 && !resolved_to_zero)
5933 || h->root.type != bfd_link_hash_undefweak))
5934 /* Or we are creating an executable, we may need to keep relocations
5935 for symbols satisfied by a dynamic library if we manage to avoid
5936 copy relocs for the symbol. */
5937 || (ELIMINATE_COPY_RELOCS
5938 && !bfd_link_pic (info)
5939 && h != NULL
5940 && (input_section->flags & SEC_ALLOC)
5941 && h->dynindx != -1
5942 && !h->non_got_ref
5943 && ((h->def_dynamic
5944 && !h->def_regular)
5945 || h->root.type == bfd_link_hash_undefweak
5946 || h->root.type == bfd_link_hash_undefined)))
5948 Elf_Internal_Rela outrel;
5949 bfd_byte *loc;
5950 bool skip, relocate;
5951 asection *sreloc;
5953 *unresolved_reloc_p = false;
5955 skip = false;
5956 relocate = false;
5958 outrel.r_addend = signed_addend;
5959 outrel.r_offset =
5960 _bfd_elf_section_offset (output_bfd, info, input_section,
5961 rel->r_offset);
5962 if (outrel.r_offset == (bfd_vma) - 1)
5963 skip = true;
5964 else if (outrel.r_offset == (bfd_vma) - 2)
5966 skip = true;
5967 relocate = true;
5969 else if (abs_symbol_p)
5971 /* Local absolute symbol. */
5972 skip = (h->forced_local || (h->dynindx == -1));
5973 relocate = skip;
5976 outrel.r_offset += (input_section->output_section->vma
5977 + input_section->output_offset);
5979 if (skip)
5980 memset (&outrel, 0, sizeof outrel);
5981 else if (h != NULL
5982 && h->dynindx != -1
5983 && (!bfd_link_pic (info)
5984 || !(bfd_link_pie (info) || SYMBOLIC_BIND (info, h))
5985 || !h->def_regular))
5986 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
5987 else if (info->enable_dt_relr
5988 && input_section->alignment_power != 0
5989 && rel->r_offset % 2 == 0)
5991 /* Don't emit a relative relocation that is packed, only
5992 apply the addend. */
5993 return _bfd_final_link_relocate (howto, input_bfd, input_section,
5994 contents, rel->r_offset, value,
5995 signed_addend);
5997 else
5999 int symbol;
6001 /* On SVR4-ish systems, the dynamic loader cannot
6002 relocate the text and data segments independently,
6003 so the symbol does not matter. */
6004 symbol = 0;
6005 relocate = !globals->no_apply_dynamic_relocs;
6006 outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
6007 outrel.r_addend += value;
6010 sreloc = elf_section_data (input_section)->sreloc;
6011 if (sreloc == NULL || sreloc->contents == NULL)
6012 return bfd_reloc_notsupported;
6014 loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
6015 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
6017 if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
6019 /* Sanity to check that we have previously allocated
6020 sufficient space in the relocation section for the
6021 number of relocations we actually want to emit. */
6022 abort ();
6025 /* If this reloc is against an external symbol, we do not want to
6026 fiddle with the addend. Otherwise, we need to include the symbol
6027 value so that it becomes an addend for the dynamic reloc. */
6028 if (!relocate)
6029 return bfd_reloc_ok;
6031 return _bfd_final_link_relocate (howto, input_bfd, input_section,
6032 contents, rel->r_offset, value,
6033 signed_addend);
6035 else
6036 value += signed_addend;
6037 break;
6039 case BFD_RELOC_AARCH64_CALL26:
6040 case BFD_RELOC_AARCH64_JUMP26:
6042 asection *splt = globals->root.splt;
6043 bool via_plt_p =
6044 splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
6046 /* A call to an undefined weak symbol is converted to a jump to
6047 the next instruction unless a PLT entry will be created.
6048 The jump to the next instruction is optimized as a NOP.
6049 Do the same for local undefined symbols. */
6050 if (weak_undef_p && ! via_plt_p)
6052 bfd_putl32 (INSN_NOP, hit_data);
6053 return bfd_reloc_ok;
6056 /* If the call goes through a PLT entry, make sure to
6057 check distance to the right destination address. */
6058 if (via_plt_p)
6059 value = (splt->output_section->vma
6060 + splt->output_offset + h->plt.offset);
6062 /* Check if a stub has to be inserted because the destination
6063 is too far away. */
6064 struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
6066 /* If the branch destination is directed to plt stub, "value" will be
6067 the final destination, otherwise we should plus signed_addend, it may
6068 contain non-zero value, for example call to local function symbol
6069 which are turned into "sec_sym + sec_off", and sec_off is kept in
6070 signed_addend. */
6071 if (! aarch64_valid_branch_p (via_plt_p ? value : value + signed_addend,
6072 place))
6073 /* The target is out of reach, so redirect the branch to
6074 the local stub for this function. */
6075 stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
6076 rel, globals);
6077 if (stub_entry != NULL)
6079 value = (stub_entry->stub_offset
6080 + stub_entry->stub_sec->output_offset
6081 + stub_entry->stub_sec->output_section->vma);
6083 /* We have redirected the destination to stub entry address,
6084 so ignore any addend record in the original rela entry. */
6085 signed_addend = 0;
6088 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6089 place, value,
6090 signed_addend, weak_undef_p);
6091 *unresolved_reloc_p = false;
6092 break;
6094 case BFD_RELOC_AARCH64_16_PCREL:
6095 case BFD_RELOC_AARCH64_32_PCREL:
6096 case BFD_RELOC_AARCH64_64_PCREL:
6097 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
6098 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
6099 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
6100 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
6101 case BFD_RELOC_AARCH64_MOVW_PREL_G0:
6102 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC:
6103 case BFD_RELOC_AARCH64_MOVW_PREL_G1:
6104 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC:
6105 case BFD_RELOC_AARCH64_MOVW_PREL_G2:
6106 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC:
6107 case BFD_RELOC_AARCH64_MOVW_PREL_G3:
6108 if (bfd_link_pic (info)
6109 && (input_section->flags & SEC_ALLOC) != 0
6110 && (input_section->flags & SEC_READONLY) != 0
6111 && !_bfd_elf_symbol_refs_local_p (h, info, 1))
6113 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
6115 _bfd_error_handler
6116 /* xgettext:c-format */
6117 (_("%pB: relocation %s against symbol `%s' which may bind "
6118 "externally can not be used when making a shared object; "
6119 "recompile with -fPIC"),
6120 input_bfd, elfNN_aarch64_howto_table[howto_index].name,
6121 h->root.root.string);
6122 bfd_set_error (bfd_error_bad_value);
6123 return bfd_reloc_notsupported;
6125 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6126 place, value,
6127 signed_addend,
6128 weak_undef_p);
6129 break;
6131 case BFD_RELOC_AARCH64_BRANCH19:
6132 case BFD_RELOC_AARCH64_TSTBR14:
6133 if (h && h->root.type == bfd_link_hash_undefined)
6135 _bfd_error_handler
6136 /* xgettext:c-format */
6137 (_("%pB: conditional branch to undefined symbol `%s' "
6138 "not allowed"), input_bfd, h->root.root.string);
6139 bfd_set_error (bfd_error_bad_value);
6140 return bfd_reloc_notsupported;
6142 /* Fall through. */
6144 case BFD_RELOC_AARCH64_16:
6145 #if ARCH_SIZE == 64
6146 case BFD_RELOC_AARCH64_32:
6147 #endif
6148 case BFD_RELOC_AARCH64_ADD_LO12:
6149 case BFD_RELOC_AARCH64_LDST128_LO12:
6150 case BFD_RELOC_AARCH64_LDST16_LO12:
6151 case BFD_RELOC_AARCH64_LDST32_LO12:
6152 case BFD_RELOC_AARCH64_LDST64_LO12:
6153 case BFD_RELOC_AARCH64_LDST8_LO12:
6154 case BFD_RELOC_AARCH64_MOVW_G0:
6155 case BFD_RELOC_AARCH64_MOVW_G0_NC:
6156 case BFD_RELOC_AARCH64_MOVW_G0_S:
6157 case BFD_RELOC_AARCH64_MOVW_G1:
6158 case BFD_RELOC_AARCH64_MOVW_G1_NC:
6159 case BFD_RELOC_AARCH64_MOVW_G1_S:
6160 case BFD_RELOC_AARCH64_MOVW_G2:
6161 case BFD_RELOC_AARCH64_MOVW_G2_NC:
6162 case BFD_RELOC_AARCH64_MOVW_G2_S:
6163 case BFD_RELOC_AARCH64_MOVW_G3:
6164 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6165 place, value,
6166 signed_addend, weak_undef_p);
6167 break;
6169 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
6170 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
6171 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
6172 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
6173 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
6174 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
6175 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
6176 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
6177 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
6178 if (globals->root.sgot == NULL)
6179 BFD_ASSERT (h != NULL);
6181 relative_reloc = false;
6182 if (h != NULL)
6184 bfd_vma addend = 0;
6186 /* If a symbol is not dynamic and is not undefined weak, bind it
6187 locally and generate a RELATIVE relocation under PIC mode.
6189 NOTE: one symbol may be referenced by several relocations, we
6190 should only generate one RELATIVE relocation for that symbol.
6191 Therefore, check GOT offset mark first. */
6192 if (h->dynindx == -1
6193 && !h->forced_local
6194 && h->root.type != bfd_link_hash_undefweak
6195 && bfd_link_pic (info)
6196 && !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
6197 relative_reloc = true;
6199 value = aarch64_calculate_got_entry_vma (h, globals, info, value,
6200 output_bfd,
6201 unresolved_reloc_p);
6202 /* Record the GOT entry address which will be used when generating
6203 RELATIVE relocation. */
6204 if (relative_reloc)
6205 got_entry_addr = value;
6207 if (aarch64_relocation_aginst_gp_p (bfd_r_type))
6208 addend = (globals->root.sgot->output_section->vma
6209 + globals->root.sgot->output_offset);
6210 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6211 place, value,
6212 addend, weak_undef_p);
6214 else
6216 bfd_vma addend = 0;
6217 struct elf_aarch64_local_symbol *locals
6218 = elf_aarch64_locals (input_bfd);
6220 if (locals == NULL)
6222 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
6223 _bfd_error_handler
6224 /* xgettext:c-format */
6225 (_("%pB: local symbol descriptor table be NULL when applying "
6226 "relocation %s against local symbol"),
6227 input_bfd, elfNN_aarch64_howto_table[howto_index].name);
6228 abort ();
6231 off = symbol_got_offset (input_bfd, h, r_symndx);
6232 base_got = globals->root.sgot;
6233 got_entry_addr = (base_got->output_section->vma
6234 + base_got->output_offset + off);
6236 if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
6238 bfd_put_64 (output_bfd, value, base_got->contents + off);
6240 /* For local symbol, we have done absolute relocation in static
6241 linking stage. While for shared library, we need to update the
6242 content of GOT entry according to the shared object's runtime
6243 base address. So, we need to generate a R_AARCH64_RELATIVE reloc
6244 for dynamic linker. */
6245 if (bfd_link_pic (info))
6246 relative_reloc = true;
6248 symbol_got_offset_mark (input_bfd, h, r_symndx);
6251 /* Update the relocation value to GOT entry addr as we have transformed
6252 the direct data access into indirect data access through GOT. */
6253 value = got_entry_addr;
6255 if (aarch64_relocation_aginst_gp_p (bfd_r_type))
6256 addend = base_got->output_section->vma + base_got->output_offset;
6258 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6259 place, value,
6260 addend, weak_undef_p);
6263 /* Emit relative relocations, but not if they are packed (DT_RELR). */
6264 if (relative_reloc && !info->enable_dt_relr)
6266 asection *s;
6267 Elf_Internal_Rela outrel;
6269 s = globals->root.srelgot;
6270 if (s == NULL)
6271 abort ();
6273 outrel.r_offset = got_entry_addr;
6274 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
6275 outrel.r_addend = orig_value;
6276 elf_append_rela (output_bfd, s, &outrel);
6278 break;
6280 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
6281 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
6282 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
6283 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
6284 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
6285 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
6286 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
6287 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
6288 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
6289 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
6290 if (globals->root.sgot == NULL)
6291 return bfd_reloc_notsupported;
6293 value = (symbol_got_offset (input_bfd, h, r_symndx)
6294 + globals->root.sgot->output_section->vma
6295 + globals->root.sgot->output_offset);
6297 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6298 place, value,
6299 0, weak_undef_p);
6300 *unresolved_reloc_p = false;
6301 break;
6303 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
6304 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
6305 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
6306 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
6307 if (globals->root.sgot == NULL)
6308 return bfd_reloc_notsupported;
6310 value = symbol_got_offset (input_bfd, h, r_symndx);
6311 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6312 place, value,
6313 0, weak_undef_p);
6314 *unresolved_reloc_p = false;
6315 break;
6317 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12:
6318 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12:
6319 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
6320 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12:
6321 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC:
6322 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12:
6323 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC:
6324 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12:
6325 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC:
6326 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12:
6327 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC:
6328 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0:
6329 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
6330 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1:
6331 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC:
6332 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2:
6334 if (!(weak_undef_p || elf_hash_table (info)->tls_sec))
6336 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
6337 _bfd_error_handler
6338 /* xgettext:c-format */
6339 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
6340 input_bfd, elfNN_aarch64_howto_table[howto_index].name,
6341 h->root.root.string);
6342 bfd_set_error (bfd_error_bad_value);
6343 return bfd_reloc_notsupported;
6346 bfd_vma def_value
6347 = weak_undef_p ? 0 : signed_addend - dtpoff_base (info);
6348 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6349 place, value,
6350 def_value, weak_undef_p);
6351 break;
6354 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
6355 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
6356 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
6357 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12:
6358 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
6359 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12:
6360 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
6361 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12:
6362 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
6363 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12:
6364 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
6365 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
6366 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
6367 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
6368 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
6369 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
6371 if (!(weak_undef_p || elf_hash_table (info)->tls_sec))
6373 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
6374 _bfd_error_handler
6375 /* xgettext:c-format */
6376 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
6377 input_bfd, elfNN_aarch64_howto_table[howto_index].name,
6378 h->root.root.string);
6379 bfd_set_error (bfd_error_bad_value);
6380 return bfd_reloc_notsupported;
6383 bfd_vma def_value
6384 = weak_undef_p ? 0 : signed_addend - tpoff_base (info);
6385 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6386 place, value,
6387 def_value, weak_undef_p);
6388 *unresolved_reloc_p = false;
6389 break;
6392 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
6393 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
6394 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
6395 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
6396 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
6397 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
6398 if (globals->root.sgot == NULL)
6399 return bfd_reloc_notsupported;
6400 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
6401 + globals->root.sgotplt->output_section->vma
6402 + globals->root.sgotplt->output_offset
6403 + globals->sgotplt_jump_table_size);
6405 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6406 place, value,
6407 0, weak_undef_p);
6408 *unresolved_reloc_p = false;
6409 break;
6411 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
6412 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
6413 if (globals->root.sgot == NULL)
6414 return bfd_reloc_notsupported;
6416 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
6417 + globals->root.sgotplt->output_section->vma
6418 + globals->root.sgotplt->output_offset
6419 + globals->sgotplt_jump_table_size);
6421 value -= (globals->root.sgot->output_section->vma
6422 + globals->root.sgot->output_offset);
6424 value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
6425 place, value,
6426 0, weak_undef_p);
6427 *unresolved_reloc_p = false;
6428 break;
6430 default:
6431 return bfd_reloc_notsupported;
6434 if (saved_addend)
6435 *saved_addend = value;
6437 /* Only apply the final relocation in a sequence. */
6438 if (save_addend)
6439 return bfd_reloc_continue;
6441 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
6442 howto, value);
6445 /* LP64 and ILP32 operates on x- and w-registers respectively.
6446 Next definitions take into account the difference between
6447 corresponding machine codes. R means x-register if the target
6448 arch is LP64, and w-register if the target is ILP32. */
6450 #if ARCH_SIZE == 64
6451 # define add_R0_R0 (0x91000000)
6452 # define add_R0_R0_R1 (0x8b000020)
6453 # define add_R0_R1 (0x91400020)
6454 # define ldr_R0 (0x58000000)
6455 # define ldr_R0_mask(i) (i & 0xffffffe0)
6456 # define ldr_R0_x0 (0xf9400000)
6457 # define ldr_hw_R0 (0xf2a00000)
6458 # define movk_R0 (0xf2800000)
6459 # define movz_R0 (0xd2a00000)
6460 # define movz_hw_R0 (0xd2c00000)
6461 #else /*ARCH_SIZE == 32 */
6462 # define add_R0_R0 (0x11000000)
6463 # define add_R0_R0_R1 (0x0b000020)
6464 # define add_R0_R1 (0x11400020)
6465 # define ldr_R0 (0x18000000)
6466 # define ldr_R0_mask(i) (i & 0xbfffffe0)
6467 # define ldr_R0_x0 (0xb9400000)
6468 # define ldr_hw_R0 (0x72a00000)
6469 # define movk_R0 (0x72800000)
6470 # define movz_R0 (0x52a00000)
6471 # define movz_hw_R0 (0x52c00000)
6472 #endif
6474 /* Structure to hold payload for _bfd_aarch64_erratum_843419_clear_stub,
6475 it is used to identify the stub information to reset. */
6477 struct erratum_843419_branch_to_stub_clear_data
6479 bfd_vma adrp_offset;
6480 asection *output_section;
6483 /* Clear the erratum information for GEN_ENTRY if the ADRP_OFFSET and
6484 section inside IN_ARG matches. The clearing is done by setting the
6485 stub_type to none. */
6487 static bool
6488 _bfd_aarch64_erratum_843419_clear_stub (struct bfd_hash_entry *gen_entry,
6489 void *in_arg)
6491 struct elf_aarch64_stub_hash_entry *stub_entry
6492 = (struct elf_aarch64_stub_hash_entry *) gen_entry;
6493 struct erratum_843419_branch_to_stub_clear_data *data
6494 = (struct erratum_843419_branch_to_stub_clear_data *) in_arg;
6496 if (stub_entry->target_section != data->output_section
6497 || stub_entry->stub_type != aarch64_stub_erratum_843419_veneer
6498 || stub_entry->adrp_offset != data->adrp_offset)
6499 return true;
6501 /* Change the stub type instead of removing the entry, removing from the hash
6502 table would be slower and we have already reserved the memory for the entry
6503 so there wouldn't be much gain. Changing the stub also keeps around a
6504 record of what was there before. */
6505 stub_entry->stub_type = aarch64_stub_none;
6507 /* We're done and there could have been only one matching stub at that
6508 particular offset, so abort further traversal. */
6509 return false;
6512 /* TLS Relaxations may relax an adrp sequence that matches the erratum 843419
6513 sequence. In this case the erratum no longer applies and we need to remove
6514 the entry from the pending stub generation. This clears matching adrp insn
6515 at ADRP_OFFSET in INPUT_SECTION in the stub table defined in GLOBALS. */
6517 static void
6518 clear_erratum_843419_entry (struct elf_aarch64_link_hash_table *globals,
6519 bfd_vma adrp_offset, asection *input_section)
6521 if (globals->fix_erratum_843419 & ERRAT_ADRP)
6523 struct erratum_843419_branch_to_stub_clear_data data;
6524 data.adrp_offset = adrp_offset;
6525 data.output_section = input_section;
6527 bfd_hash_traverse (&globals->stub_hash_table,
6528 _bfd_aarch64_erratum_843419_clear_stub, &data);
6532 /* Handle TLS relaxations. Relaxing is possible for symbols that use
6533 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
6534 link.
6536 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
6537 is to then call final_link_relocate. Return other values in the
6538 case of error. */
6540 static bfd_reloc_status_type
6541 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
6542 bfd *input_bfd, asection *input_section,
6543 bfd_byte *contents, Elf_Internal_Rela *rel,
6544 struct elf_link_hash_entry *h,
6545 struct bfd_link_info *info)
6547 bool local_exec = bfd_link_executable (info)
6548 && SYMBOL_REFERENCES_LOCAL (info, h);
6549 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
6550 unsigned long insn;
6552 BFD_ASSERT (globals && input_bfd && contents && rel);
6554 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type))
6556 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
6557 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
6558 if (local_exec)
6560 /* GD->LE relaxation:
6561 adrp x0, :tlsgd:var => movz R0, :tprel_g1:var
6563 adrp x0, :tlsdesc:var => movz R0, :tprel_g1:var
6565 Where R is x for LP64, and w for ILP32. */
6566 bfd_putl32 (movz_R0, contents + rel->r_offset);
6567 /* We have relaxed the adrp into a mov, we may have to clear any
6568 pending erratum fixes. */
6569 clear_erratum_843419_entry (globals, rel->r_offset, input_section);
6570 return bfd_reloc_continue;
6572 else
6574 /* GD->IE relaxation:
6575 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
6577 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
6579 return bfd_reloc_continue;
6582 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
6583 BFD_ASSERT (0);
6584 break;
6586 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
6587 if (local_exec)
6589 /* Tiny TLSDESC->LE relaxation:
6590 ldr x1, :tlsdesc:var => movz R0, #:tprel_g1:var
6591 adr x0, :tlsdesc:var => movk R0, #:tprel_g0_nc:var
6592 .tlsdesccall var
6593 blr x1 => nop
6595 Where R is x for LP64, and w for ILP32. */
6596 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
6597 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
6599 rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6600 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
6601 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6603 bfd_putl32 (movz_R0, contents + rel->r_offset);
6604 bfd_putl32 (movk_R0, contents + rel->r_offset + 4);
6605 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
6606 return bfd_reloc_continue;
6608 else
6610 /* Tiny TLSDESC->IE relaxation:
6611 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
6612 adr x0, :tlsdesc:var => nop
6613 .tlsdesccall var
6614 blr x1 => nop
6616 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
6617 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
6619 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6620 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6622 bfd_putl32 (ldr_R0, contents + rel->r_offset);
6623 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
6624 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
6625 return bfd_reloc_continue;
6628 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
6629 if (local_exec)
6631 /* Tiny GD->LE relaxation:
6632 adr x0, :tlsgd:var => mrs x1, tpidr_el0
6633 bl __tls_get_addr => add R0, R1, #:tprel_hi12:x, lsl #12
6634 nop => add R0, R0, #:tprel_lo12_nc:x
6636 Where R is x for LP64, and x for Ilp32. */
6638 /* First kill the tls_get_addr reloc on the bl instruction. */
6639 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6641 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 0);
6642 bfd_putl32 (add_R0_R1, contents + rel->r_offset + 4);
6643 bfd_putl32 (add_R0_R0, contents + rel->r_offset + 8);
6645 rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6646 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC));
6647 rel[1].r_offset = rel->r_offset + 8;
6649 /* Move the current relocation to the second instruction in
6650 the sequence. */
6651 rel->r_offset += 4;
6652 rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6653 AARCH64_R (TLSLE_ADD_TPREL_HI12));
6654 return bfd_reloc_continue;
6656 else
6658 /* Tiny GD->IE relaxation:
6659 adr x0, :tlsgd:var => ldr R0, :gottprel:var
6660 bl __tls_get_addr => mrs x1, tpidr_el0
6661 nop => add R0, R0, R1
6663 Where R is x for LP64, and w for Ilp32. */
6665 /* First kill the tls_get_addr reloc on the bl instruction. */
6666 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6667 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6669 bfd_putl32 (ldr_R0, contents + rel->r_offset);
6670 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
6671 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 8);
6672 return bfd_reloc_continue;
6675 #if ARCH_SIZE == 64
6676 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
6677 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSGD_MOVW_G0_NC));
6678 BFD_ASSERT (rel->r_offset + 12 == rel[2].r_offset);
6679 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (CALL26));
6681 if (local_exec)
6683 /* Large GD->LE relaxation:
6684 movz x0, #:tlsgd_g1:var => movz x0, #:tprel_g2:var, lsl #32
6685 movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
6686 add x0, gp, x0 => movk x0, #:tprel_g0_nc:var
6687 bl __tls_get_addr => mrs x1, tpidr_el0
6688 nop => add x0, x0, x1
6690 rel[2].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6691 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
6692 rel[2].r_offset = rel->r_offset + 8;
6694 bfd_putl32 (movz_hw_R0, contents + rel->r_offset + 0);
6695 bfd_putl32 (ldr_hw_R0, contents + rel->r_offset + 4);
6696 bfd_putl32 (movk_R0, contents + rel->r_offset + 8);
6697 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
6698 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 16);
6700 else
6702 /* Large GD->IE relaxation:
6703 movz x0, #:tlsgd_g1:var => movz x0, #:gottprel_g1:var, lsl #16
6704 movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
6705 add x0, gp, x0 => ldr x0, [gp, x0]
6706 bl __tls_get_addr => mrs x1, tpidr_el0
6707 nop => add x0, x0, x1
6709 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6710 bfd_putl32 (0xd2a80000, contents + rel->r_offset + 0);
6711 bfd_putl32 (ldr_R0, contents + rel->r_offset + 8);
6712 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
6713 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 16);
6715 return bfd_reloc_continue;
6717 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
6718 return bfd_reloc_continue;
6719 #endif
6721 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
6722 return bfd_reloc_continue;
6724 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
6725 if (local_exec)
6727 /* GD->LE relaxation:
6728 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
6730 Where R is x for lp64 mode, and w for ILP32 mode. */
6731 bfd_putl32 (movk_R0, contents + rel->r_offset);
6732 return bfd_reloc_continue;
6734 else
6736 /* GD->IE relaxation:
6737 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr R0, [x0, #:gottprel_lo12:var]
6739 Where R is x for lp64 mode, and w for ILP32 mode. */
6740 insn = bfd_getl32 (contents + rel->r_offset);
6741 bfd_putl32 (ldr_R0_mask (insn), contents + rel->r_offset);
6742 return bfd_reloc_continue;
6745 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
6746 if (local_exec)
6748 /* GD->LE relaxation
6749 add x0, #:tlsgd_lo12:var => movk R0, :tprel_g0_nc:var
6750 bl __tls_get_addr => mrs x1, tpidr_el0
6751 nop => add R0, R1, R0
6753 Where R is x for lp64 mode, and w for ILP32 mode. */
6755 /* First kill the tls_get_addr reloc on the bl instruction. */
6756 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6757 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6759 bfd_putl32 (movk_R0, contents + rel->r_offset);
6760 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
6761 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 8);
6762 return bfd_reloc_continue;
6764 else
6766 /* GD->IE relaxation
6767 ADD x0, #:tlsgd_lo12:var => ldr R0, [x0, #:gottprel_lo12:var]
6768 BL __tls_get_addr => mrs x1, tpidr_el0
6769 R_AARCH64_CALL26
6770 NOP => add R0, R1, R0
6772 Where R is x for lp64 mode, and w for ilp32 mode. */
6774 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
6776 /* Remove the relocation on the BL instruction. */
6777 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6779 /* We choose to fixup the BL and NOP instructions using the
6780 offset from the second relocation to allow flexibility in
6781 scheduling instructions between the ADD and BL. */
6782 bfd_putl32 (ldr_R0_x0, contents + rel->r_offset);
6783 bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
6784 bfd_putl32 (add_R0_R0_R1, contents + rel[1].r_offset + 4);
6785 return bfd_reloc_continue;
6788 case BFD_RELOC_AARCH64_TLSDESC_ADD:
6789 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
6790 case BFD_RELOC_AARCH64_TLSDESC_CALL:
6791 /* GD->IE/LE relaxation:
6792 add x0, x0, #:tlsdesc_lo12:var => nop
6793 blr xd => nop
6795 bfd_putl32 (INSN_NOP, contents + rel->r_offset);
6796 return bfd_reloc_ok;
6798 case BFD_RELOC_AARCH64_TLSDESC_LDR:
6799 if (local_exec)
6801 /* GD->LE relaxation:
6802 ldr xd, [gp, xn] => movk R0, #:tprel_g0_nc:var
6804 Where R is x for lp64 mode, and w for ILP32 mode. */
6805 bfd_putl32 (movk_R0, contents + rel->r_offset);
6806 return bfd_reloc_continue;
6808 else
6810 /* GD->IE relaxation:
6811 ldr xd, [gp, xn] => ldr R0, [gp, xn]
6813 Where R is x for lp64 mode, and w for ILP32 mode. */
6814 insn = bfd_getl32 (contents + rel->r_offset);
6815 bfd_putl32 (ldr_R0_mask (insn), contents + rel->r_offset);
6816 return bfd_reloc_ok;
6819 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
6820 /* GD->LE relaxation:
6821 movk xd, #:tlsdesc_off_g0_nc:var => movk R0, #:tprel_g1_nc:var, lsl #16
6822 GD->IE relaxation:
6823 movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
6825 Where R is x for lp64 mode, and w for ILP32 mode. */
6826 if (local_exec)
6827 bfd_putl32 (ldr_hw_R0, contents + rel->r_offset);
6828 return bfd_reloc_continue;
6830 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
6831 if (local_exec)
6833 /* GD->LE relaxation:
6834 movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
6836 Where R is x for lp64 mode, and w for ILP32 mode. */
6837 bfd_putl32 (movz_hw_R0, contents + rel->r_offset);
6838 return bfd_reloc_continue;
6840 else
6842 /* GD->IE relaxation:
6843 movz xd, #:tlsdesc_off_g1:var => movz Rd, #:gottprel_g1:var, lsl #16
6845 Where R is x for lp64 mode, and w for ILP32 mode. */
6846 insn = bfd_getl32 (contents + rel->r_offset);
6847 bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
6848 return bfd_reloc_continue;
6851 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
6852 /* IE->LE relaxation:
6853 adrp xd, :gottprel:var => movz Rd, :tprel_g1:var
6855 Where R is x for lp64 mode, and w for ILP32 mode. */
6856 if (local_exec)
6858 insn = bfd_getl32 (contents + rel->r_offset);
6859 bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
6860 /* We have relaxed the adrp into a mov, we may have to clear any
6861 pending erratum fixes. */
6862 clear_erratum_843419_entry (globals, rel->r_offset, input_section);
6864 return bfd_reloc_continue;
6866 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
6867 /* IE->LE relaxation:
6868 ldr xd, [xm, #:gottprel_lo12:var] => movk Rd, :tprel_g0_nc:var
6870 Where R is x for lp64 mode, and w for ILP32 mode. */
6871 if (local_exec)
6873 insn = bfd_getl32 (contents + rel->r_offset);
6874 bfd_putl32 (movk_R0 | (insn & 0x1f), contents + rel->r_offset);
6876 return bfd_reloc_continue;
6878 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
6879 /* LD->LE relaxation (tiny):
6880 adr x0, :tlsldm:x => mrs x0, tpidr_el0
6881 bl __tls_get_addr => add R0, R0, TCB_SIZE
6883 Where R is x for lp64 mode, and w for ilp32 mode. */
6884 if (local_exec)
6886 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6887 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
6888 /* No need of CALL26 relocation for tls_get_addr. */
6889 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6890 bfd_putl32 (0xd53bd040, contents + rel->r_offset + 0);
6891 bfd_putl32 (add_R0_R0 | (TCB_SIZE << 10),
6892 contents + rel->r_offset + 4);
6893 return bfd_reloc_ok;
6895 return bfd_reloc_continue;
6897 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
6898 /* LD->LE relaxation (small):
6899 adrp x0, :tlsldm:x => mrs x0, tpidr_el0
6901 if (local_exec)
6903 bfd_putl32 (0xd53bd040, contents + rel->r_offset);
6904 return bfd_reloc_ok;
6906 return bfd_reloc_continue;
6908 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
6909 /* LD->LE relaxation (small):
6910 add x0, #:tlsldm_lo12:x => add R0, R0, TCB_SIZE
6911 bl __tls_get_addr => nop
6913 Where R is x for lp64 mode, and w for ilp32 mode. */
6914 if (local_exec)
6916 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6917 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
6918 /* No need of CALL26 relocation for tls_get_addr. */
6919 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6920 bfd_putl32 (add_R0_R0 | (TCB_SIZE << 10),
6921 contents + rel->r_offset + 0);
6922 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
6923 return bfd_reloc_ok;
6925 return bfd_reloc_continue;
6927 default:
6928 return bfd_reloc_continue;
6931 return bfd_reloc_ok;
6934 /* Relocate an AArch64 ELF section. */
6936 static int
6937 elfNN_aarch64_relocate_section (bfd *output_bfd,
6938 struct bfd_link_info *info,
6939 bfd *input_bfd,
6940 asection *input_section,
6941 bfd_byte *contents,
6942 Elf_Internal_Rela *relocs,
6943 Elf_Internal_Sym *local_syms,
6944 asection **local_sections)
6946 Elf_Internal_Shdr *symtab_hdr;
6947 struct elf_link_hash_entry **sym_hashes;
6948 Elf_Internal_Rela *rel;
6949 Elf_Internal_Rela *relend;
6950 const char *name;
6951 struct elf_aarch64_link_hash_table *globals;
6952 bool save_addend = false;
6953 bfd_vma addend = 0;
6955 globals = elf_aarch64_hash_table (info);
6957 symtab_hdr = &elf_symtab_hdr (input_bfd);
6958 sym_hashes = elf_sym_hashes (input_bfd);
6960 rel = relocs;
6961 relend = relocs + input_section->reloc_count;
6962 for (; rel < relend; rel++)
6964 unsigned int r_type;
6965 bfd_reloc_code_real_type bfd_r_type;
6966 bfd_reloc_code_real_type relaxed_bfd_r_type;
6967 reloc_howto_type *howto;
6968 unsigned long r_symndx;
6969 Elf_Internal_Sym *sym;
6970 asection *sec;
6971 struct elf_link_hash_entry *h;
6972 bfd_vma relocation;
6973 bfd_reloc_status_type r;
6974 arelent bfd_reloc;
6975 char sym_type;
6976 bool unresolved_reloc = false;
6977 char *error_message = NULL;
6979 r_symndx = ELFNN_R_SYM (rel->r_info);
6980 r_type = ELFNN_R_TYPE (rel->r_info);
6982 bfd_reloc.howto = elfNN_aarch64_howto_from_type (input_bfd, r_type);
6983 howto = bfd_reloc.howto;
6985 if (howto == NULL)
6986 return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
6988 bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
6990 h = NULL;
6991 sym = NULL;
6992 sec = NULL;
6994 if (r_symndx < symtab_hdr->sh_info)
6996 sym = local_syms + r_symndx;
6997 sym_type = ELFNN_ST_TYPE (sym->st_info);
6998 sec = local_sections[r_symndx];
7000 /* An object file might have a reference to a local
7001 undefined symbol. This is a daft object file, but we
7002 should at least do something about it. NONE and NULL
7003 relocations do not use the symbol and are explicitly
7004 allowed to use an undefined one, so allow those.
7005 Likewise for relocations against STN_UNDEF. */
7006 if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
7007 && r_symndx != STN_UNDEF
7008 && bfd_is_und_section (sec)
7009 && ELF_ST_BIND (sym->st_info) != STB_WEAK)
7010 (*info->callbacks->undefined_symbol)
7011 (info, bfd_elf_string_from_elf_section
7012 (input_bfd, symtab_hdr->sh_link, sym->st_name),
7013 input_bfd, input_section, rel->r_offset, true);
7015 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
7017 /* Relocate against local STT_GNU_IFUNC symbol. */
7018 if (!bfd_link_relocatable (info)
7019 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
7021 h = elfNN_aarch64_get_local_sym_hash (globals, input_bfd,
7022 rel, false);
7023 if (h == NULL)
7024 abort ();
7026 /* Set STT_GNU_IFUNC symbol value. */
7027 h->root.u.def.value = sym->st_value;
7028 h->root.u.def.section = sec;
7031 else
7033 bool warned, ignored;
7035 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
7036 r_symndx, symtab_hdr, sym_hashes,
7037 h, sec, relocation,
7038 unresolved_reloc, warned, ignored);
7040 sym_type = h->type;
7043 if (sec != NULL && discarded_section (sec))
7044 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
7045 rel, 1, relend, howto, 0, contents);
7047 if (bfd_link_relocatable (info))
7048 continue;
7050 if (h != NULL)
7051 name = h->root.root.string;
7052 else
7054 name = (bfd_elf_string_from_elf_section
7055 (input_bfd, symtab_hdr->sh_link, sym->st_name));
7056 if (name == NULL || *name == '\0')
7057 name = bfd_section_name (sec);
7060 if (r_symndx != 0
7061 && r_type != R_AARCH64_NONE
7062 && r_type != R_AARCH64_NULL
7063 && (h == NULL
7064 || h->root.type == bfd_link_hash_defined
7065 || h->root.type == bfd_link_hash_defweak)
7066 && IS_AARCH64_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
7068 _bfd_error_handler
7069 ((sym_type == STT_TLS
7070 /* xgettext:c-format */
7071 ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
7072 /* xgettext:c-format */
7073 : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
7074 input_bfd,
7075 input_section, (uint64_t) rel->r_offset, howto->name, name);
7078 /* We relax only if we can see that there can be a valid transition
7079 from a reloc type to another.
7080 We call elfNN_aarch64_final_link_relocate unless we're completely
7081 done, i.e., the relaxation produced the final output we want. */
7083 relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
7084 h, r_symndx);
7085 if (relaxed_bfd_r_type != bfd_r_type)
7087 bfd_r_type = relaxed_bfd_r_type;
7088 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
7089 BFD_ASSERT (howto != NULL);
7090 r_type = howto->type;
7091 r = elfNN_aarch64_tls_relax (globals, input_bfd, input_section,
7092 contents, rel, h, info);
7093 unresolved_reloc = 0;
7095 else
7096 r = bfd_reloc_continue;
7098 /* There may be multiple consecutive relocations for the
7099 same offset. In that case we are supposed to treat the
7100 output of each relocation as the addend for the next. */
7101 if (rel + 1 < relend
7102 && rel->r_offset == rel[1].r_offset
7103 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NONE
7104 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NULL)
7105 save_addend = true;
7106 else
7107 save_addend = false;
7109 if (r == bfd_reloc_continue)
7110 r = elfNN_aarch64_final_link_relocate (howto, input_bfd, output_bfd,
7111 input_section, contents, rel,
7112 relocation, info, sec,
7113 h, &unresolved_reloc,
7114 save_addend, &addend, sym);
7116 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type))
7118 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
7119 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
7120 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
7121 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
7122 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
7123 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
7124 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
7125 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
7126 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
7128 bool need_relocs = false;
7129 bfd_byte *loc;
7130 int indx;
7131 bfd_vma off;
7133 off = symbol_got_offset (input_bfd, h, r_symndx);
7134 indx = h && h->dynindx != -1 ? h->dynindx : 0;
7136 need_relocs =
7137 (!bfd_link_executable (info) || indx != 0) &&
7138 (h == NULL
7139 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
7140 || h->root.type != bfd_link_hash_undefweak);
7142 BFD_ASSERT (globals->root.srelgot != NULL);
7144 if (need_relocs)
7146 Elf_Internal_Rela rela;
7147 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPMOD));
7148 rela.r_addend = 0;
7149 rela.r_offset = globals->root.sgot->output_section->vma +
7150 globals->root.sgot->output_offset + off;
7153 loc = globals->root.srelgot->contents;
7154 loc += globals->root.srelgot->reloc_count++
7155 * RELOC_SIZE (htab);
7156 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
7158 bfd_reloc_code_real_type real_type =
7159 elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
7161 if (real_type == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
7162 || real_type == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
7163 || real_type == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC)
7165 /* For local dynamic, don't generate DTPREL in any case.
7166 Initialize the DTPREL slot into zero, so we get module
7167 base address when invoke runtime TLS resolver. */
7168 bfd_put_NN (output_bfd, 0,
7169 globals->root.sgot->contents + off
7170 + GOT_ENTRY_SIZE);
7172 else if (indx == 0)
7174 bfd_put_NN (output_bfd,
7175 relocation - dtpoff_base (info),
7176 globals->root.sgot->contents + off
7177 + GOT_ENTRY_SIZE);
7179 else
7181 /* This TLS symbol is global. We emit a
7182 relocation to fixup the tls offset at load
7183 time. */
7184 rela.r_info =
7185 ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPREL));
7186 rela.r_addend = 0;
7187 rela.r_offset =
7188 (globals->root.sgot->output_section->vma
7189 + globals->root.sgot->output_offset + off
7190 + GOT_ENTRY_SIZE);
7192 loc = globals->root.srelgot->contents;
7193 loc += globals->root.srelgot->reloc_count++
7194 * RELOC_SIZE (globals);
7195 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
7196 bfd_put_NN (output_bfd, (bfd_vma) 0,
7197 globals->root.sgot->contents + off
7198 + GOT_ENTRY_SIZE);
7201 else
7203 bfd_put_NN (output_bfd, (bfd_vma) 1,
7204 globals->root.sgot->contents + off);
7205 bfd_put_NN (output_bfd,
7206 relocation - dtpoff_base (info),
7207 globals->root.sgot->contents + off
7208 + GOT_ENTRY_SIZE);
7211 symbol_got_offset_mark (input_bfd, h, r_symndx);
7213 break;
7215 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
7216 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
7217 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
7218 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
7219 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
7220 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
7222 bool need_relocs = false;
7223 bfd_byte *loc;
7224 int indx;
7225 bfd_vma off;
7227 off = symbol_got_offset (input_bfd, h, r_symndx);
7229 indx = h && h->dynindx != -1 ? h->dynindx : 0;
7231 need_relocs =
7232 (!bfd_link_executable (info) || indx != 0) &&
7233 (h == NULL
7234 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
7235 || h->root.type != bfd_link_hash_undefweak);
7237 BFD_ASSERT (globals->root.srelgot != NULL);
7239 if (need_relocs)
7241 Elf_Internal_Rela rela;
7243 if (indx == 0)
7244 rela.r_addend = relocation - dtpoff_base (info);
7245 else
7246 rela.r_addend = 0;
7248 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_TPREL));
7249 rela.r_offset = globals->root.sgot->output_section->vma +
7250 globals->root.sgot->output_offset + off;
7252 loc = globals->root.srelgot->contents;
7253 loc += globals->root.srelgot->reloc_count++
7254 * RELOC_SIZE (htab);
7256 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
7258 bfd_put_NN (output_bfd, rela.r_addend,
7259 globals->root.sgot->contents + off);
7261 else
7262 bfd_put_NN (output_bfd, relocation - tpoff_base (info),
7263 globals->root.sgot->contents + off);
7265 symbol_got_offset_mark (input_bfd, h, r_symndx);
7267 break;
7269 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
7270 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
7271 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
7272 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
7273 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
7274 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
7275 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
7276 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
7278 bool need_relocs = false;
7279 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
7280 bfd_vma off = symbol_tlsdesc_got_offset (input_bfd, h, r_symndx);
7282 need_relocs = (h == NULL
7283 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
7284 || h->root.type != bfd_link_hash_undefweak);
7286 BFD_ASSERT (globals->root.srelgot != NULL);
7287 BFD_ASSERT (globals->root.sgot != NULL);
7289 if (need_relocs)
7291 bfd_byte *loc;
7292 Elf_Internal_Rela rela;
7293 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
7295 rela.r_addend = 0;
7296 rela.r_offset = (globals->root.sgotplt->output_section->vma
7297 + globals->root.sgotplt->output_offset
7298 + off + globals->sgotplt_jump_table_size);
7300 if (indx == 0)
7301 rela.r_addend = relocation - dtpoff_base (info);
7303 /* Allocate the next available slot in the PLT reloc
7304 section to hold our R_AARCH64_TLSDESC, the next
7305 available slot is determined from reloc_count,
7306 which we step. But note, reloc_count was
7307 artifically moved down while allocating slots for
7308 real PLT relocs such that all of the PLT relocs
7309 will fit above the initial reloc_count and the
7310 extra stuff will fit below. */
7311 loc = globals->root.srelplt->contents;
7312 loc += globals->root.srelplt->reloc_count++
7313 * RELOC_SIZE (globals);
7315 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
7317 bfd_put_NN (output_bfd, (bfd_vma) 0,
7318 globals->root.sgotplt->contents + off +
7319 globals->sgotplt_jump_table_size);
7320 bfd_put_NN (output_bfd, (bfd_vma) 0,
7321 globals->root.sgotplt->contents + off +
7322 globals->sgotplt_jump_table_size +
7323 GOT_ENTRY_SIZE);
7326 symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
7328 break;
7329 default:
7330 break;
7333 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
7334 because such sections are not SEC_ALLOC and thus ld.so will
7335 not process them. */
7336 if (unresolved_reloc
7337 && !((input_section->flags & SEC_DEBUGGING) != 0
7338 && h->def_dynamic)
7339 && _bfd_elf_section_offset (output_bfd, info, input_section,
7340 +rel->r_offset) != (bfd_vma) - 1)
7342 _bfd_error_handler
7343 /* xgettext:c-format */
7344 (_("%pB(%pA+%#" PRIx64 "): "
7345 "unresolvable %s relocation against symbol `%s'"),
7346 input_bfd, input_section, (uint64_t) rel->r_offset, howto->name,
7347 h->root.root.string);
7348 return false;
7351 if (r != bfd_reloc_ok && r != bfd_reloc_continue)
7353 bfd_reloc_code_real_type real_r_type
7354 = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
7356 switch (r)
7358 case bfd_reloc_overflow:
7359 (*info->callbacks->reloc_overflow)
7360 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
7361 input_bfd, input_section, rel->r_offset);
7362 if (real_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
7363 || real_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
7365 (*info->callbacks->warning)
7366 (info,
7367 _("too many GOT entries for -fpic, "
7368 "please recompile with -fPIC"),
7369 name, input_bfd, input_section, rel->r_offset);
7370 return false;
7372 /* Overflow can occur when a variable is referenced with a type
7373 that has a larger alignment than the type with which it was
7374 declared. eg:
7375 file1.c: extern int foo; int a (void) { return foo; }
7376 file2.c: char bar, foo, baz;
7377 If the variable is placed into a data section at an offset
7378 that is incompatible with the larger alignment requirement
7379 overflow will occur. (Strictly speaking this is not overflow
7380 but rather an alignment problem, but the bfd_reloc_ error
7381 enum does not have a value to cover that situation).
7383 Try to catch this situation here and provide a more helpful
7384 error message to the user. */
7385 if (addend & (((bfd_vma) 1 << howto->rightshift) - 1)
7386 /* FIXME: Are we testing all of the appropriate reloc
7387 types here ? */
7388 && (real_r_type == BFD_RELOC_AARCH64_LD_LO19_PCREL
7389 || real_r_type == BFD_RELOC_AARCH64_LDST16_LO12
7390 || real_r_type == BFD_RELOC_AARCH64_LDST32_LO12
7391 || real_r_type == BFD_RELOC_AARCH64_LDST64_LO12
7392 || real_r_type == BFD_RELOC_AARCH64_LDST128_LO12))
7394 info->callbacks->warning
7395 (info, _("one possible cause of this error is that the \
7396 symbol is being referenced in the indicated code as if it had a larger \
7397 alignment than was declared where it was defined"),
7398 name, input_bfd, input_section, rel->r_offset);
7400 break;
7402 case bfd_reloc_undefined:
7403 (*info->callbacks->undefined_symbol)
7404 (info, name, input_bfd, input_section, rel->r_offset, true);
7405 break;
7407 case bfd_reloc_outofrange:
7408 error_message = _("out of range");
7409 goto common_error;
7411 case bfd_reloc_notsupported:
7412 error_message = _("unsupported relocation");
7413 goto common_error;
7415 case bfd_reloc_dangerous:
7416 /* error_message should already be set. */
7417 goto common_error;
7419 default:
7420 error_message = _("unknown error");
7421 /* Fall through. */
7423 common_error:
7424 BFD_ASSERT (error_message != NULL);
7425 (*info->callbacks->reloc_dangerous)
7426 (info, error_message, input_bfd, input_section, rel->r_offset);
7427 break;
7431 if (!save_addend)
7432 addend = 0;
7435 return true;
7438 /* Set the right machine number. */
7440 static bool
7441 elfNN_aarch64_object_p (bfd *abfd)
7443 #if ARCH_SIZE == 32
7444 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64_ilp32);
7445 #else
7446 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64);
7447 #endif
7448 return true;
7451 /* Function to keep AArch64 specific flags in the ELF header. */
7453 static bool
7454 elfNN_aarch64_set_private_flags (bfd *abfd, flagword flags)
7456 if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
7459 else
7461 elf_elfheader (abfd)->e_flags = flags;
7462 elf_flags_init (abfd) = true;
7465 return true;
7468 /* Merge backend specific data from an object file to the output
7469 object file when linking. */
7471 static bool
7472 elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
7474 bfd *obfd = info->output_bfd;
7475 flagword out_flags;
7476 flagword in_flags;
7477 bool flags_compatible = true;
7478 asection *sec;
7480 /* Check if we have the same endianess. */
7481 if (!_bfd_generic_verify_endian_match (ibfd, info))
7482 return false;
7484 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
7485 return true;
7487 /* The input BFD must have had its flags initialised. */
7488 /* The following seems bogus to me -- The flags are initialized in
7489 the assembler but I don't think an elf_flags_init field is
7490 written into the object. */
7491 /* BFD_ASSERT (elf_flags_init (ibfd)); */
7493 in_flags = elf_elfheader (ibfd)->e_flags;
7494 out_flags = elf_elfheader (obfd)->e_flags;
7496 if (!elf_flags_init (obfd))
7498 /* If the input is the default architecture and had the default
7499 flags then do not bother setting the flags for the output
7500 architecture, instead allow future merges to do this. If no
7501 future merges ever set these flags then they will retain their
7502 uninitialised values, which surprise surprise, correspond
7503 to the default values. */
7504 if (bfd_get_arch_info (ibfd)->the_default
7505 && elf_elfheader (ibfd)->e_flags == 0)
7506 return true;
7508 elf_flags_init (obfd) = true;
7509 elf_elfheader (obfd)->e_flags = in_flags;
7511 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
7512 && bfd_get_arch_info (obfd)->the_default)
7513 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
7514 bfd_get_mach (ibfd));
7516 return true;
7519 /* Identical flags must be compatible. */
7520 if (in_flags == out_flags)
7521 return true;
7523 /* Check to see if the input BFD actually contains any sections. If
7524 not, its flags may not have been initialised either, but it
7525 cannot actually cause any incompatiblity. Do not short-circuit
7526 dynamic objects; their section list may be emptied by
7527 elf_link_add_object_symbols.
7529 Also check to see if there are no code sections in the input.
7530 In this case there is no need to check for code specific flags.
7531 XXX - do we need to worry about floating-point format compatability
7532 in data sections ? */
7533 if (!(ibfd->flags & DYNAMIC))
7535 bool null_input_bfd = true;
7536 bool only_data_sections = true;
7538 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
7540 if ((bfd_section_flags (sec)
7541 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
7542 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
7543 only_data_sections = false;
7545 null_input_bfd = false;
7546 break;
7549 if (null_input_bfd || only_data_sections)
7550 return true;
7553 return flags_compatible;
7556 /* Display the flags field. */
7558 static bool
7559 elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
7561 FILE *file = (FILE *) ptr;
7562 unsigned long flags;
7564 BFD_ASSERT (abfd != NULL && ptr != NULL);
7566 /* Print normal ELF private data. */
7567 _bfd_elf_print_private_bfd_data (abfd, ptr);
7569 flags = elf_elfheader (abfd)->e_flags;
7570 /* Ignore init flag - it may not be set, despite the flags field
7571 containing valid data. */
7573 /* xgettext:c-format */
7574 fprintf (file, _("private flags = 0x%lx:"), elf_elfheader (abfd)->e_flags);
7576 if (flags)
7577 fprintf (file, _(" <Unrecognised flag bits set>"));
7579 fputc ('\n', file);
7581 return true;
7584 /* Return true if we need copy relocation against EH. */
7586 static bool
7587 need_copy_relocation_p (struct elf_aarch64_link_hash_entry *eh)
7589 struct elf_dyn_relocs *p;
7590 asection *s;
7592 for (p = eh->root.dyn_relocs; p != NULL; p = p->next)
7594 /* If there is any pc-relative reference, we need to keep copy relocation
7595 to avoid propagating the relocation into runtime that current glibc
7596 does not support. */
7597 if (p->pc_count)
7598 return true;
7600 s = p->sec->output_section;
7601 /* Need copy relocation if it's against read-only section. */
7602 if (s != NULL && (s->flags & SEC_READONLY) != 0)
7603 return true;
7606 return false;
7609 /* Adjust a symbol defined by a dynamic object and referenced by a
7610 regular object. The current definition is in some section of the
7611 dynamic object, but we're not including those sections. We have to
7612 change the definition to something the rest of the link can
7613 understand. */
7615 static bool
7616 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
7617 struct elf_link_hash_entry *h)
7619 struct elf_aarch64_link_hash_table *htab;
7620 asection *s, *srel;
7622 /* If this is a function, put it in the procedure linkage table. We
7623 will fill in the contents of the procedure linkage table later,
7624 when we know the address of the .got section. */
7625 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
7627 if (h->plt.refcount <= 0
7628 || (h->type != STT_GNU_IFUNC
7629 && (SYMBOL_CALLS_LOCAL (info, h)
7630 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
7631 && h->root.type == bfd_link_hash_undefweak))))
7633 /* This case can occur if we saw a CALL26 reloc in
7634 an input file, but the symbol wasn't referred to
7635 by a dynamic object or all references were
7636 garbage collected. In which case we can end up
7637 resolving. */
7638 h->plt.offset = (bfd_vma) - 1;
7639 h->needs_plt = 0;
7642 return true;
7644 else
7645 /* Otherwise, reset to -1. */
7646 h->plt.offset = (bfd_vma) - 1;
7649 /* If this is a weak symbol, and there is a real definition, the
7650 processor independent code will have arranged for us to see the
7651 real definition first, and we can just use the same value. */
7652 if (h->is_weakalias)
7654 struct elf_link_hash_entry *def = weakdef (h);
7655 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
7656 h->root.u.def.section = def->root.u.def.section;
7657 h->root.u.def.value = def->root.u.def.value;
7658 if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
7659 h->non_got_ref = def->non_got_ref;
7660 return true;
7663 /* If we are creating a shared library, we must presume that the
7664 only references to the symbol are via the global offset table.
7665 For such cases we need not do anything here; the relocations will
7666 be handled correctly by relocate_section. */
7667 if (bfd_link_pic (info))
7668 return true;
7670 /* If there are no references to this symbol that do not use the
7671 GOT, we don't need to generate a copy reloc. */
7672 if (!h->non_got_ref)
7673 return true;
7675 /* If -z nocopyreloc was given, we won't generate them either. */
7676 if (info->nocopyreloc)
7678 h->non_got_ref = 0;
7679 return true;
7682 if (ELIMINATE_COPY_RELOCS)
7684 struct elf_aarch64_link_hash_entry *eh;
7685 /* If we don't find any dynamic relocs in read-only sections, then
7686 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
7687 eh = (struct elf_aarch64_link_hash_entry *) h;
7688 if (!need_copy_relocation_p (eh))
7690 h->non_got_ref = 0;
7691 return true;
7695 /* We must allocate the symbol in our .dynbss section, which will
7696 become part of the .bss section of the executable. There will be
7697 an entry for this symbol in the .dynsym section. The dynamic
7698 object will contain position independent code, so all references
7699 from the dynamic object to this symbol will go through the global
7700 offset table. The dynamic linker will use the .dynsym entry to
7701 determine the address it must put in the global offset table, so
7702 both the dynamic object and the regular object will refer to the
7703 same memory location for the variable. */
7705 htab = elf_aarch64_hash_table (info);
7707 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
7708 to copy the initial value out of the dynamic object and into the
7709 runtime process image. */
7710 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
7712 s = htab->root.sdynrelro;
7713 srel = htab->root.sreldynrelro;
7715 else
7717 s = htab->root.sdynbss;
7718 srel = htab->root.srelbss;
7720 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
7722 srel->size += RELOC_SIZE (htab);
7723 h->needs_copy = 1;
7726 return _bfd_elf_adjust_dynamic_copy (info, h, s);
7730 static bool
7731 elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
7733 struct elf_aarch64_local_symbol *locals;
7734 locals = elf_aarch64_locals (abfd);
7735 if (locals == NULL)
7737 locals = (struct elf_aarch64_local_symbol *)
7738 bfd_zalloc (abfd, number * sizeof (struct elf_aarch64_local_symbol));
7739 if (locals == NULL)
7740 return false;
7741 elf_aarch64_locals (abfd) = locals;
7743 return true;
7746 /* Create the .got section to hold the global offset table. */
7748 static bool
7749 aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
7751 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7752 flagword flags;
7753 asection *s;
7754 struct elf_link_hash_entry *h;
7755 struct elf_link_hash_table *htab = elf_hash_table (info);
7757 /* This function may be called more than once. */
7758 if (htab->sgot != NULL)
7759 return true;
7761 flags = bed->dynamic_sec_flags;
7763 s = bfd_make_section_anyway_with_flags (abfd,
7764 (bed->rela_plts_and_copies_p
7765 ? ".rela.got" : ".rel.got"),
7766 (bed->dynamic_sec_flags
7767 | SEC_READONLY));
7768 if (s == NULL
7769 || !bfd_set_section_alignment (s, bed->s->log_file_align))
7770 return false;
7771 htab->srelgot = s;
7773 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
7774 if (s == NULL
7775 || !bfd_set_section_alignment (s, bed->s->log_file_align))
7776 return false;
7777 htab->sgot = s;
7778 htab->sgot->size += GOT_ENTRY_SIZE;
7780 if (bed->want_got_sym)
7782 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
7783 (or .got.plt) section. We don't do this in the linker script
7784 because we don't want to define the symbol if we are not creating
7785 a global offset table. */
7786 h = _bfd_elf_define_linkage_sym (abfd, info, s,
7787 "_GLOBAL_OFFSET_TABLE_");
7788 elf_hash_table (info)->hgot = h;
7789 if (h == NULL)
7790 return false;
7793 if (bed->want_got_plt)
7795 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
7796 if (s == NULL
7797 || !bfd_set_section_alignment (s, bed->s->log_file_align))
7798 return false;
7799 htab->sgotplt = s;
7802 /* The first bit of the global offset table is the header. */
7803 s->size += bed->got_header_size;
7805 return true;
7808 /* Look through the relocs for a section during the first phase. */
7810 static bool
7811 elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
7812 asection *sec, const Elf_Internal_Rela *relocs)
7814 Elf_Internal_Shdr *symtab_hdr;
7815 struct elf_link_hash_entry **sym_hashes;
7816 const Elf_Internal_Rela *rel;
7817 const Elf_Internal_Rela *rel_end;
7818 asection *sreloc;
7820 struct elf_aarch64_link_hash_table *htab;
7822 if (bfd_link_relocatable (info))
7823 return true;
7825 BFD_ASSERT (is_aarch64_elf (abfd));
7827 htab = elf_aarch64_hash_table (info);
7828 sreloc = NULL;
7830 symtab_hdr = &elf_symtab_hdr (abfd);
7831 sym_hashes = elf_sym_hashes (abfd);
7833 rel_end = relocs + sec->reloc_count;
7834 for (rel = relocs; rel < rel_end; rel++)
7836 struct elf_link_hash_entry *h;
7837 unsigned int r_symndx;
7838 unsigned int r_type;
7839 bfd_reloc_code_real_type bfd_r_type;
7840 Elf_Internal_Sym *isym;
7842 r_symndx = ELFNN_R_SYM (rel->r_info);
7843 r_type = ELFNN_R_TYPE (rel->r_info);
7845 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
7847 /* xgettext:c-format */
7848 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
7849 return false;
7852 if (r_symndx < symtab_hdr->sh_info)
7854 /* A local symbol. */
7855 isym = bfd_sym_from_r_symndx (&htab->root.sym_cache,
7856 abfd, r_symndx);
7857 if (isym == NULL)
7858 return false;
7860 /* Check relocation against local STT_GNU_IFUNC symbol. */
7861 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
7863 h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel,
7864 true);
7865 if (h == NULL)
7866 return false;
7868 /* Fake a STT_GNU_IFUNC symbol. */
7869 h->type = STT_GNU_IFUNC;
7870 h->def_regular = 1;
7871 h->ref_regular = 1;
7872 h->forced_local = 1;
7873 h->root.type = bfd_link_hash_defined;
7875 else
7876 h = NULL;
7878 else
7880 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
7881 while (h->root.type == bfd_link_hash_indirect
7882 || h->root.type == bfd_link_hash_warning)
7883 h = (struct elf_link_hash_entry *) h->root.u.i.link;
7886 /* Could be done earlier, if h were already available. */
7887 bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
7889 if (h != NULL)
7891 /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
7892 This shows up in particular in an R_AARCH64_PREL64 in large model
7893 when calculating the pc-relative address to .got section which is
7894 used to initialize the gp register. */
7895 if (h->root.root.string
7896 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
7898 if (htab->root.dynobj == NULL)
7899 htab->root.dynobj = abfd;
7901 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
7902 return false;
7904 BFD_ASSERT (h == htab->root.hgot);
7907 /* Create the ifunc sections for static executables. If we
7908 never see an indirect function symbol nor we are building
7909 a static executable, those sections will be empty and
7910 won't appear in output. */
7911 switch (bfd_r_type)
7913 default:
7914 break;
7916 case BFD_RELOC_AARCH64_ADD_LO12:
7917 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
7918 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
7919 case BFD_RELOC_AARCH64_CALL26:
7920 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
7921 case BFD_RELOC_AARCH64_JUMP26:
7922 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
7923 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
7924 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
7925 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
7926 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
7927 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
7928 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
7929 case BFD_RELOC_AARCH64_NN:
7930 if (htab->root.dynobj == NULL)
7931 htab->root.dynobj = abfd;
7932 if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
7933 return false;
7934 break;
7937 /* It is referenced by a non-shared object. */
7938 h->ref_regular = 1;
7941 switch (bfd_r_type)
7943 case BFD_RELOC_AARCH64_16:
7944 #if ARCH_SIZE == 64
7945 case BFD_RELOC_AARCH64_32:
7946 #endif
7947 if (bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0)
7949 if (h != NULL
7950 /* This is an absolute symbol. It represents a value instead
7951 of an address. */
7952 && (bfd_is_abs_symbol (&h->root)
7953 /* This is an undefined symbol. */
7954 || h->root.type == bfd_link_hash_undefined))
7955 break;
7957 /* For local symbols, defined global symbols in a non-ABS section,
7958 it is assumed that the value is an address. */
7959 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
7960 _bfd_error_handler
7961 /* xgettext:c-format */
7962 (_("%pB: relocation %s against `%s' can not be used when making "
7963 "a shared object"),
7964 abfd, elfNN_aarch64_howto_table[howto_index].name,
7965 (h) ? h->root.root.string : "a local symbol");
7966 bfd_set_error (bfd_error_bad_value);
7967 return false;
7969 else
7970 break;
7972 case BFD_RELOC_AARCH64_MOVW_G0_NC:
7973 case BFD_RELOC_AARCH64_MOVW_G1_NC:
7974 case BFD_RELOC_AARCH64_MOVW_G2_NC:
7975 case BFD_RELOC_AARCH64_MOVW_G3:
7976 if (bfd_link_pic (info))
7978 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
7979 _bfd_error_handler
7980 /* xgettext:c-format */
7981 (_("%pB: relocation %s against `%s' can not be used when making "
7982 "a shared object; recompile with -fPIC"),
7983 abfd, elfNN_aarch64_howto_table[howto_index].name,
7984 (h) ? h->root.root.string : "a local symbol");
7985 bfd_set_error (bfd_error_bad_value);
7986 return false;
7988 /* Fall through. */
7990 case BFD_RELOC_AARCH64_16_PCREL:
7991 case BFD_RELOC_AARCH64_32_PCREL:
7992 case BFD_RELOC_AARCH64_64_PCREL:
7993 case BFD_RELOC_AARCH64_ADD_LO12:
7994 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
7995 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
7996 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
7997 case BFD_RELOC_AARCH64_LDST128_LO12:
7998 case BFD_RELOC_AARCH64_LDST16_LO12:
7999 case BFD_RELOC_AARCH64_LDST32_LO12:
8000 case BFD_RELOC_AARCH64_LDST64_LO12:
8001 case BFD_RELOC_AARCH64_LDST8_LO12:
8002 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
8003 if (h == NULL || bfd_link_pic (info))
8004 break;
8005 /* Fall through. */
8007 case BFD_RELOC_AARCH64_NN:
8009 /* We don't need to handle relocs into sections not going into
8010 the "real" output. */
8011 if ((sec->flags & SEC_ALLOC) == 0)
8012 break;
8014 if (h != NULL)
8016 if (!bfd_link_pic (info))
8017 h->non_got_ref = 1;
8019 h->plt.refcount += 1;
8020 h->pointer_equality_needed = 1;
8023 /* No need to do anything if we're not creating a shared
8024 object. */
8025 if (!(bfd_link_pic (info)
8026 /* If on the other hand, we are creating an executable, we
8027 may need to keep relocations for symbols satisfied by a
8028 dynamic library if we manage to avoid copy relocs for the
8029 symbol.
8031 NOTE: Currently, there is no support of copy relocs
8032 elimination on pc-relative relocation types, because there is
8033 no dynamic relocation support for them in glibc. We still
8034 record the dynamic symbol reference for them. This is
8035 because one symbol may be referenced by both absolute
8036 relocation (for example, BFD_RELOC_AARCH64_NN) and
8037 pc-relative relocation. We need full symbol reference
8038 information to make correct decision later in
8039 elfNN_aarch64_adjust_dynamic_symbol. */
8040 || (ELIMINATE_COPY_RELOCS
8041 && !bfd_link_pic (info)
8042 && h != NULL
8043 && (h->root.type == bfd_link_hash_defweak
8044 || !h->def_regular))))
8045 break;
8048 struct elf_dyn_relocs *p;
8049 struct elf_dyn_relocs **head;
8050 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
8052 /* We must copy these reloc types into the output file.
8053 Create a reloc section in dynobj and make room for
8054 this reloc. */
8055 if (sreloc == NULL)
8057 if (htab->root.dynobj == NULL)
8058 htab->root.dynobj = abfd;
8060 sreloc = _bfd_elf_make_dynamic_reloc_section
8061 (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ true);
8063 if (sreloc == NULL)
8064 return false;
8067 /* If this is a global symbol, we count the number of
8068 relocations we need for this symbol. */
8069 if (h != NULL)
8071 head = &h->dyn_relocs;
8073 else
8075 /* Track dynamic relocs needed for local syms too.
8076 We really need local syms available to do this
8077 easily. Oh well. */
8079 asection *s;
8080 void **vpp;
8082 isym = bfd_sym_from_r_symndx (&htab->root.sym_cache,
8083 abfd, r_symndx);
8084 if (isym == NULL)
8085 return false;
8087 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
8088 if (s == NULL)
8089 s = sec;
8091 /* Beware of type punned pointers vs strict aliasing
8092 rules. */
8093 vpp = &(elf_section_data (s)->local_dynrel);
8094 head = (struct elf_dyn_relocs **) vpp;
8097 p = *head;
8098 if (p == NULL || p->sec != sec)
8100 size_t amt = sizeof *p;
8101 p = ((struct elf_dyn_relocs *)
8102 bfd_zalloc (htab->root.dynobj, amt));
8103 if (p == NULL)
8104 return false;
8105 p->next = *head;
8106 *head = p;
8107 p->sec = sec;
8110 p->count += 1;
8112 if (elfNN_aarch64_howto_table[howto_index].pc_relative)
8113 p->pc_count += 1;
8115 break;
8117 /* RR: We probably want to keep a consistency check that
8118 there are no dangling GOT_PAGE relocs. */
8119 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
8120 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
8121 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
8122 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
8123 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
8124 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
8125 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
8126 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
8127 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
8128 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
8129 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
8130 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
8131 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
8132 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
8133 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
8134 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
8135 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
8136 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
8137 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
8138 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
8139 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
8140 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
8141 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
8142 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
8143 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
8144 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
8145 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
8146 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
8147 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
8148 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
8149 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
8151 unsigned got_type;
8152 unsigned old_got_type;
8154 got_type = aarch64_reloc_got_type (bfd_r_type);
8156 if (h)
8158 h->got.refcount += 1;
8159 old_got_type = elf_aarch64_hash_entry (h)->got_type;
8161 else
8163 struct elf_aarch64_local_symbol *locals;
8165 if (!elfNN_aarch64_allocate_local_symbols
8166 (abfd, symtab_hdr->sh_info))
8167 return false;
8169 locals = elf_aarch64_locals (abfd);
8170 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
8171 locals[r_symndx].got_refcount += 1;
8172 old_got_type = locals[r_symndx].got_type;
8175 /* If a variable is accessed with both general dynamic TLS
8176 methods, two slots may be created. */
8177 if (GOT_TLS_GD_ANY_P (old_got_type) && GOT_TLS_GD_ANY_P (got_type))
8178 got_type |= old_got_type;
8180 /* We will already have issued an error message if there
8181 is a TLS/non-TLS mismatch, based on the symbol type.
8182 So just combine any TLS types needed. */
8183 if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
8184 && got_type != GOT_NORMAL)
8185 got_type |= old_got_type;
8187 /* If the symbol is accessed by both IE and GD methods, we
8188 are able to relax. Turn off the GD flag, without
8189 messing up with any other kind of TLS types that may be
8190 involved. */
8191 if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
8192 got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
8194 if (old_got_type != got_type)
8196 if (h != NULL)
8197 elf_aarch64_hash_entry (h)->got_type = got_type;
8198 else
8200 struct elf_aarch64_local_symbol *locals;
8201 locals = elf_aarch64_locals (abfd);
8202 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
8203 locals[r_symndx].got_type = got_type;
8207 if (htab->root.dynobj == NULL)
8208 htab->root.dynobj = abfd;
8209 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
8210 return false;
8211 break;
8214 case BFD_RELOC_AARCH64_CALL26:
8215 case BFD_RELOC_AARCH64_JUMP26:
8216 /* If this is a local symbol then we resolve it
8217 directly without creating a PLT entry. */
8218 if (h == NULL)
8219 continue;
8221 h->needs_plt = 1;
8222 if (h->plt.refcount <= 0)
8223 h->plt.refcount = 1;
8224 else
8225 h->plt.refcount += 1;
8226 break;
8228 default:
8229 break;
8233 return true;
8236 /* Treat mapping symbols as special target symbols. */
8238 static bool
8239 elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED,
8240 asymbol *sym)
8242 return bfd_is_aarch64_special_symbol_name (sym->name,
8243 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
8246 /* If the ELF symbol SYM might be a function in SEC, return the
8247 function size and set *CODE_OFF to the function's entry point,
8248 otherwise return zero. */
8250 static bfd_size_type
8251 elfNN_aarch64_maybe_function_sym (const asymbol *sym, asection *sec,
8252 bfd_vma *code_off)
8254 bfd_size_type size;
8255 elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
8257 if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
8258 | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
8259 || sym->section != sec)
8260 return 0;
8262 size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
8264 if (!(sym->flags & BSF_SYNTHETIC))
8265 switch (ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info))
8267 case STT_NOTYPE:
8268 /* Ignore symbols created by the annobin plugin for gcc and clang.
8269 These symbols are hidden, local, notype and have a size of 0. */
8270 if (size == 0
8271 && sym->flags & BSF_LOCAL
8272 && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
8273 return 0;
8274 /* Fall through. */
8275 case STT_FUNC:
8276 /* FIXME: Allow STT_GNU_IFUNC as well ? */
8277 break;
8278 default:
8279 return 0;
8282 if ((sym->flags & BSF_LOCAL)
8283 && bfd_is_aarch64_special_symbol_name (sym->name,
8284 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY))
8285 return 0;
8287 *code_off = sym->value;
8289 /* Do not return 0 for the function's size. */
8290 return size ? size : 1;
8293 static bool
8294 elfNN_aarch64_find_inliner_info (bfd *abfd,
8295 const char **filename_ptr,
8296 const char **functionname_ptr,
8297 unsigned int *line_ptr)
8299 bool found;
8300 found = _bfd_dwarf2_find_inliner_info
8301 (abfd, filename_ptr,
8302 functionname_ptr, line_ptr, &elf_tdata (abfd)->dwarf2_find_line_info);
8303 return found;
8307 static bool
8308 elfNN_aarch64_init_file_header (bfd *abfd, struct bfd_link_info *link_info)
8310 Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
8312 if (!_bfd_elf_init_file_header (abfd, link_info))
8313 return false;
8315 i_ehdrp = elf_elfheader (abfd);
8316 i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
8317 return true;
8320 static enum elf_reloc_type_class
8321 elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
8322 const asection *rel_sec ATTRIBUTE_UNUSED,
8323 const Elf_Internal_Rela *rela)
8325 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
8327 if (htab->root.dynsym != NULL
8328 && htab->root.dynsym->contents != NULL)
8330 /* Check relocation against STT_GNU_IFUNC symbol if there are
8331 dynamic symbols. */
8332 bfd *abfd = info->output_bfd;
8333 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
8334 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
8335 if (r_symndx != STN_UNDEF)
8337 Elf_Internal_Sym sym;
8338 if (!bed->s->swap_symbol_in (abfd,
8339 (htab->root.dynsym->contents
8340 + r_symndx * bed->s->sizeof_sym),
8341 0, &sym))
8343 /* xgettext:c-format */
8344 _bfd_error_handler (_("%pB symbol number %lu references"
8345 " nonexistent SHT_SYMTAB_SHNDX section"),
8346 abfd, r_symndx);
8347 /* Ideally an error class should be returned here. */
8349 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
8350 return reloc_class_ifunc;
8354 switch ((int) ELFNN_R_TYPE (rela->r_info))
8356 case AARCH64_R (IRELATIVE):
8357 return reloc_class_ifunc;
8358 case AARCH64_R (RELATIVE):
8359 return reloc_class_relative;
8360 case AARCH64_R (JUMP_SLOT):
8361 return reloc_class_plt;
8362 case AARCH64_R (COPY):
8363 return reloc_class_copy;
8364 default:
8365 return reloc_class_normal;
8369 /* Handle an AArch64 specific section when reading an object file. This is
8370 called when bfd_section_from_shdr finds a section with an unknown
8371 type. */
8373 static bool
8374 elfNN_aarch64_section_from_shdr (bfd *abfd,
8375 Elf_Internal_Shdr *hdr,
8376 const char *name, int shindex)
8378 /* There ought to be a place to keep ELF backend specific flags, but
8379 at the moment there isn't one. We just keep track of the
8380 sections by their name, instead. Fortunately, the ABI gives
8381 names for all the AArch64 specific sections, so we will probably get
8382 away with this. */
8383 switch (hdr->sh_type)
8385 case SHT_AARCH64_ATTRIBUTES:
8386 break;
8388 default:
8389 return false;
8392 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
8393 return false;
8395 return true;
8398 /* Process any AArch64-specific program segment types. */
8400 static bool
8401 elfNN_aarch64_section_from_phdr (bfd *abfd ATTRIBUTE_UNUSED,
8402 Elf_Internal_Phdr *hdr,
8403 int hdr_index ATTRIBUTE_UNUSED,
8404 const char *name ATTRIBUTE_UNUSED)
8406 /* Right now we only handle the PT_AARCH64_MEMTAG_MTE segment type. */
8407 if (hdr == NULL || hdr->p_type != PT_AARCH64_MEMTAG_MTE)
8408 return false;
8410 if (hdr->p_filesz > 0)
8412 /* Sections created from memory tag p_type's are always named
8413 "memtag". This makes it easier for tools (for example, GDB)
8414 to find them. */
8415 asection *newsect = bfd_make_section_anyway (abfd, "memtag");
8417 if (newsect == NULL)
8418 return false;
8420 unsigned int opb = bfd_octets_per_byte (abfd, NULL);
8422 /* p_vaddr holds the original start address of the tagged memory
8423 range. */
8424 newsect->vma = hdr->p_vaddr / opb;
8426 /* p_filesz holds the storage size of the packed tags. */
8427 newsect->size = hdr->p_filesz;
8428 newsect->filepos = hdr->p_offset;
8430 /* p_memsz holds the size of the memory range that contains tags. The
8431 section's rawsize field is reused for this purpose. */
8432 newsect->rawsize = hdr->p_memsz;
8434 /* Make sure the section's flags has SEC_HAS_CONTENTS set, otherwise
8435 BFD will return all zeroes when attempting to get contents from this
8436 section. */
8437 newsect->flags |= SEC_HAS_CONTENTS;
8440 return true;
8443 /* Implements the bfd_elf_modify_headers hook for aarch64. */
8445 static bool
8446 elfNN_aarch64_modify_headers (bfd *abfd,
8447 struct bfd_link_info *info)
8449 struct elf_segment_map *m;
8450 unsigned int segment_count = 0;
8451 Elf_Internal_Phdr *p;
8453 for (m = elf_seg_map (abfd); m != NULL; m = m->next, segment_count++)
8455 /* We are only interested in the memory tag segment that will be dumped
8456 to a core file. If we have no memory tags or this isn't a core file we
8457 are dealing with, just skip this segment. */
8458 if (m->p_type != PT_AARCH64_MEMTAG_MTE
8459 || bfd_get_format (abfd) != bfd_core)
8460 continue;
8462 /* For memory tag segments in core files, the size of the file contents
8463 is smaller than the size of the memory range. Adjust the memory size
8464 accordingly. The real memory size is held in the section's rawsize
8465 field. */
8466 if (m->count > 0)
8468 p = elf_tdata (abfd)->phdr;
8469 p += m->idx;
8470 p->p_memsz = m->sections[0]->rawsize;
8471 p->p_flags = 0;
8472 p->p_paddr = 0;
8473 p->p_align = 0;
8477 /* Give the generic code a chance to handle the headers. */
8478 return _bfd_elf_modify_headers (abfd, info);
8481 /* A structure used to record a list of sections, independently
8482 of the next and prev fields in the asection structure. */
8483 typedef struct section_list
8485 asection *sec;
8486 struct section_list *next;
8487 struct section_list *prev;
8489 section_list;
8491 /* Unfortunately we need to keep a list of sections for which
8492 an _aarch64_elf_section_data structure has been allocated. This
8493 is because it is possible for functions like elfNN_aarch64_write_section
8494 to be called on a section which has had an elf_data_structure
8495 allocated for it (and so the used_by_bfd field is valid) but
8496 for which the AArch64 extended version of this structure - the
8497 _aarch64_elf_section_data structure - has not been allocated. */
8498 static section_list *sections_with_aarch64_elf_section_data = NULL;
8500 static void
8501 record_section_with_aarch64_elf_section_data (asection *sec)
8503 struct section_list *entry;
8505 entry = bfd_malloc (sizeof (*entry));
8506 if (entry == NULL)
8507 return;
8508 entry->sec = sec;
8509 entry->next = sections_with_aarch64_elf_section_data;
8510 entry->prev = NULL;
8511 if (entry->next != NULL)
8512 entry->next->prev = entry;
8513 sections_with_aarch64_elf_section_data = entry;
8516 static struct section_list *
8517 find_aarch64_elf_section_entry (asection *sec)
8519 struct section_list *entry;
8520 static struct section_list *last_entry = NULL;
8522 /* This is a short cut for the typical case where the sections are added
8523 to the sections_with_aarch64_elf_section_data list in forward order and
8524 then looked up here in backwards order. This makes a real difference
8525 to the ld-srec/sec64k.exp linker test. */
8526 entry = sections_with_aarch64_elf_section_data;
8527 if (last_entry != NULL)
8529 if (last_entry->sec == sec)
8530 entry = last_entry;
8531 else if (last_entry->next != NULL && last_entry->next->sec == sec)
8532 entry = last_entry->next;
8535 for (; entry; entry = entry->next)
8536 if (entry->sec == sec)
8537 break;
8539 if (entry)
8540 /* Record the entry prior to this one - it is the entry we are
8541 most likely to want to locate next time. Also this way if we
8542 have been called from
8543 unrecord_section_with_aarch64_elf_section_data () we will not
8544 be caching a pointer that is about to be freed. */
8545 last_entry = entry->prev;
8547 return entry;
8550 static void
8551 unrecord_section_with_aarch64_elf_section_data (asection *sec)
8553 struct section_list *entry;
8555 entry = find_aarch64_elf_section_entry (sec);
8557 if (entry)
8559 if (entry->prev != NULL)
8560 entry->prev->next = entry->next;
8561 if (entry->next != NULL)
8562 entry->next->prev = entry->prev;
8563 if (entry == sections_with_aarch64_elf_section_data)
8564 sections_with_aarch64_elf_section_data = entry->next;
8565 free (entry);
8570 typedef struct
8572 void *finfo;
8573 struct bfd_link_info *info;
8574 asection *sec;
8575 int sec_shndx;
8576 int (*func) (void *, const char *, Elf_Internal_Sym *,
8577 asection *, struct elf_link_hash_entry *);
8578 } output_arch_syminfo;
8580 enum map_symbol_type
8582 AARCH64_MAP_INSN,
8583 AARCH64_MAP_DATA
8587 /* Output a single mapping symbol. */
8589 static bool
8590 elfNN_aarch64_output_map_sym (output_arch_syminfo *osi,
8591 enum map_symbol_type type, bfd_vma offset)
8593 static const char *names[2] = { "$x", "$d" };
8594 Elf_Internal_Sym sym;
8596 sym.st_value = (osi->sec->output_section->vma
8597 + osi->sec->output_offset + offset);
8598 sym.st_size = 0;
8599 sym.st_other = 0;
8600 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
8601 sym.st_shndx = osi->sec_shndx;
8602 return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
8605 /* Output a single local symbol for a generated stub. */
8607 static bool
8608 elfNN_aarch64_output_stub_sym (output_arch_syminfo *osi, const char *name,
8609 bfd_vma offset, bfd_vma size)
8611 Elf_Internal_Sym sym;
8613 sym.st_value = (osi->sec->output_section->vma
8614 + osi->sec->output_offset + offset);
8615 sym.st_size = size;
8616 sym.st_other = 0;
8617 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
8618 sym.st_shndx = osi->sec_shndx;
8619 return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
8622 static bool
8623 aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
8625 struct elf_aarch64_stub_hash_entry *stub_entry;
8626 asection *stub_sec;
8627 bfd_vma addr;
8628 char *stub_name;
8629 output_arch_syminfo *osi;
8631 /* Massage our args to the form they really have. */
8632 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
8633 osi = (output_arch_syminfo *) in_arg;
8635 stub_sec = stub_entry->stub_sec;
8637 /* Ensure this stub is attached to the current section being
8638 processed. */
8639 if (stub_sec != osi->sec)
8640 return true;
8642 addr = (bfd_vma) stub_entry->stub_offset;
8644 stub_name = stub_entry->output_name;
8646 switch (stub_entry->stub_type)
8648 case aarch64_stub_adrp_branch:
8649 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
8650 sizeof (aarch64_adrp_branch_stub)))
8651 return false;
8652 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8653 return false;
8654 break;
8655 case aarch64_stub_long_branch:
8656 if (!elfNN_aarch64_output_stub_sym
8657 (osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
8658 return false;
8659 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8660 return false;
8661 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_DATA, addr + 16))
8662 return false;
8663 break;
8664 case aarch64_stub_bti_direct_branch:
8665 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
8666 sizeof (aarch64_bti_direct_branch_stub)))
8667 return false;
8668 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8669 return false;
8670 break;
8671 case aarch64_stub_erratum_835769_veneer:
8672 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
8673 sizeof (aarch64_erratum_835769_stub)))
8674 return false;
8675 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8676 return false;
8677 break;
8678 case aarch64_stub_erratum_843419_veneer:
8679 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
8680 sizeof (aarch64_erratum_843419_stub)))
8681 return false;
8682 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8683 return false;
8684 break;
8685 case aarch64_stub_none:
8686 break;
8688 default:
8689 abort ();
8692 return true;
8695 /* Output mapping symbols for linker generated sections. */
8697 static bool
8698 elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
8699 struct bfd_link_info *info,
8700 void *finfo,
8701 int (*func) (void *, const char *,
8702 Elf_Internal_Sym *,
8703 asection *,
8704 struct elf_link_hash_entry
8707 output_arch_syminfo osi;
8708 struct elf_aarch64_link_hash_table *htab;
8710 if (info->strip == strip_all
8711 && !info->emitrelocations
8712 && !bfd_link_relocatable (info))
8713 return true;
8715 htab = elf_aarch64_hash_table (info);
8717 osi.finfo = finfo;
8718 osi.info = info;
8719 osi.func = func;
8721 /* Long calls stubs. */
8722 if (htab->stub_bfd && htab->stub_bfd->sections)
8724 asection *stub_sec;
8726 for (stub_sec = htab->stub_bfd->sections;
8727 stub_sec != NULL; stub_sec = stub_sec->next)
8729 /* Ignore non-stub sections. */
8730 if (!strstr (stub_sec->name, STUB_SUFFIX))
8731 continue;
8733 osi.sec = stub_sec;
8735 osi.sec_shndx = _bfd_elf_section_from_bfd_section
8736 (output_bfd, osi.sec->output_section);
8738 /* The first instruction in a stub is always a branch. */
8739 if (!elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0))
8740 return false;
8742 bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
8743 &osi);
8747 /* Finally, output mapping symbols for the PLT. */
8748 if (!htab->root.splt || htab->root.splt->size == 0)
8749 return true;
8751 osi.sec_shndx = _bfd_elf_section_from_bfd_section
8752 (output_bfd, htab->root.splt->output_section);
8753 osi.sec = htab->root.splt;
8755 elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0);
8757 return true;
8761 /* Allocate target specific section data. */
8763 static bool
8764 elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec)
8766 if (!sec->used_by_bfd)
8768 _aarch64_elf_section_data *sdata;
8769 size_t amt = sizeof (*sdata);
8771 sdata = bfd_zalloc (abfd, amt);
8772 if (sdata == NULL)
8773 return false;
8774 sec->used_by_bfd = sdata;
8777 record_section_with_aarch64_elf_section_data (sec);
8779 return _bfd_elf_new_section_hook (abfd, sec);
8783 static void
8784 unrecord_section_via_map_over_sections (bfd *abfd ATTRIBUTE_UNUSED,
8785 asection *sec,
8786 void *ignore ATTRIBUTE_UNUSED)
8788 unrecord_section_with_aarch64_elf_section_data (sec);
8791 static bool
8792 elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
8794 if (abfd->sections)
8795 bfd_map_over_sections (abfd,
8796 unrecord_section_via_map_over_sections, NULL);
8798 return _bfd_elf_free_cached_info (abfd);
8801 /* Create dynamic sections. This is different from the ARM backend in that
8802 the got, plt, gotplt and their relocation sections are all created in the
8803 standard part of the bfd elf backend. */
8805 static bool
8806 elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
8807 struct bfd_link_info *info)
8809 /* We need to create .got section. */
8810 if (!aarch64_elf_create_got_section (dynobj, info))
8811 return false;
8813 return _bfd_elf_create_dynamic_sections (dynobj, info);
8817 /* Allocate space in .plt, .got and associated reloc sections for
8818 dynamic relocs. */
8820 static bool
8821 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
8823 struct bfd_link_info *info;
8824 struct elf_aarch64_link_hash_table *htab;
8825 struct elf_aarch64_link_hash_entry *eh;
8826 struct elf_dyn_relocs *p;
8828 /* An example of a bfd_link_hash_indirect symbol is versioned
8829 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
8830 -> __gxx_personality_v0(bfd_link_hash_defined)
8832 There is no need to process bfd_link_hash_indirect symbols here
8833 because we will also be presented with the concrete instance of
8834 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
8835 called to copy all relevant data from the generic to the concrete
8836 symbol instance. */
8837 if (h->root.type == bfd_link_hash_indirect)
8838 return true;
8840 if (h->root.type == bfd_link_hash_warning)
8841 h = (struct elf_link_hash_entry *) h->root.u.i.link;
8843 info = (struct bfd_link_info *) inf;
8844 htab = elf_aarch64_hash_table (info);
8846 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
8847 here if it is defined and referenced in a non-shared object. */
8848 if (h->type == STT_GNU_IFUNC
8849 && h->def_regular)
8850 return true;
8851 else if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
8853 /* Make sure this symbol is output as a dynamic symbol.
8854 Undefined weak syms won't yet be marked as dynamic. */
8855 if (h->dynindx == -1 && !h->forced_local
8856 && h->root.type == bfd_link_hash_undefweak)
8858 if (!bfd_elf_link_record_dynamic_symbol (info, h))
8859 return false;
8862 if (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
8864 asection *s = htab->root.splt;
8866 /* If this is the first .plt entry, make room for the special
8867 first entry. */
8868 if (s->size == 0)
8869 s->size += htab->plt_header_size;
8871 h->plt.offset = s->size;
8873 /* If this symbol is not defined in a regular file, and we are
8874 not generating a shared library, then set the symbol to this
8875 location in the .plt. This is required to make function
8876 pointers compare as equal between the normal executable and
8877 the shared library. */
8878 if (!bfd_link_pic (info) && !h->def_regular)
8880 h->root.u.def.section = s;
8881 h->root.u.def.value = h->plt.offset;
8884 /* Make room for this entry. For now we only create the
8885 small model PLT entries. We later need to find a way
8886 of relaxing into these from the large model PLT entries. */
8887 s->size += htab->plt_entry_size;
8889 /* We also need to make an entry in the .got.plt section, which
8890 will be placed in the .got section by the linker script. */
8891 htab->root.sgotplt->size += GOT_ENTRY_SIZE;
8893 /* We also need to make an entry in the .rela.plt section. */
8894 htab->root.srelplt->size += RELOC_SIZE (htab);
8896 /* We need to ensure that all GOT entries that serve the PLT
8897 are consecutive with the special GOT slots [0] [1] and
8898 [2]. Any addtional relocations, such as
8899 R_AARCH64_TLSDESC, must be placed after the PLT related
8900 entries. We abuse the reloc_count such that during
8901 sizing we adjust reloc_count to indicate the number of
8902 PLT related reserved entries. In subsequent phases when
8903 filling in the contents of the reloc entries, PLT related
8904 entries are placed by computing their PLT index (0
8905 .. reloc_count). While other none PLT relocs are placed
8906 at the slot indicated by reloc_count and reloc_count is
8907 updated. */
8909 htab->root.srelplt->reloc_count++;
8911 /* Mark the DSO in case R_<CLS>_JUMP_SLOT relocs against
8912 variant PCS symbols are present. */
8913 if (h->other & STO_AARCH64_VARIANT_PCS)
8914 htab->variant_pcs = 1;
8917 else
8919 h->plt.offset = (bfd_vma) - 1;
8920 h->needs_plt = 0;
8923 else
8925 h->plt.offset = (bfd_vma) - 1;
8926 h->needs_plt = 0;
8929 eh = (struct elf_aarch64_link_hash_entry *) h;
8930 eh->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
8932 if (h->got.refcount > 0)
8934 bool dyn;
8935 unsigned got_type = elf_aarch64_hash_entry (h)->got_type;
8937 h->got.offset = (bfd_vma) - 1;
8939 dyn = htab->root.dynamic_sections_created;
8941 /* Make sure this symbol is output as a dynamic symbol.
8942 Undefined weak syms won't yet be marked as dynamic. */
8943 if (dyn && h->dynindx == -1 && !h->forced_local
8944 && h->root.type == bfd_link_hash_undefweak)
8946 if (!bfd_elf_link_record_dynamic_symbol (info, h))
8947 return false;
8950 if (got_type == GOT_UNKNOWN)
8953 else if (got_type == GOT_NORMAL)
8955 h->got.offset = htab->root.sgot->size;
8956 htab->root.sgot->size += GOT_ENTRY_SIZE;
8957 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8958 || h->root.type != bfd_link_hash_undefweak)
8959 && (bfd_link_pic (info)
8960 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
8961 /* Undefined weak symbol in static PIE resolves to 0 without
8962 any dynamic relocations. */
8963 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
8965 htab->root.srelgot->size += RELOC_SIZE (htab);
8968 else
8970 int indx;
8971 if (got_type & GOT_TLSDESC_GD)
8973 eh->tlsdesc_got_jump_table_offset =
8974 (htab->root.sgotplt->size
8975 - aarch64_compute_jump_table_size (htab));
8976 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
8977 h->got.offset = (bfd_vma) - 2;
8980 if (got_type & GOT_TLS_GD)
8982 h->got.offset = htab->root.sgot->size;
8983 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
8986 if (got_type & GOT_TLS_IE)
8988 h->got.offset = htab->root.sgot->size;
8989 htab->root.sgot->size += GOT_ENTRY_SIZE;
8992 indx = h && h->dynindx != -1 ? h->dynindx : 0;
8993 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8994 || h->root.type != bfd_link_hash_undefweak)
8995 && (!bfd_link_executable (info)
8996 || indx != 0
8997 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
8999 if (got_type & GOT_TLSDESC_GD)
9001 htab->root.srelplt->size += RELOC_SIZE (htab);
9002 /* Note reloc_count not incremented here! We have
9003 already adjusted reloc_count for this relocation
9004 type. */
9006 /* TLSDESC PLT is now needed, but not yet determined. */
9007 htab->root.tlsdesc_plt = (bfd_vma) - 1;
9010 if (got_type & GOT_TLS_GD)
9011 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
9013 if (got_type & GOT_TLS_IE)
9014 htab->root.srelgot->size += RELOC_SIZE (htab);
9018 else
9020 h->got.offset = (bfd_vma) - 1;
9023 if (h->dyn_relocs == NULL)
9024 return true;
9026 for (p = h->dyn_relocs; p != NULL; p = p->next)
9027 if (eh->def_protected)
9029 /* Disallow copy relocations against protected symbol. */
9030 asection *s = p->sec->output_section;
9031 if (s != NULL && (s->flags & SEC_READONLY) != 0)
9033 info->callbacks->einfo
9034 /* xgettext:c-format */
9035 (_ ("%F%P: %pB: copy relocation against non-copyable "
9036 "protected symbol `%s'\n"),
9037 p->sec->owner, h->root.root.string);
9038 return false;
9042 /* In the shared -Bsymbolic case, discard space allocated for
9043 dynamic pc-relative relocs against symbols which turn out to be
9044 defined in regular objects. For the normal shared case, discard
9045 space for pc-relative relocs that have become local due to symbol
9046 visibility changes. */
9048 if (bfd_link_pic (info))
9050 /* Relocs that use pc_count are those that appear on a call
9051 insn, or certain REL relocs that can generated via assembly.
9052 We want calls to protected symbols to resolve directly to the
9053 function rather than going via the plt. If people want
9054 function pointer comparisons to work as expected then they
9055 should avoid writing weird assembly. */
9056 if (SYMBOL_CALLS_LOCAL (info, h))
9058 struct elf_dyn_relocs **pp;
9060 for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
9062 p->count -= p->pc_count;
9063 p->pc_count = 0;
9064 if (p->count == 0)
9065 *pp = p->next;
9066 else
9067 pp = &p->next;
9071 /* Also discard relocs on undefined weak syms with non-default
9072 visibility. */
9073 if (h->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
9075 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
9076 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
9077 h->dyn_relocs = NULL;
9079 /* Make sure undefined weak symbols are output as a dynamic
9080 symbol in PIEs. */
9081 else if (h->dynindx == -1
9082 && !h->forced_local
9083 && h->root.type == bfd_link_hash_undefweak
9084 && !bfd_elf_link_record_dynamic_symbol (info, h))
9085 return false;
9089 else if (ELIMINATE_COPY_RELOCS)
9091 /* For the non-shared case, discard space for relocs against
9092 symbols which turn out to need copy relocs or are not
9093 dynamic. */
9095 if (!h->non_got_ref
9096 && ((h->def_dynamic
9097 && !h->def_regular)
9098 || (htab->root.dynamic_sections_created
9099 && (h->root.type == bfd_link_hash_undefweak
9100 || h->root.type == bfd_link_hash_undefined))))
9102 /* Make sure this symbol is output as a dynamic symbol.
9103 Undefined weak syms won't yet be marked as dynamic. */
9104 if (h->dynindx == -1
9105 && !h->forced_local
9106 && h->root.type == bfd_link_hash_undefweak
9107 && !bfd_elf_link_record_dynamic_symbol (info, h))
9108 return false;
9110 /* If that succeeded, we know we'll be keeping all the
9111 relocs. */
9112 if (h->dynindx != -1)
9113 goto keep;
9116 h->dyn_relocs = NULL;
9118 keep:;
9121 /* Finally, allocate space. */
9122 for (p = h->dyn_relocs; p != NULL; p = p->next)
9124 asection *sreloc;
9126 sreloc = elf_section_data (p->sec)->sreloc;
9128 BFD_ASSERT (sreloc != NULL);
9130 sreloc->size += p->count * RELOC_SIZE (htab);
9133 return true;
9136 /* Allocate space in .plt, .got and associated reloc sections for
9137 ifunc dynamic relocs. */
9139 static bool
9140 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
9141 void *inf)
9143 struct bfd_link_info *info;
9144 struct elf_aarch64_link_hash_table *htab;
9146 /* An example of a bfd_link_hash_indirect symbol is versioned
9147 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
9148 -> __gxx_personality_v0(bfd_link_hash_defined)
9150 There is no need to process bfd_link_hash_indirect symbols here
9151 because we will also be presented with the concrete instance of
9152 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
9153 called to copy all relevant data from the generic to the concrete
9154 symbol instance. */
9155 if (h->root.type == bfd_link_hash_indirect)
9156 return true;
9158 if (h->root.type == bfd_link_hash_warning)
9159 h = (struct elf_link_hash_entry *) h->root.u.i.link;
9161 info = (struct bfd_link_info *) inf;
9162 htab = elf_aarch64_hash_table (info);
9164 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
9165 here if it is defined and referenced in a non-shared object. */
9166 if (h->type == STT_GNU_IFUNC
9167 && h->def_regular)
9168 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
9169 &h->dyn_relocs,
9170 htab->plt_entry_size,
9171 htab->plt_header_size,
9172 GOT_ENTRY_SIZE,
9173 false);
9174 return true;
9177 /* Allocate space in .plt, .got and associated reloc sections for
9178 local ifunc dynamic relocs. */
9180 static int
9181 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
9183 struct elf_link_hash_entry *h
9184 = (struct elf_link_hash_entry *) *slot;
9186 if (h->type != STT_GNU_IFUNC
9187 || !h->def_regular
9188 || !h->ref_regular
9189 || !h->forced_local
9190 || h->root.type != bfd_link_hash_defined)
9191 abort ();
9193 return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
9196 /* Record a relative relocation that will be emitted packed (DT_RELR).
9197 Called after relocation sections are sized, so undo the size accounting
9198 for this relocation. */
9200 static bool
9201 record_relr (struct elf_aarch64_link_hash_table *htab, asection *sec,
9202 bfd_vma off, asection *sreloc)
9204 /* Undo the relocation section size accounting. */
9205 BFD_ASSERT (sreloc->size >= RELOC_SIZE (htab));
9206 sreloc->size -= RELOC_SIZE (htab);
9207 /* The packing format uses the last bit of the address so that
9208 must be aligned. We don't pack relocations that may not be
9209 aligned even though the final output address could end up
9210 aligned, to avoid complex sizing logic for a rare case. */
9211 BFD_ASSERT (off % 2 == 0 && sec->alignment_power > 0);
9212 if (htab->relr_count >= htab->relr_alloc)
9214 if (htab->relr_alloc == 0)
9215 htab->relr_alloc = 4096;
9216 else
9217 htab->relr_alloc *= 2;
9218 htab->relr = bfd_realloc (htab->relr,
9219 htab->relr_alloc * sizeof (*htab->relr));
9220 if (htab->relr == NULL)
9221 return false;
9223 htab->relr[htab->relr_count].sec = sec;
9224 htab->relr[htab->relr_count].off = off;
9225 htab->relr_count++;
9226 return true;
9229 /* Follow elfNN_aarch64_allocate_dynrelocs, but only record relative
9230 relocations against the GOT and undo their previous size accounting. */
9232 static bool
9233 record_relr_dyn_got_relocs (struct elf_link_hash_entry *h, void *inf)
9236 if (h->root.type == bfd_link_hash_indirect)
9237 return true;
9238 if (h->root.type == bfd_link_hash_warning)
9239 h = (struct elf_link_hash_entry *) h->root.u.i.link;
9240 if (h->type == STT_GNU_IFUNC && h->def_regular)
9241 return true;
9242 if (h->got.refcount <= 0)
9243 return true;
9244 if (elf_aarch64_hash_entry (h)->got_type != GOT_NORMAL)
9245 return true;
9247 struct bfd_link_info *info = (struct bfd_link_info *) inf;
9248 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
9250 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
9251 || h->root.type != bfd_link_hash_undefweak)
9252 && bfd_link_pic (info)
9253 /* Undefined weak symbol in static PIE resolves to 0 without
9254 any dynamic relocations. */
9255 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
9257 bool relative_reloc = SYMBOL_REFERENCES_LOCAL (info, h)
9258 && !bfd_is_abs_symbol (&h->root);
9259 if (relative_reloc)
9260 if (!record_relr (htab, htab->root.sgot, h->got.offset,
9261 htab->root.srelgot))
9262 return false;
9264 return true;
9267 /* Record packed relative relocs against the GOT for local symbols.
9268 Undo the size accounting of elfNN_aarch64_late_size_sections. */
9270 static bool
9271 record_relr_local_got_relocs (bfd *input_bfd, struct bfd_link_info *info)
9273 struct elf_aarch64_local_symbol *locals;
9274 Elf_Internal_Shdr *symtab_hdr;
9275 struct elf_aarch64_link_hash_table *htab;
9277 if (!bfd_link_pic (info))
9278 return true;
9280 locals = elf_aarch64_locals (input_bfd);
9281 if (locals == NULL)
9282 return true;
9284 symtab_hdr = &elf_symtab_hdr (input_bfd);
9285 htab = elf_aarch64_hash_table (info);
9286 for (unsigned int i = 0; i < symtab_hdr->sh_info; i++)
9288 bfd_vma off = locals[i].got_offset;
9289 if (locals[i].got_refcount <= 0)
9290 continue;
9291 if ((locals[i].got_type & GOT_NORMAL) == 0)
9292 continue;
9294 /* FIXME: If the local symbol is in SHN_ABS then emitting
9295 a relative relocation is not correct, but it seems to
9296 be wrong in elfNN_aarch64_final_link_relocate too. */
9297 if (!record_relr (htab, htab->root.sgot, off, htab->root.srelgot))
9298 return false;
9300 return true;
9303 /* Follows the logic of elfNN_aarch64_relocate_section to decide which
9304 relocations will become relative and possible to pack. Ignore
9305 relocations against the GOT, those are handled separately per-symbol.
9306 Undo the size accounting of the packed relocations and record them
9307 so the relr section can be sized later. */
9309 static bool
9310 record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info,
9311 asection *sec)
9313 const Elf_Internal_Rela *relocs;
9314 const Elf_Internal_Rela *rel;
9315 const Elf_Internal_Rela *rel_end;
9316 asection *sreloc;
9317 struct elf_aarch64_link_hash_table *htab;
9318 Elf_Internal_Shdr *symtab_hdr;
9319 struct elf_link_hash_entry **sym_hashes;
9321 if (sec->reloc_count == 0)
9322 return true;
9323 if ((sec->flags & (SEC_RELOC | SEC_ALLOC | SEC_DEBUGGING))
9324 != (SEC_RELOC | SEC_ALLOC))
9325 return true;
9326 if (sec->alignment_power == 0)
9327 return true;
9328 if (discarded_section (sec))
9329 return true;
9330 sreloc = elf_section_data (sec)->sreloc;
9331 if (sreloc == NULL)
9332 return true;
9333 htab = elf_aarch64_hash_table (info);
9334 symtab_hdr = &elf_symtab_hdr (input_bfd);
9335 sym_hashes = elf_sym_hashes (input_bfd);
9336 relocs = _bfd_elf_link_info_read_relocs (input_bfd, info, sec, NULL, NULL,
9337 info->keep_memory);
9338 BFD_ASSERT (relocs != NULL);
9339 rel_end = relocs + sec->reloc_count;
9340 for (rel = relocs; rel < rel_end; rel++)
9342 unsigned int r_symndx = ELFNN_R_SYM (rel->r_info);
9343 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
9345 bfd_reloc_code_real_type bfd_r_type
9346 = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
9347 /* Handle relocs that can become R_AARCH64_RELATIVE,
9348 but not ones against the GOT as those are handled
9349 separately per-symbol. */
9350 if (bfd_r_type != BFD_RELOC_AARCH64_NN)
9351 continue;
9352 /* Can only pack relocation against an aligned address. */
9353 if (rel->r_offset % 2 != 0)
9354 continue;
9356 struct elf_link_hash_entry *h = NULL;
9357 asection *def_sec = NULL;
9358 bool resolved_to_zero = false;
9359 if (r_symndx < symtab_hdr->sh_info)
9361 /* A local symbol. */
9362 Elf_Internal_Sym *isym;
9363 isym = bfd_sym_from_r_symndx (&htab->root.sym_cache,
9364 input_bfd, r_symndx);
9365 BFD_ASSERT (isym != NULL);
9366 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
9367 continue;
9368 def_sec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
9370 else
9372 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
9373 while (h->root.type == bfd_link_hash_indirect
9374 || h->root.type == bfd_link_hash_warning)
9375 h = (struct elf_link_hash_entry *) h->root.u.i.link;
9377 /* Filter out symbols that cannot have a relative reloc. */
9378 if (h->dyn_relocs == NULL)
9379 continue;
9380 if (bfd_is_abs_symbol (&h->root))
9381 continue;
9382 if (h->type == STT_GNU_IFUNC)
9383 continue;
9385 if (h->root.type == bfd_link_hash_defined
9386 || h->root.type == bfd_link_hash_defweak)
9387 def_sec = h->root.u.def.section;
9388 resolved_to_zero = UNDEFWEAK_NO_DYNAMIC_RELOC (info, h);
9390 if (def_sec != NULL && discarded_section (def_sec))
9391 continue;
9392 /* Same logic as in elfNN_aarch64_final_link_relocate.
9393 Except conditionals trimmed that cannot result a reltive reloc. */
9394 if (bfd_link_pic (info)
9395 && (h == NULL
9396 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
9397 && !resolved_to_zero)
9398 || h->root.type != bfd_link_hash_undefweak))
9400 if (h != NULL
9401 && h->dynindx != -1
9402 && (!(bfd_link_pie (info) || SYMBOLIC_BIND (info, h))
9403 || !h->def_regular))
9404 continue;
9405 if (!record_relr (htab, sec, rel->r_offset, sreloc))
9406 return false;
9409 return true;
9412 static int
9413 cmp_relr_addr (const void *p, const void *q)
9415 const bfd_vma *a = p;
9416 const bfd_vma *b = q;
9417 return *a < *b ? -1 : *a > *b ? 1 : 0;
9420 /* Produce a malloc'd sorted array of reloc addresses in htab->relr_sorted.
9421 Returns false on allocation failure. */
9423 static bool
9424 sort_relr (struct bfd_link_info *info,
9425 struct elf_aarch64_link_hash_table *htab)
9427 if (htab->relr_count == 0)
9428 return true;
9430 bfd_vma *addr = htab->relr_sorted;
9431 if (addr == NULL)
9433 addr = bfd_malloc (htab->relr_count * sizeof (*addr));
9434 if (addr == NULL)
9435 return false;
9436 htab->relr_sorted = addr;
9439 for (bfd_size_type i = 0; i < htab->relr_count; i++)
9441 bfd_vma off = _bfd_elf_section_offset (info->output_bfd, info,
9442 htab->relr[i].sec,
9443 htab->relr[i].off);
9444 addr[i] = htab->relr[i].sec->output_section->vma
9445 + htab->relr[i].sec->output_offset
9446 + off;
9448 qsort (addr, htab->relr_count, sizeof (*addr), cmp_relr_addr);
9449 return true;
9452 /* Size of a relr entry and a relocated location. */
9453 #define RELR_SZ (ARCH_SIZE / 8)
9454 /* Number of consecutive locations a relr bitmap entry references. */
9455 #define RELR_N (ARCH_SIZE - 1)
9457 /* Size .relr.dyn whenever the layout changes, the number of packed
9458 relocs are unchanged but the packed representation can. */
9460 bool
9461 elfNN_aarch64_size_relative_relocs (struct bfd_link_info *info,
9462 bool *need_layout)
9464 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
9465 asection *srelrdyn = htab->root.srelrdyn;
9466 *need_layout = false;
9468 if (!sort_relr (info, htab))
9469 return false;
9470 bfd_vma *addr = htab->relr_sorted;
9472 BFD_ASSERT (srelrdyn != NULL);
9473 bfd_size_type oldsize = srelrdyn->size;
9474 srelrdyn->size = 0;
9475 for (bfd_size_type i = 0; i < htab->relr_count; )
9477 bfd_vma base = addr[i];
9478 i++;
9479 srelrdyn->size += RELR_SZ;
9480 base += RELR_SZ;
9481 for (;;)
9483 bfd_size_type start_i = i;
9484 while (i < htab->relr_count
9485 && addr[i] - base < RELR_N * RELR_SZ
9486 && (addr[i] - base) % RELR_SZ == 0)
9487 i++;
9488 if (i == start_i)
9489 break;
9490 srelrdyn->size += RELR_SZ;
9491 base += RELR_N * RELR_SZ;
9494 if (srelrdyn->size != oldsize)
9496 *need_layout = true;
9497 /* Stop after a few iterations in case the layout does not converge,
9498 we can do this when the size would shrink. */
9499 if (htab->relr_layout_iter++ > 5 && srelrdyn->size < oldsize)
9501 srelrdyn->size = oldsize;
9502 *need_layout = false;
9505 return true;
9508 /* Emit the .relr.dyn section after it is sized and the layout is fixed. */
9510 bool
9511 elfNN_aarch64_finish_relative_relocs (struct bfd_link_info *info)
9513 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
9514 asection *srelrdyn = htab->root.srelrdyn;
9515 bfd *dynobj = htab->root.dynobj;
9517 if (srelrdyn == NULL || srelrdyn->size == 0)
9518 return true;
9519 srelrdyn->contents = bfd_alloc (dynobj, srelrdyn->size);
9520 if (srelrdyn->contents == NULL)
9521 return false;
9522 bfd_vma *addr = htab->relr_sorted;
9523 bfd_byte *loc = srelrdyn->contents;
9524 for (bfd_size_type i = 0; i < htab->relr_count; )
9526 bfd_vma base = addr[i];
9527 i++;
9528 bfd_put_NN (dynobj, base, loc);
9529 loc += RELR_SZ;
9530 base += RELR_SZ;
9531 for (;;)
9533 bfd_vma bits = 0;
9534 while (i < htab->relr_count)
9536 bfd_vma delta = addr[i] - base;
9537 if (delta >= RELR_N * RELR_SZ || delta % RELR_SZ != 0)
9538 break;
9539 bits |= (bfd_vma) 1 << (delta / RELR_SZ);
9540 i++;
9542 if (bits == 0)
9543 break;
9544 bfd_put_NN (dynobj, (bits << 1) | 1, loc);
9545 loc += RELR_SZ;
9546 base += RELR_N * RELR_SZ;
9549 free (addr);
9550 htab->relr_sorted = NULL;
9551 /* Pad any excess with 1's, a do-nothing encoding. */
9552 while (loc < srelrdyn->contents + srelrdyn->size)
9554 bfd_put_NN (dynobj, 1, loc);
9555 loc += RELR_SZ;
9557 return true;
9560 /* This is the most important function of all . Innocuosly named
9561 though ! */
9563 static bool
9564 elfNN_aarch64_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
9565 struct bfd_link_info *info)
9567 struct elf_aarch64_link_hash_table *htab;
9568 bfd *dynobj;
9569 asection *s;
9570 bool relocs;
9571 bfd *ibfd;
9573 htab = elf_aarch64_hash_table ((info));
9574 dynobj = htab->root.dynobj;
9576 if (dynobj == NULL)
9577 return true;
9579 if (htab->root.dynamic_sections_created)
9581 if (bfd_link_executable (info) && !info->nointerp)
9583 s = bfd_get_linker_section (dynobj, ".interp");
9584 if (s == NULL)
9585 abort ();
9586 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
9587 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
9591 /* Set up .got offsets for local syms, and space for local dynamic
9592 relocs. */
9593 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
9595 struct elf_aarch64_local_symbol *locals = NULL;
9596 Elf_Internal_Shdr *symtab_hdr;
9597 asection *srel;
9598 unsigned int i;
9600 if (!is_aarch64_elf (ibfd))
9601 continue;
9603 for (s = ibfd->sections; s != NULL; s = s->next)
9605 struct elf_dyn_relocs *p;
9607 for (p = (struct elf_dyn_relocs *)
9608 (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
9610 if (discarded_section (p->sec))
9612 /* Input section has been discarded, either because
9613 it is a copy of a linkonce section or due to
9614 linker script /DISCARD/, so we'll be discarding
9615 the relocs too. */
9617 else if (p->count != 0)
9619 srel = elf_section_data (p->sec)->sreloc;
9620 srel->size += p->count * RELOC_SIZE (htab);
9621 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
9622 info->flags |= DF_TEXTREL;
9627 locals = elf_aarch64_locals (ibfd);
9628 if (!locals)
9629 continue;
9631 symtab_hdr = &elf_symtab_hdr (ibfd);
9632 srel = htab->root.srelgot;
9633 for (i = 0; i < symtab_hdr->sh_info; i++)
9635 locals[i].got_offset = (bfd_vma) - 1;
9636 locals[i].tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
9637 if (locals[i].got_refcount > 0)
9639 unsigned got_type = locals[i].got_type;
9640 if (got_type & GOT_TLSDESC_GD)
9642 locals[i].tlsdesc_got_jump_table_offset =
9643 (htab->root.sgotplt->size
9644 - aarch64_compute_jump_table_size (htab));
9645 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
9646 locals[i].got_offset = (bfd_vma) - 2;
9649 if (got_type & GOT_TLS_GD)
9651 locals[i].got_offset = htab->root.sgot->size;
9652 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
9655 if (got_type & GOT_TLS_IE
9656 || got_type & GOT_NORMAL)
9658 locals[i].got_offset = htab->root.sgot->size;
9659 htab->root.sgot->size += GOT_ENTRY_SIZE;
9662 if (got_type == GOT_UNKNOWN)
9666 if (bfd_link_pic (info))
9668 if (got_type & GOT_TLSDESC_GD)
9670 htab->root.srelplt->size += RELOC_SIZE (htab);
9671 /* Note RELOC_COUNT not incremented here! */
9672 htab->root.tlsdesc_plt = (bfd_vma) - 1;
9675 if (got_type & GOT_TLS_GD)
9676 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
9678 if (got_type & GOT_TLS_IE
9679 || got_type & GOT_NORMAL)
9680 htab->root.srelgot->size += RELOC_SIZE (htab);
9683 else
9685 locals[i].got_refcount = (bfd_vma) - 1;
9691 /* Allocate global sym .plt and .got entries, and space for global
9692 sym dynamic relocs. */
9693 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
9694 info);
9696 /* Allocate global ifunc sym .plt and .got entries, and space for global
9697 ifunc sym dynamic relocs. */
9698 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_ifunc_dynrelocs,
9699 info);
9701 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
9702 htab_traverse (htab->loc_hash_table,
9703 elfNN_aarch64_allocate_local_ifunc_dynrelocs,
9704 info);
9706 /* For every jump slot reserved in the sgotplt, reloc_count is
9707 incremented. However, when we reserve space for TLS descriptors,
9708 it's not incremented, so in order to compute the space reserved
9709 for them, it suffices to multiply the reloc count by the jump
9710 slot size. */
9712 if (htab->root.srelplt)
9713 htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab);
9715 if (htab->root.tlsdesc_plt)
9717 if (htab->root.splt->size == 0)
9718 htab->root.splt->size += htab->plt_header_size;
9720 /* If we're not using lazy TLS relocations, don't generate the
9721 GOT and PLT entry required. */
9722 if ((info->flags & DF_BIND_NOW))
9723 htab->root.tlsdesc_plt = 0;
9724 else
9726 htab->root.tlsdesc_plt = htab->root.splt->size;
9727 htab->root.splt->size += htab->tlsdesc_plt_entry_size;
9729 htab->root.tlsdesc_got = htab->root.sgot->size;
9730 htab->root.sgot->size += GOT_ENTRY_SIZE;
9734 /* Record the relative relocations that will be packed and undo the
9735 size allocation for them in .rela.*. The size of .relr.dyn will be
9736 computed later iteratively since it depends on the final layout. */
9737 if (info->enable_dt_relr && !bfd_link_relocatable (info))
9739 elf_link_hash_traverse (&htab->root, record_relr_dyn_got_relocs, info);
9741 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
9743 if (!is_aarch64_elf (ibfd))
9744 continue;
9746 for (s = ibfd->sections; s != NULL; s = s->next)
9747 if (!record_relr_non_got_relocs (ibfd, info, s))
9748 return false;
9750 if (!record_relr_local_got_relocs (ibfd, info))
9751 return false;
9755 /* Init mapping symbols information to use later to distingush between
9756 code and data while scanning for errata. */
9757 if (htab->fix_erratum_835769 || htab->fix_erratum_843419)
9758 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
9760 if (!is_aarch64_elf (ibfd))
9761 continue;
9762 bfd_elfNN_aarch64_init_maps (ibfd);
9765 /* We now have determined the sizes of the various dynamic sections.
9766 Allocate memory for them. */
9767 relocs = false;
9768 for (s = dynobj->sections; s != NULL; s = s->next)
9770 if ((s->flags & SEC_LINKER_CREATED) == 0)
9771 continue;
9773 if (s == htab->root.splt
9774 || s == htab->root.sgot
9775 || s == htab->root.sgotplt
9776 || s == htab->root.iplt
9777 || s == htab->root.igotplt
9778 || s == htab->root.sdynbss
9779 || s == htab->root.sdynrelro)
9781 /* Strip this section if we don't need it; see the
9782 comment below. */
9784 else if (startswith (bfd_section_name (s), ".rela"))
9786 if (s->size != 0 && s != htab->root.srelplt)
9787 relocs = true;
9789 /* We use the reloc_count field as a counter if we need
9790 to copy relocs into the output file. */
9791 if (s != htab->root.srelplt)
9792 s->reloc_count = 0;
9794 else if (s == htab->root.srelrdyn)
9796 /* Remove .relr.dyn based on relr_count, not size, since
9797 it is not sized yet. */
9798 if (htab->relr_count == 0)
9799 s->flags |= SEC_EXCLUDE;
9800 else
9801 /* Force dynamic tags for relocs even if there are no
9802 .rela* relocs, required for setting DT_TEXTREL. */
9803 relocs = true;
9804 /* Allocate contents later. */
9805 continue;
9807 else
9809 /* It's not one of our sections, so don't allocate space. */
9810 continue;
9813 if (s->size == 0)
9815 /* If we don't need this section, strip it from the
9816 output file. This is mostly to handle .rela.bss and
9817 .rela.plt. We must create both sections in
9818 create_dynamic_sections, because they must be created
9819 before the linker maps input sections to output
9820 sections. The linker does that before
9821 adjust_dynamic_symbol is called, and it is that
9822 function which decides whether anything needs to go
9823 into these sections. */
9824 s->flags |= SEC_EXCLUDE;
9825 continue;
9828 if ((s->flags & SEC_HAS_CONTENTS) == 0)
9829 continue;
9831 /* Allocate memory for the section contents. We use bfd_zalloc
9832 here in case unused entries are not reclaimed before the
9833 section's contents are written out. This should not happen,
9834 but this way if it does, we get a R_AARCH64_NONE reloc instead
9835 of garbage. */
9836 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
9837 if (s->contents == NULL)
9838 return false;
9841 if (htab->root.dynamic_sections_created)
9843 /* Add some entries to the .dynamic section. We fill in the
9844 values later, in elfNN_aarch64_finish_dynamic_sections, but we
9845 must add the entries now so that we get the correct size for
9846 the .dynamic section. The DT_DEBUG entry is filled in by the
9847 dynamic linker and used by the debugger. */
9848 #define add_dynamic_entry(TAG, VAL) \
9849 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
9851 if (!_bfd_elf_add_dynamic_tags (output_bfd, info, relocs))
9852 return false;
9854 if (htab->root.splt->size != 0)
9856 if (htab->variant_pcs
9857 && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS, 0))
9858 return false;
9860 if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI_PAC)
9861 && (!add_dynamic_entry (DT_AARCH64_BTI_PLT, 0)
9862 || !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0)))
9863 return false;
9865 else if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI)
9866 && !add_dynamic_entry (DT_AARCH64_BTI_PLT, 0))
9867 return false;
9869 else if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_PAC)
9870 && !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0))
9871 return false;
9874 #undef add_dynamic_entry
9876 return true;
9879 static inline void
9880 elf_aarch64_update_plt_entry (bfd *output_bfd,
9881 bfd_reloc_code_real_type r_type,
9882 bfd_byte *plt_entry, bfd_vma value)
9884 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
9886 /* FIXME: We should check the return value from this function call. */
9887 (void) _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
9890 static void
9891 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
9892 struct elf_aarch64_link_hash_table
9893 *htab, bfd *output_bfd,
9894 struct bfd_link_info *info)
9896 bfd_byte *plt_entry;
9897 bfd_vma plt_index;
9898 bfd_vma got_offset;
9899 bfd_vma gotplt_entry_address;
9900 bfd_vma plt_entry_address;
9901 Elf_Internal_Rela rela;
9902 bfd_byte *loc;
9903 asection *plt, *gotplt, *relplt;
9905 /* When building a static executable, use .iplt, .igot.plt and
9906 .rela.iplt sections for STT_GNU_IFUNC symbols. */
9907 if (htab->root.splt != NULL)
9909 plt = htab->root.splt;
9910 gotplt = htab->root.sgotplt;
9911 relplt = htab->root.srelplt;
9913 else
9915 plt = htab->root.iplt;
9916 gotplt = htab->root.igotplt;
9917 relplt = htab->root.irelplt;
9920 /* Get the index in the procedure linkage table which
9921 corresponds to this symbol. This is the index of this symbol
9922 in all the symbols for which we are making plt entries. The
9923 first entry in the procedure linkage table is reserved.
9925 Get the offset into the .got table of the entry that
9926 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
9927 bytes. The first three are reserved for the dynamic linker.
9929 For static executables, we don't reserve anything. */
9931 if (plt == htab->root.splt)
9933 plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
9934 got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
9936 else
9938 plt_index = h->plt.offset / htab->plt_entry_size;
9939 got_offset = plt_index * GOT_ENTRY_SIZE;
9942 plt_entry = plt->contents + h->plt.offset;
9943 plt_entry_address = plt->output_section->vma
9944 + plt->output_offset + h->plt.offset;
9945 gotplt_entry_address = gotplt->output_section->vma +
9946 gotplt->output_offset + got_offset;
9948 /* Copy in the boiler-plate for the PLTn entry. */
9949 memcpy (plt_entry, htab->plt_entry, htab->plt_entry_size);
9951 /* First instruction in BTI enabled PLT stub is a BTI
9952 instruction so skip it. */
9953 if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI
9954 && elf_elfheader (output_bfd)->e_type == ET_EXEC)
9955 plt_entry = plt_entry + 4;
9957 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
9958 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
9959 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
9960 plt_entry,
9961 PG (gotplt_entry_address) -
9962 PG (plt_entry_address));
9964 /* Fill in the lo12 bits for the load from the pltgot. */
9965 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
9966 plt_entry + 4,
9967 PG_OFFSET (gotplt_entry_address));
9969 /* Fill in the lo12 bits for the add from the pltgot entry. */
9970 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
9971 plt_entry + 8,
9972 PG_OFFSET (gotplt_entry_address));
9974 /* All the GOTPLT Entries are essentially initialized to PLT0. */
9975 bfd_put_NN (output_bfd,
9976 plt->output_section->vma + plt->output_offset,
9977 gotplt->contents + got_offset);
9979 rela.r_offset = gotplt_entry_address;
9981 if (h->dynindx == -1
9982 || ((bfd_link_executable (info)
9983 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
9984 && h->def_regular
9985 && h->type == STT_GNU_IFUNC))
9987 /* If an STT_GNU_IFUNC symbol is locally defined, generate
9988 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
9989 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
9990 rela.r_addend = (h->root.u.def.value
9991 + h->root.u.def.section->output_section->vma
9992 + h->root.u.def.section->output_offset);
9994 else
9996 /* Fill in the entry in the .rela.plt section. */
9997 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
9998 rela.r_addend = 0;
10001 /* Compute the relocation entry to used based on PLT index and do
10002 not adjust reloc_count. The reloc_count has already been adjusted
10003 to account for this entry. */
10004 loc = relplt->contents + plt_index * RELOC_SIZE (htab);
10005 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
10008 /* Size sections even though they're not dynamic. We use it to setup
10009 _TLS_MODULE_BASE_, if needed. */
10011 static bool
10012 elfNN_aarch64_early_size_sections (bfd *output_bfd,
10013 struct bfd_link_info *info)
10015 asection *tls_sec;
10017 if (bfd_link_relocatable (info))
10018 return true;
10020 tls_sec = elf_hash_table (info)->tls_sec;
10022 if (tls_sec)
10024 struct elf_link_hash_entry *tlsbase;
10026 tlsbase = elf_link_hash_lookup (elf_hash_table (info),
10027 "_TLS_MODULE_BASE_", true, true, false);
10029 if (tlsbase)
10031 struct bfd_link_hash_entry *h = NULL;
10032 const struct elf_backend_data *bed =
10033 get_elf_backend_data (output_bfd);
10035 if (!(_bfd_generic_link_add_one_symbol
10036 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
10037 tls_sec, 0, NULL, false, bed->collect, &h)))
10038 return false;
10040 tlsbase->type = STT_TLS;
10041 tlsbase = (struct elf_link_hash_entry *) h;
10042 tlsbase->def_regular = 1;
10043 tlsbase->other = STV_HIDDEN;
10044 (*bed->elf_backend_hide_symbol) (info, tlsbase, true);
10048 return true;
10051 /* Finish up dynamic symbol handling. We set the contents of various
10052 dynamic sections here. */
10054 static bool
10055 elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
10056 struct bfd_link_info *info,
10057 struct elf_link_hash_entry *h,
10058 Elf_Internal_Sym *sym)
10060 struct elf_aarch64_link_hash_table *htab;
10061 htab = elf_aarch64_hash_table (info);
10063 if (h->plt.offset != (bfd_vma) - 1)
10065 asection *plt, *gotplt, *relplt;
10067 /* This symbol has an entry in the procedure linkage table. Set
10068 it up. */
10070 /* When building a static executable, use .iplt, .igot.plt and
10071 .rela.iplt sections for STT_GNU_IFUNC symbols. */
10072 if (htab->root.splt != NULL)
10074 plt = htab->root.splt;
10075 gotplt = htab->root.sgotplt;
10076 relplt = htab->root.srelplt;
10078 else
10080 plt = htab->root.iplt;
10081 gotplt = htab->root.igotplt;
10082 relplt = htab->root.irelplt;
10085 /* This symbol has an entry in the procedure linkage table. Set
10086 it up. */
10087 if ((h->dynindx == -1
10088 && !((h->forced_local || bfd_link_executable (info))
10089 && h->def_regular
10090 && h->type == STT_GNU_IFUNC))
10091 || plt == NULL
10092 || gotplt == NULL
10093 || relplt == NULL)
10094 abort ();
10096 elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd, info);
10097 if (!h->def_regular)
10099 /* Mark the symbol as undefined, rather than as defined in
10100 the .plt section. */
10101 sym->st_shndx = SHN_UNDEF;
10102 /* If the symbol is weak we need to clear the value.
10103 Otherwise, the PLT entry would provide a definition for
10104 the symbol even if the symbol wasn't defined anywhere,
10105 and so the symbol would never be NULL. Leave the value if
10106 there were any relocations where pointer equality matters
10107 (this is a clue for the dynamic linker, to make function
10108 pointer comparisons work between an application and shared
10109 library). */
10110 if (!h->ref_regular_nonweak || !h->pointer_equality_needed)
10111 sym->st_value = 0;
10115 if (h->got.offset != (bfd_vma) - 1
10116 && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
10117 /* Undefined weak symbol in static PIE resolves to 0 without
10118 any dynamic relocations. */
10119 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
10121 Elf_Internal_Rela rela;
10122 bfd_byte *loc;
10124 /* This symbol has an entry in the global offset table. Set it
10125 up. */
10126 if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
10127 abort ();
10129 rela.r_offset = (htab->root.sgot->output_section->vma
10130 + htab->root.sgot->output_offset
10131 + (h->got.offset & ~(bfd_vma) 1));
10133 if (h->def_regular
10134 && h->type == STT_GNU_IFUNC)
10136 if (bfd_link_pic (info))
10138 /* Generate R_AARCH64_GLOB_DAT. */
10139 goto do_glob_dat;
10141 else
10143 asection *plt;
10145 if (!h->pointer_equality_needed)
10146 abort ();
10148 /* For non-shared object, we can't use .got.plt, which
10149 contains the real function address if we need pointer
10150 equality. We load the GOT entry with the PLT entry. */
10151 plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
10152 bfd_put_NN (output_bfd, (plt->output_section->vma
10153 + plt->output_offset
10154 + h->plt.offset),
10155 htab->root.sgot->contents
10156 + (h->got.offset & ~(bfd_vma) 1));
10157 return true;
10160 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
10162 if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
10163 return false;
10164 BFD_ASSERT ((h->got.offset & 1) != 0);
10165 /* Don't emit relative relocs if they are packed. */
10166 if (info->enable_dt_relr)
10167 goto skip_got_reloc;
10168 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
10169 rela.r_addend = (h->root.u.def.value
10170 + h->root.u.def.section->output_section->vma
10171 + h->root.u.def.section->output_offset);
10173 else
10175 do_glob_dat:
10176 BFD_ASSERT ((h->got.offset & 1) == 0);
10177 bfd_put_NN (output_bfd, (bfd_vma) 0,
10178 htab->root.sgot->contents + h->got.offset);
10179 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
10180 rela.r_addend = 0;
10183 loc = htab->root.srelgot->contents;
10184 loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
10185 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
10187 skip_got_reloc:
10189 if (h->needs_copy)
10191 Elf_Internal_Rela rela;
10192 asection *s;
10193 bfd_byte *loc;
10195 /* This symbol needs a copy reloc. Set it up. */
10196 if (h->dynindx == -1
10197 || (h->root.type != bfd_link_hash_defined
10198 && h->root.type != bfd_link_hash_defweak)
10199 || htab->root.srelbss == NULL)
10200 abort ();
10202 rela.r_offset = (h->root.u.def.value
10203 + h->root.u.def.section->output_section->vma
10204 + h->root.u.def.section->output_offset);
10205 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
10206 rela.r_addend = 0;
10207 if (h->root.u.def.section == htab->root.sdynrelro)
10208 s = htab->root.sreldynrelro;
10209 else
10210 s = htab->root.srelbss;
10211 loc = s->contents + s->reloc_count++ * RELOC_SIZE (htab);
10212 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
10215 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
10216 be NULL for local symbols. */
10217 if (sym != NULL
10218 && (h == elf_hash_table (info)->hdynamic
10219 || h == elf_hash_table (info)->hgot))
10220 sym->st_shndx = SHN_ABS;
10222 return true;
10225 /* Finish up local dynamic symbol handling. We set the contents of
10226 various dynamic sections here. */
10228 static int
10229 elfNN_aarch64_finish_local_dynamic_symbol (void **slot, void *inf)
10231 struct elf_link_hash_entry *h
10232 = (struct elf_link_hash_entry *) *slot;
10233 struct bfd_link_info *info
10234 = (struct bfd_link_info *) inf;
10236 return elfNN_aarch64_finish_dynamic_symbol (info->output_bfd,
10237 info, h, NULL);
10240 static void
10241 elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
10242 struct elf_aarch64_link_hash_table
10243 *htab)
10245 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
10246 small and large plts and at the minute just generates
10247 the small PLT. */
10249 /* PLT0 of the small PLT looks like this in ELF64 -
10250 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
10251 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
10252 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
10253 // symbol resolver
10254 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
10255 // GOTPLT entry for this.
10256 br x17
10257 PLT0 will be slightly different in ELF32 due to different got entry
10258 size. */
10259 bfd_vma plt_got_2nd_ent; /* Address of GOT[2]. */
10260 bfd_vma plt_base;
10263 memcpy (htab->root.splt->contents, htab->plt0_entry,
10264 htab->plt_header_size);
10266 /* PR 26312: Explicitly set the sh_entsize to 0 so that
10267 consumers do not think that the section contains fixed
10268 sized objects. */
10269 elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize = 0;
10271 plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
10272 + htab->root.sgotplt->output_offset
10273 + GOT_ENTRY_SIZE * 2);
10275 plt_base = htab->root.splt->output_section->vma +
10276 htab->root.splt->output_offset;
10278 /* First instruction in BTI enabled PLT stub is a BTI
10279 instruction so skip it. */
10280 bfd_byte *plt0_entry = htab->root.splt->contents;
10281 if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI)
10282 plt0_entry = plt0_entry + 4;
10284 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
10285 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
10286 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
10287 plt0_entry + 4,
10288 PG (plt_got_2nd_ent) - PG (plt_base + 4));
10290 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
10291 plt0_entry + 8,
10292 PG_OFFSET (plt_got_2nd_ent));
10294 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
10295 plt0_entry + 12,
10296 PG_OFFSET (plt_got_2nd_ent));
10299 static bool
10300 elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
10301 struct bfd_link_info *info)
10303 struct elf_aarch64_link_hash_table *htab;
10304 bfd *dynobj;
10305 asection *sdyn;
10307 htab = elf_aarch64_hash_table (info);
10308 dynobj = htab->root.dynobj;
10309 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
10311 if (htab->root.dynamic_sections_created)
10313 ElfNN_External_Dyn *dyncon, *dynconend;
10315 if (sdyn == NULL || htab->root.sgot == NULL)
10316 abort ();
10318 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
10319 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
10320 for (; dyncon < dynconend; dyncon++)
10322 Elf_Internal_Dyn dyn;
10323 asection *s;
10325 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
10327 switch (dyn.d_tag)
10329 default:
10330 continue;
10332 case DT_PLTGOT:
10333 s = htab->root.sgotplt;
10334 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
10335 break;
10337 case DT_JMPREL:
10338 s = htab->root.srelplt;
10339 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
10340 break;
10342 case DT_PLTRELSZ:
10343 s = htab->root.srelplt;
10344 dyn.d_un.d_val = s->size;
10345 break;
10347 case DT_TLSDESC_PLT:
10348 s = htab->root.splt;
10349 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
10350 + htab->root.tlsdesc_plt;
10351 break;
10353 case DT_TLSDESC_GOT:
10354 s = htab->root.sgot;
10355 BFD_ASSERT (htab->root.tlsdesc_got != (bfd_vma)-1);
10356 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
10357 + htab->root.tlsdesc_got;
10358 break;
10361 bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
10366 /* Fill in the special first entry in the procedure linkage table. */
10367 if (htab->root.splt && htab->root.splt->size > 0)
10369 elfNN_aarch64_init_small_plt0_entry (output_bfd, htab);
10371 if (htab->root.tlsdesc_plt && !(info->flags & DF_BIND_NOW))
10373 BFD_ASSERT (htab->root.tlsdesc_got != (bfd_vma)-1);
10374 bfd_put_NN (output_bfd, (bfd_vma) 0,
10375 htab->root.sgot->contents + htab->root.tlsdesc_got);
10377 const bfd_byte *entry = elfNN_aarch64_tlsdesc_small_plt_entry;
10378 htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
10380 aarch64_plt_type type = elf_aarch64_tdata (output_bfd)->plt_type;
10381 if (type == PLT_BTI || type == PLT_BTI_PAC)
10383 entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry;
10386 memcpy (htab->root.splt->contents + htab->root.tlsdesc_plt,
10387 entry, htab->tlsdesc_plt_entry_size);
10390 bfd_vma adrp1_addr =
10391 htab->root.splt->output_section->vma
10392 + htab->root.splt->output_offset
10393 + htab->root.tlsdesc_plt + 4;
10395 bfd_vma adrp2_addr = adrp1_addr + 4;
10397 bfd_vma got_addr =
10398 htab->root.sgot->output_section->vma
10399 + htab->root.sgot->output_offset;
10401 bfd_vma pltgot_addr =
10402 htab->root.sgotplt->output_section->vma
10403 + htab->root.sgotplt->output_offset;
10405 bfd_vma dt_tlsdesc_got = got_addr + htab->root.tlsdesc_got;
10407 bfd_byte *plt_entry =
10408 htab->root.splt->contents + htab->root.tlsdesc_plt;
10410 /* First instruction in BTI enabled PLT stub is a BTI
10411 instruction so skip it. */
10412 if (type & PLT_BTI)
10414 plt_entry = plt_entry + 4;
10415 adrp1_addr = adrp1_addr + 4;
10416 adrp2_addr = adrp2_addr + 4;
10419 /* adrp x2, DT_TLSDESC_GOT */
10420 elf_aarch64_update_plt_entry (output_bfd,
10421 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
10422 plt_entry + 4,
10423 (PG (dt_tlsdesc_got)
10424 - PG (adrp1_addr)));
10426 /* adrp x3, 0 */
10427 elf_aarch64_update_plt_entry (output_bfd,
10428 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
10429 plt_entry + 8,
10430 (PG (pltgot_addr)
10431 - PG (adrp2_addr)));
10433 /* ldr x2, [x2, #0] */
10434 elf_aarch64_update_plt_entry (output_bfd,
10435 BFD_RELOC_AARCH64_LDSTNN_LO12,
10436 plt_entry + 12,
10437 PG_OFFSET (dt_tlsdesc_got));
10439 /* add x3, x3, 0 */
10440 elf_aarch64_update_plt_entry (output_bfd,
10441 BFD_RELOC_AARCH64_ADD_LO12,
10442 plt_entry + 16,
10443 PG_OFFSET (pltgot_addr));
10448 if (htab->root.sgotplt)
10450 if (bfd_is_abs_section (htab->root.sgotplt->output_section))
10452 _bfd_error_handler
10453 (_("discarded output section: `%pA'"), htab->root.sgotplt);
10454 return false;
10457 /* Fill in the first three entries in the global offset table. */
10458 if (htab->root.sgotplt->size > 0)
10460 bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
10462 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
10463 bfd_put_NN (output_bfd,
10464 (bfd_vma) 0,
10465 htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
10466 bfd_put_NN (output_bfd,
10467 (bfd_vma) 0,
10468 htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
10471 if (htab->root.sgot)
10473 if (htab->root.sgot->size > 0)
10475 bfd_vma addr =
10476 sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
10477 bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
10481 elf_section_data (htab->root.sgotplt->output_section)->
10482 this_hdr.sh_entsize = GOT_ENTRY_SIZE;
10485 if (htab->root.sgot && htab->root.sgot->size > 0)
10486 elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
10487 = GOT_ENTRY_SIZE;
10489 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
10490 htab_traverse (htab->loc_hash_table,
10491 elfNN_aarch64_finish_local_dynamic_symbol,
10492 info);
10494 return true;
10497 /* Check if BTI enabled PLTs are needed. Returns the type needed. */
10498 static aarch64_plt_type
10499 get_plt_type (bfd *abfd)
10501 aarch64_plt_type ret = PLT_NORMAL;
10502 bfd_byte *contents, *extdyn, *extdynend;
10503 asection *sec = bfd_get_section_by_name (abfd, ".dynamic");
10504 if (!sec
10505 || (sec->flags & SEC_HAS_CONTENTS) == 0
10506 || sec->size < sizeof (ElfNN_External_Dyn)
10507 || !bfd_malloc_and_get_section (abfd, sec, &contents))
10508 return ret;
10509 extdyn = contents;
10510 extdynend = contents + sec->size - sizeof (ElfNN_External_Dyn);
10511 for (; extdyn <= extdynend; extdyn += sizeof (ElfNN_External_Dyn))
10513 Elf_Internal_Dyn dyn;
10514 bfd_elfNN_swap_dyn_in (abfd, extdyn, &dyn);
10516 /* Let's check the processor specific dynamic array tags. */
10517 bfd_vma tag = dyn.d_tag;
10518 if (tag < DT_LOPROC || tag > DT_HIPROC)
10519 continue;
10521 switch (tag)
10523 case DT_AARCH64_BTI_PLT:
10524 ret |= PLT_BTI;
10525 break;
10527 case DT_AARCH64_PAC_PLT:
10528 ret |= PLT_PAC;
10529 break;
10531 default: break;
10534 free (contents);
10535 return ret;
10538 static long
10539 elfNN_aarch64_get_synthetic_symtab (bfd *abfd,
10540 long symcount,
10541 asymbol **syms,
10542 long dynsymcount,
10543 asymbol **dynsyms,
10544 asymbol **ret)
10546 elf_aarch64_tdata (abfd)->plt_type = get_plt_type (abfd);
10547 return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
10548 dynsymcount, dynsyms, ret);
10551 /* Return address for Ith PLT stub in section PLT, for relocation REL
10552 or (bfd_vma) -1 if it should not be included. */
10554 static bfd_vma
10555 elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
10556 const arelent *rel ATTRIBUTE_UNUSED)
10558 size_t plt0_size = PLT_ENTRY_SIZE;
10559 size_t pltn_size = PLT_SMALL_ENTRY_SIZE;
10561 if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI_PAC)
10563 if (elf_elfheader (plt->owner)->e_type == ET_EXEC)
10564 pltn_size = PLT_BTI_PAC_SMALL_ENTRY_SIZE;
10565 else
10566 pltn_size = PLT_PAC_SMALL_ENTRY_SIZE;
10568 else if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI)
10570 if (elf_elfheader (plt->owner)->e_type == ET_EXEC)
10571 pltn_size = PLT_BTI_SMALL_ENTRY_SIZE;
10573 else if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_PAC)
10575 pltn_size = PLT_PAC_SMALL_ENTRY_SIZE;
10578 return plt->vma + plt0_size + i * pltn_size;
10581 /* Returns TRUE if NAME is an AArch64 mapping symbol.
10582 The ARM ELF standard defines $x (for A64 code) and $d (for data).
10583 It also allows a period initiated suffix to be added to the symbol, ie:
10584 "$[adtx]\.[:sym_char]+". */
10586 static bool
10587 is_aarch64_mapping_symbol (const char * name)
10589 return name != NULL /* Paranoia. */
10590 && name[0] == '$' /* Note: if objcopy --prefix-symbols has been used then
10591 the mapping symbols could have acquired a prefix.
10592 We do not support this here, since such symbols no
10593 longer conform to the ARM ELF ABI. */
10594 && (name[1] == 'd' || name[1] == 'x')
10595 && (name[2] == 0 || name[2] == '.');
10596 /* FIXME: Strictly speaking the symbol is only a valid mapping symbol if
10597 any characters that follow the period are legal characters for the body
10598 of a symbol's name. For now we just assume that this is the case. */
10601 /* Make sure that mapping symbols in object files are not removed via the
10602 "strip --strip-unneeded" tool. These symbols might needed in order to
10603 correctly generate linked files. Once an object file has been linked,
10604 it should be safe to remove them. */
10606 static void
10607 elfNN_aarch64_backend_symbol_processing (bfd *abfd, asymbol *sym)
10609 if (((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
10610 && sym->section != bfd_abs_section_ptr
10611 && is_aarch64_mapping_symbol (sym->name))
10612 sym->flags |= BSF_KEEP;
10615 /* Implement elf_backend_setup_gnu_properties for AArch64. It serves as a
10616 wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account
10617 for the effect of GNU properties of the output_bfd. */
10618 static bfd *
10619 elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info)
10621 uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
10622 bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop);
10623 elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop;
10624 elf_aarch64_tdata (info->output_bfd)->plt_type
10625 |= (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ? PLT_BTI : 0;
10626 setup_plt_values (info, elf_aarch64_tdata (info->output_bfd)->plt_type);
10627 return pbfd;
10630 /* Implement elf_backend_merge_gnu_properties for AArch64. It serves as a
10631 wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account
10632 for the effect of GNU properties of the output_bfd. */
10633 static bool
10634 elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
10635 bfd *abfd, bfd *bbfd,
10636 elf_property *aprop,
10637 elf_property *bprop)
10639 uint32_t prop
10640 = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
10642 /* If output has been marked with BTI using command line argument, give out
10643 warning if necessary. */
10644 /* Properties are merged per type, hence only check for warnings when merging
10645 GNU_PROPERTY_AARCH64_FEATURE_1_AND. */
10646 if (((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
10647 || (bprop && bprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND))
10648 && (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
10649 && (!elf_aarch64_tdata (info->output_bfd)->no_bti_warn))
10651 if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
10652 || !aprop)
10654 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
10655 "all inputs do not have BTI in NOTE section."),
10656 abfd);
10658 if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
10659 || !bprop)
10661 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
10662 "all inputs do not have BTI in NOTE section."),
10663 bbfd);
10667 return _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
10668 bprop, prop);
10671 /* We use this so we can override certain functions
10672 (though currently we don't). */
10674 const struct elf_size_info elfNN_aarch64_size_info =
10676 sizeof (ElfNN_External_Ehdr),
10677 sizeof (ElfNN_External_Phdr),
10678 sizeof (ElfNN_External_Shdr),
10679 sizeof (ElfNN_External_Rel),
10680 sizeof (ElfNN_External_Rela),
10681 sizeof (ElfNN_External_Sym),
10682 sizeof (ElfNN_External_Dyn),
10683 sizeof (Elf_External_Note),
10684 4, /* Hash table entry size. */
10685 1, /* Internal relocs per external relocs. */
10686 ARCH_SIZE, /* Arch size. */
10687 LOG_FILE_ALIGN, /* Log_file_align. */
10688 ELFCLASSNN, EV_CURRENT,
10689 bfd_elfNN_write_out_phdrs,
10690 bfd_elfNN_write_shdrs_and_ehdr,
10691 bfd_elfNN_checksum_contents,
10692 bfd_elfNN_write_relocs,
10693 bfd_elfNN_swap_symbol_in,
10694 bfd_elfNN_swap_symbol_out,
10695 bfd_elfNN_slurp_reloc_table,
10696 bfd_elfNN_slurp_symbol_table,
10697 bfd_elfNN_swap_dyn_in,
10698 bfd_elfNN_swap_dyn_out,
10699 bfd_elfNN_swap_reloc_in,
10700 bfd_elfNN_swap_reloc_out,
10701 bfd_elfNN_swap_reloca_in,
10702 bfd_elfNN_swap_reloca_out
10705 #define ELF_ARCH bfd_arch_aarch64
10706 #define ELF_MACHINE_CODE EM_AARCH64
10707 #define ELF_MAXPAGESIZE 0x10000
10708 #define ELF_COMMONPAGESIZE 0x1000
10710 #define bfd_elfNN_bfd_free_cached_info \
10711 elfNN_aarch64_bfd_free_cached_info
10713 #define bfd_elfNN_bfd_is_target_special_symbol \
10714 elfNN_aarch64_is_target_special_symbol
10716 #define bfd_elfNN_bfd_link_hash_table_create \
10717 elfNN_aarch64_link_hash_table_create
10719 #define bfd_elfNN_bfd_merge_private_bfd_data \
10720 elfNN_aarch64_merge_private_bfd_data
10722 #define bfd_elfNN_bfd_print_private_bfd_data \
10723 elfNN_aarch64_print_private_bfd_data
10725 #define bfd_elfNN_bfd_reloc_type_lookup \
10726 elfNN_aarch64_reloc_type_lookup
10728 #define bfd_elfNN_bfd_reloc_name_lookup \
10729 elfNN_aarch64_reloc_name_lookup
10731 #define bfd_elfNN_bfd_set_private_flags \
10732 elfNN_aarch64_set_private_flags
10734 #define bfd_elfNN_find_inliner_info \
10735 elfNN_aarch64_find_inliner_info
10737 #define bfd_elfNN_get_synthetic_symtab \
10738 elfNN_aarch64_get_synthetic_symtab
10740 #define bfd_elfNN_mkobject \
10741 elfNN_aarch64_mkobject
10743 #define bfd_elfNN_new_section_hook \
10744 elfNN_aarch64_new_section_hook
10746 #define elf_backend_adjust_dynamic_symbol \
10747 elfNN_aarch64_adjust_dynamic_symbol
10749 #define elf_backend_early_size_sections \
10750 elfNN_aarch64_early_size_sections
10752 #define elf_backend_check_relocs \
10753 elfNN_aarch64_check_relocs
10755 #define elf_backend_copy_indirect_symbol \
10756 elfNN_aarch64_copy_indirect_symbol
10758 #define elf_backend_merge_symbol_attribute \
10759 elfNN_aarch64_merge_symbol_attribute
10761 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
10762 to them in our hash. */
10763 #define elf_backend_create_dynamic_sections \
10764 elfNN_aarch64_create_dynamic_sections
10766 #define elf_backend_init_index_section \
10767 _bfd_elf_init_2_index_sections
10769 #define elf_backend_finish_dynamic_sections \
10770 elfNN_aarch64_finish_dynamic_sections
10772 #define elf_backend_finish_dynamic_symbol \
10773 elfNN_aarch64_finish_dynamic_symbol
10775 #define elf_backend_object_p \
10776 elfNN_aarch64_object_p
10778 #define elf_backend_output_arch_local_syms \
10779 elfNN_aarch64_output_arch_local_syms
10781 #define elf_backend_maybe_function_sym \
10782 elfNN_aarch64_maybe_function_sym
10784 #define elf_backend_plt_sym_val \
10785 elfNN_aarch64_plt_sym_val
10787 #define elf_backend_init_file_header \
10788 elfNN_aarch64_init_file_header
10790 #define elf_backend_relocate_section \
10791 elfNN_aarch64_relocate_section
10793 #define elf_backend_reloc_type_class \
10794 elfNN_aarch64_reloc_type_class
10796 #define elf_backend_section_from_shdr \
10797 elfNN_aarch64_section_from_shdr
10799 #define elf_backend_section_from_phdr \
10800 elfNN_aarch64_section_from_phdr
10802 #define elf_backend_modify_headers \
10803 elfNN_aarch64_modify_headers
10805 #define elf_backend_late_size_sections \
10806 elfNN_aarch64_late_size_sections
10808 #define elf_backend_size_info \
10809 elfNN_aarch64_size_info
10811 #define elf_backend_write_section \
10812 elfNN_aarch64_write_section
10814 #define elf_backend_symbol_processing \
10815 elfNN_aarch64_backend_symbol_processing
10817 #define elf_backend_setup_gnu_properties \
10818 elfNN_aarch64_link_setup_gnu_properties
10820 #define elf_backend_merge_gnu_properties \
10821 elfNN_aarch64_merge_gnu_properties
10823 #define elf_backend_size_relative_relocs \
10824 elfNN_aarch64_size_relative_relocs
10826 #define elf_backend_finish_relative_relocs \
10827 elfNN_aarch64_finish_relative_relocs
10829 #define elf_backend_can_refcount 1
10830 #define elf_backend_can_gc_sections 1
10831 #define elf_backend_plt_readonly 1
10832 #define elf_backend_want_got_plt 1
10833 #define elf_backend_want_plt_sym 0
10834 #define elf_backend_want_dynrelro 1
10835 #define elf_backend_may_use_rel_p 0
10836 #define elf_backend_may_use_rela_p 1
10837 #define elf_backend_default_use_rela_p 1
10838 #define elf_backend_rela_normal 1
10839 #define elf_backend_dtrel_excludes_plt 1
10840 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
10841 #define elf_backend_default_execstack 0
10842 #define elf_backend_extern_protected_data 0
10843 #define elf_backend_hash_symbol elf_aarch64_hash_symbol
10845 #undef elf_backend_obj_attrs_section
10846 #define elf_backend_obj_attrs_section ".ARM.attributes"
10848 #include "elfNN-target.h"
10850 /* CloudABI support. */
10852 #undef TARGET_LITTLE_SYM
10853 #define TARGET_LITTLE_SYM aarch64_elfNN_le_cloudabi_vec
10854 #undef TARGET_LITTLE_NAME
10855 #define TARGET_LITTLE_NAME "elfNN-littleaarch64-cloudabi"
10856 #undef TARGET_BIG_SYM
10857 #define TARGET_BIG_SYM aarch64_elfNN_be_cloudabi_vec
10858 #undef TARGET_BIG_NAME
10859 #define TARGET_BIG_NAME "elfNN-bigaarch64-cloudabi"
10861 #undef ELF_OSABI
10862 #define ELF_OSABI ELFOSABI_CLOUDABI
10864 #undef elfNN_bed
10865 #define elfNN_bed elfNN_aarch64_cloudabi_bed
10867 #include "elfNN-target.h"