1 /* AArch64-specific support for NN-bit ELF.
2 Copyright (C) 2009-2015 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)
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:
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
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)
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.
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.
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
115 elfNN_aarch64_size_dynamic_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. */
140 #include "libiberty.h"
142 #include "bfd_stdint.h"
145 #include "objalloc.h"
146 #include "elf/aarch64.h"
147 #include "elfxx-aarch64.h"
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
160 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
161 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
162 #define HOWTO64(...) EMPTY_HOWTO (0)
163 #define HOWTO32(...) HOWTO (__VA_ARGS__)
164 #define LOG_FILE_ALIGN 2
167 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
168 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
169 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
170 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
171 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12 \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
192 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
194 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
195 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC)
208 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
209 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
210 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
212 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
213 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
214 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
215 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
216 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
220 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
222 #define ELIMINATE_COPY_RELOCS 0
224 /* Return size of a relocation entry. HTAB is the bfd's
225 elf_aarch64_link_hash_entry. */
226 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
228 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
229 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
230 #define PLT_ENTRY_SIZE (32)
231 #define PLT_SMALL_ENTRY_SIZE (16)
232 #define PLT_TLSDESC_ENTRY_SIZE (32)
234 /* Encoding of the nop instruction */
235 #define INSN_NOP 0xd503201f
237 #define aarch64_compute_jump_table_size(htab) \
238 (((htab)->root.srelplt == NULL) ? 0 \
239 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
241 /* The first entry in a procedure linkage table looks like this
242 if the distance between the PLTGOT and the PLT is < 4GB use
243 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
244 in x16 and needs to work out PLTGOT[1] by using an address of
245 [x16,#-GOT_ENTRY_SIZE]. */
246 static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
248 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
249 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
251 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
252 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
254 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
255 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
257 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
258 0x1f, 0x20, 0x03, 0xd5, /* nop */
259 0x1f, 0x20, 0x03, 0xd5, /* nop */
260 0x1f, 0x20, 0x03, 0xd5, /* nop */
263 /* Per function entry in a procedure linkage table looks like this
264 if the distance between the PLTGOT and the PLT is < 4GB use
265 these PLT entries. */
266 static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
268 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
270 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
271 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
273 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
274 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
276 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
279 static const bfd_byte
280 elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
282 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
283 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
284 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
286 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
287 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
289 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
290 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
292 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
293 0x1f, 0x20, 0x03, 0xd5, /* nop */
294 0x1f, 0x20, 0x03, 0xd5, /* nop */
297 #define elf_info_to_howto elfNN_aarch64_info_to_howto
298 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
300 #define AARCH64_ELF_ABI_VERSION 0
302 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
303 #define ALL_ONES (~ (bfd_vma) 0)
305 /* Indexed by the bfd interal reloc enumerators.
306 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
309 static reloc_howto_type elfNN_aarch64_howto_table[] =
313 /* Basic data relocations. */
316 HOWTO (R_AARCH64_NULL, /* type */
318 3, /* size (0 = byte, 1 = short, 2 = long) */
320 FALSE, /* pc_relative */
322 complain_overflow_dont, /* complain_on_overflow */
323 bfd_elf_generic_reloc, /* special_function */
324 "R_AARCH64_NULL", /* name */
325 FALSE, /* partial_inplace */
328 FALSE), /* pcrel_offset */
330 HOWTO (R_AARCH64_NONE, /* type */
332 3, /* size (0 = byte, 1 = short, 2 = long) */
334 FALSE, /* pc_relative */
336 complain_overflow_dont, /* complain_on_overflow */
337 bfd_elf_generic_reloc, /* special_function */
338 "R_AARCH64_NONE", /* name */
339 FALSE, /* partial_inplace */
342 FALSE), /* pcrel_offset */
346 HOWTO64 (AARCH64_R (ABS64), /* type */
348 4, /* size (4 = long long) */
350 FALSE, /* pc_relative */
352 complain_overflow_unsigned, /* complain_on_overflow */
353 bfd_elf_generic_reloc, /* special_function */
354 AARCH64_R_STR (ABS64), /* name */
355 FALSE, /* partial_inplace */
356 ALL_ONES, /* src_mask */
357 ALL_ONES, /* dst_mask */
358 FALSE), /* pcrel_offset */
361 HOWTO (AARCH64_R (ABS32), /* type */
363 2, /* size (0 = byte, 1 = short, 2 = long) */
365 FALSE, /* pc_relative */
367 complain_overflow_unsigned, /* complain_on_overflow */
368 bfd_elf_generic_reloc, /* special_function */
369 AARCH64_R_STR (ABS32), /* name */
370 FALSE, /* partial_inplace */
371 0xffffffff, /* src_mask */
372 0xffffffff, /* dst_mask */
373 FALSE), /* pcrel_offset */
376 HOWTO (AARCH64_R (ABS16), /* type */
378 1, /* size (0 = byte, 1 = short, 2 = long) */
380 FALSE, /* pc_relative */
382 complain_overflow_unsigned, /* complain_on_overflow */
383 bfd_elf_generic_reloc, /* special_function */
384 AARCH64_R_STR (ABS16), /* name */
385 FALSE, /* partial_inplace */
386 0xffff, /* src_mask */
387 0xffff, /* dst_mask */
388 FALSE), /* pcrel_offset */
390 /* .xword: (S+A-P) */
391 HOWTO64 (AARCH64_R (PREL64), /* type */
393 4, /* size (4 = long long) */
395 TRUE, /* pc_relative */
397 complain_overflow_signed, /* complain_on_overflow */
398 bfd_elf_generic_reloc, /* special_function */
399 AARCH64_R_STR (PREL64), /* name */
400 FALSE, /* partial_inplace */
401 ALL_ONES, /* src_mask */
402 ALL_ONES, /* dst_mask */
403 TRUE), /* pcrel_offset */
406 HOWTO (AARCH64_R (PREL32), /* type */
408 2, /* size (0 = byte, 1 = short, 2 = long) */
410 TRUE, /* pc_relative */
412 complain_overflow_signed, /* complain_on_overflow */
413 bfd_elf_generic_reloc, /* special_function */
414 AARCH64_R_STR (PREL32), /* name */
415 FALSE, /* partial_inplace */
416 0xffffffff, /* src_mask */
417 0xffffffff, /* dst_mask */
418 TRUE), /* pcrel_offset */
421 HOWTO (AARCH64_R (PREL16), /* type */
423 1, /* size (0 = byte, 1 = short, 2 = long) */
425 TRUE, /* pc_relative */
427 complain_overflow_signed, /* complain_on_overflow */
428 bfd_elf_generic_reloc, /* special_function */
429 AARCH64_R_STR (PREL16), /* name */
430 FALSE, /* partial_inplace */
431 0xffff, /* src_mask */
432 0xffff, /* dst_mask */
433 TRUE), /* pcrel_offset */
435 /* Group relocations to create a 16, 32, 48 or 64 bit
436 unsigned data or abs address inline. */
438 /* MOVZ: ((S+A) >> 0) & 0xffff */
439 HOWTO (AARCH64_R (MOVW_UABS_G0), /* type */
441 2, /* size (0 = byte, 1 = short, 2 = long) */
443 FALSE, /* pc_relative */
445 complain_overflow_unsigned, /* complain_on_overflow */
446 bfd_elf_generic_reloc, /* special_function */
447 AARCH64_R_STR (MOVW_UABS_G0), /* name */
448 FALSE, /* partial_inplace */
449 0xffff, /* src_mask */
450 0xffff, /* dst_mask */
451 FALSE), /* pcrel_offset */
453 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
454 HOWTO (AARCH64_R (MOVW_UABS_G0_NC), /* type */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
458 FALSE, /* pc_relative */
460 complain_overflow_dont, /* complain_on_overflow */
461 bfd_elf_generic_reloc, /* special_function */
462 AARCH64_R_STR (MOVW_UABS_G0_NC), /* name */
463 FALSE, /* partial_inplace */
464 0xffff, /* src_mask */
465 0xffff, /* dst_mask */
466 FALSE), /* pcrel_offset */
468 /* MOVZ: ((S+A) >> 16) & 0xffff */
469 HOWTO (AARCH64_R (MOVW_UABS_G1), /* type */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 FALSE, /* pc_relative */
475 complain_overflow_unsigned, /* complain_on_overflow */
476 bfd_elf_generic_reloc, /* special_function */
477 AARCH64_R_STR (MOVW_UABS_G1), /* name */
478 FALSE, /* partial_inplace */
479 0xffff, /* src_mask */
480 0xffff, /* dst_mask */
481 FALSE), /* pcrel_offset */
483 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
484 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC), /* type */
486 2, /* size (0 = byte, 1 = short, 2 = long) */
488 FALSE, /* pc_relative */
490 complain_overflow_dont, /* complain_on_overflow */
491 bfd_elf_generic_reloc, /* special_function */
492 AARCH64_R_STR (MOVW_UABS_G1_NC), /* name */
493 FALSE, /* partial_inplace */
494 0xffff, /* src_mask */
495 0xffff, /* dst_mask */
496 FALSE), /* pcrel_offset */
498 /* MOVZ: ((S+A) >> 32) & 0xffff */
499 HOWTO64 (AARCH64_R (MOVW_UABS_G2), /* type */
501 2, /* size (0 = byte, 1 = short, 2 = long) */
503 FALSE, /* pc_relative */
505 complain_overflow_unsigned, /* complain_on_overflow */
506 bfd_elf_generic_reloc, /* special_function */
507 AARCH64_R_STR (MOVW_UABS_G2), /* name */
508 FALSE, /* partial_inplace */
509 0xffff, /* src_mask */
510 0xffff, /* dst_mask */
511 FALSE), /* pcrel_offset */
513 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
514 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC), /* type */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
518 FALSE, /* pc_relative */
520 complain_overflow_dont, /* complain_on_overflow */
521 bfd_elf_generic_reloc, /* special_function */
522 AARCH64_R_STR (MOVW_UABS_G2_NC), /* name */
523 FALSE, /* partial_inplace */
524 0xffff, /* src_mask */
525 0xffff, /* dst_mask */
526 FALSE), /* pcrel_offset */
528 /* MOVZ: ((S+A) >> 48) & 0xffff */
529 HOWTO64 (AARCH64_R (MOVW_UABS_G3), /* type */
531 2, /* size (0 = byte, 1 = short, 2 = long) */
533 FALSE, /* pc_relative */
535 complain_overflow_unsigned, /* complain_on_overflow */
536 bfd_elf_generic_reloc, /* special_function */
537 AARCH64_R_STR (MOVW_UABS_G3), /* name */
538 FALSE, /* partial_inplace */
539 0xffff, /* src_mask */
540 0xffff, /* dst_mask */
541 FALSE), /* pcrel_offset */
543 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
544 signed data or abs address inline. Will change instruction
545 to MOVN or MOVZ depending on sign of calculated value. */
547 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
548 HOWTO (AARCH64_R (MOVW_SABS_G0), /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 FALSE, /* pc_relative */
554 complain_overflow_signed, /* complain_on_overflow */
555 bfd_elf_generic_reloc, /* special_function */
556 AARCH64_R_STR (MOVW_SABS_G0), /* name */
557 FALSE, /* partial_inplace */
558 0xffff, /* src_mask */
559 0xffff, /* dst_mask */
560 FALSE), /* pcrel_offset */
562 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
563 HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
567 FALSE, /* pc_relative */
569 complain_overflow_signed, /* complain_on_overflow */
570 bfd_elf_generic_reloc, /* special_function */
571 AARCH64_R_STR (MOVW_SABS_G1), /* name */
572 FALSE, /* partial_inplace */
573 0xffff, /* src_mask */
574 0xffff, /* dst_mask */
575 FALSE), /* pcrel_offset */
577 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
578 HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
582 FALSE, /* pc_relative */
584 complain_overflow_signed, /* complain_on_overflow */
585 bfd_elf_generic_reloc, /* special_function */
586 AARCH64_R_STR (MOVW_SABS_G2), /* name */
587 FALSE, /* partial_inplace */
588 0xffff, /* src_mask */
589 0xffff, /* dst_mask */
590 FALSE), /* pcrel_offset */
592 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
593 addresses: PG(x) is (x & ~0xfff). */
595 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
596 HOWTO (AARCH64_R (LD_PREL_LO19), /* type */
598 2, /* size (0 = byte, 1 = short, 2 = long) */
600 TRUE, /* pc_relative */
602 complain_overflow_signed, /* complain_on_overflow */
603 bfd_elf_generic_reloc, /* special_function */
604 AARCH64_R_STR (LD_PREL_LO19), /* name */
605 FALSE, /* partial_inplace */
606 0x7ffff, /* src_mask */
607 0x7ffff, /* dst_mask */
608 TRUE), /* pcrel_offset */
610 /* ADR: (S+A-P) & 0x1fffff */
611 HOWTO (AARCH64_R (ADR_PREL_LO21), /* type */
613 2, /* size (0 = byte, 1 = short, 2 = long) */
615 TRUE, /* pc_relative */
617 complain_overflow_signed, /* complain_on_overflow */
618 bfd_elf_generic_reloc, /* special_function */
619 AARCH64_R_STR (ADR_PREL_LO21), /* name */
620 FALSE, /* partial_inplace */
621 0x1fffff, /* src_mask */
622 0x1fffff, /* dst_mask */
623 TRUE), /* pcrel_offset */
625 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
626 HOWTO (AARCH64_R (ADR_PREL_PG_HI21), /* type */
628 2, /* size (0 = byte, 1 = short, 2 = long) */
630 TRUE, /* pc_relative */
632 complain_overflow_signed, /* complain_on_overflow */
633 bfd_elf_generic_reloc, /* special_function */
634 AARCH64_R_STR (ADR_PREL_PG_HI21), /* name */
635 FALSE, /* partial_inplace */
636 0x1fffff, /* src_mask */
637 0x1fffff, /* dst_mask */
638 TRUE), /* pcrel_offset */
640 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
641 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC), /* type */
643 2, /* size (0 = byte, 1 = short, 2 = long) */
645 TRUE, /* pc_relative */
647 complain_overflow_dont, /* complain_on_overflow */
648 bfd_elf_generic_reloc, /* special_function */
649 AARCH64_R_STR (ADR_PREL_PG_HI21_NC), /* name */
650 FALSE, /* partial_inplace */
651 0x1fffff, /* src_mask */
652 0x1fffff, /* dst_mask */
653 TRUE), /* pcrel_offset */
655 /* ADD: (S+A) & 0xfff [no overflow check] */
656 HOWTO (AARCH64_R (ADD_ABS_LO12_NC), /* type */
658 2, /* size (0 = byte, 1 = short, 2 = long) */
660 FALSE, /* pc_relative */
662 complain_overflow_dont, /* complain_on_overflow */
663 bfd_elf_generic_reloc, /* special_function */
664 AARCH64_R_STR (ADD_ABS_LO12_NC), /* name */
665 FALSE, /* partial_inplace */
666 0x3ffc00, /* src_mask */
667 0x3ffc00, /* dst_mask */
668 FALSE), /* pcrel_offset */
670 /* LD/ST8: (S+A) & 0xfff */
671 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC), /* type */
673 2, /* size (0 = byte, 1 = short, 2 = long) */
675 FALSE, /* pc_relative */
677 complain_overflow_dont, /* complain_on_overflow */
678 bfd_elf_generic_reloc, /* special_function */
679 AARCH64_R_STR (LDST8_ABS_LO12_NC), /* name */
680 FALSE, /* partial_inplace */
681 0xfff, /* src_mask */
682 0xfff, /* dst_mask */
683 FALSE), /* pcrel_offset */
685 /* Relocations for control-flow instructions. */
687 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
688 HOWTO (AARCH64_R (TSTBR14), /* type */
690 2, /* size (0 = byte, 1 = short, 2 = long) */
692 TRUE, /* pc_relative */
694 complain_overflow_signed, /* complain_on_overflow */
695 bfd_elf_generic_reloc, /* special_function */
696 AARCH64_R_STR (TSTBR14), /* name */
697 FALSE, /* partial_inplace */
698 0x3fff, /* src_mask */
699 0x3fff, /* dst_mask */
700 TRUE), /* pcrel_offset */
702 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
703 HOWTO (AARCH64_R (CONDBR19), /* type */
705 2, /* size (0 = byte, 1 = short, 2 = long) */
707 TRUE, /* pc_relative */
709 complain_overflow_signed, /* complain_on_overflow */
710 bfd_elf_generic_reloc, /* special_function */
711 AARCH64_R_STR (CONDBR19), /* name */
712 FALSE, /* partial_inplace */
713 0x7ffff, /* src_mask */
714 0x7ffff, /* dst_mask */
715 TRUE), /* pcrel_offset */
717 /* B: ((S+A-P) >> 2) & 0x3ffffff */
718 HOWTO (AARCH64_R (JUMP26), /* type */
720 2, /* size (0 = byte, 1 = short, 2 = long) */
722 TRUE, /* pc_relative */
724 complain_overflow_signed, /* complain_on_overflow */
725 bfd_elf_generic_reloc, /* special_function */
726 AARCH64_R_STR (JUMP26), /* name */
727 FALSE, /* partial_inplace */
728 0x3ffffff, /* src_mask */
729 0x3ffffff, /* dst_mask */
730 TRUE), /* pcrel_offset */
732 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
733 HOWTO (AARCH64_R (CALL26), /* type */
735 2, /* size (0 = byte, 1 = short, 2 = long) */
737 TRUE, /* pc_relative */
739 complain_overflow_signed, /* complain_on_overflow */
740 bfd_elf_generic_reloc, /* special_function */
741 AARCH64_R_STR (CALL26), /* name */
742 FALSE, /* partial_inplace */
743 0x3ffffff, /* src_mask */
744 0x3ffffff, /* dst_mask */
745 TRUE), /* pcrel_offset */
747 /* LD/ST16: (S+A) & 0xffe */
748 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */
750 2, /* size (0 = byte, 1 = short, 2 = long) */
752 FALSE, /* pc_relative */
754 complain_overflow_dont, /* complain_on_overflow */
755 bfd_elf_generic_reloc, /* special_function */
756 AARCH64_R_STR (LDST16_ABS_LO12_NC), /* name */
757 FALSE, /* partial_inplace */
758 0xffe, /* src_mask */
759 0xffe, /* dst_mask */
760 FALSE), /* pcrel_offset */
762 /* LD/ST32: (S+A) & 0xffc */
763 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC), /* type */
765 2, /* size (0 = byte, 1 = short, 2 = long) */
767 FALSE, /* pc_relative */
769 complain_overflow_dont, /* complain_on_overflow */
770 bfd_elf_generic_reloc, /* special_function */
771 AARCH64_R_STR (LDST32_ABS_LO12_NC), /* name */
772 FALSE, /* partial_inplace */
773 0xffc, /* src_mask */
774 0xffc, /* dst_mask */
775 FALSE), /* pcrel_offset */
777 /* LD/ST64: (S+A) & 0xff8 */
778 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC), /* type */
780 2, /* size (0 = byte, 1 = short, 2 = long) */
782 FALSE, /* pc_relative */
784 complain_overflow_dont, /* complain_on_overflow */
785 bfd_elf_generic_reloc, /* special_function */
786 AARCH64_R_STR (LDST64_ABS_LO12_NC), /* name */
787 FALSE, /* partial_inplace */
788 0xff8, /* src_mask */
789 0xff8, /* dst_mask */
790 FALSE), /* pcrel_offset */
792 /* LD/ST128: (S+A) & 0xff0 */
793 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC), /* type */
795 2, /* size (0 = byte, 1 = short, 2 = long) */
797 FALSE, /* pc_relative */
799 complain_overflow_dont, /* complain_on_overflow */
800 bfd_elf_generic_reloc, /* special_function */
801 AARCH64_R_STR (LDST128_ABS_LO12_NC), /* name */
802 FALSE, /* partial_inplace */
803 0xff0, /* src_mask */
804 0xff0, /* dst_mask */
805 FALSE), /* pcrel_offset */
807 /* Set a load-literal immediate field to bits
808 0x1FFFFC of G(S)-P */
809 HOWTO (AARCH64_R (GOT_LD_PREL19), /* type */
811 2, /* size (0 = byte,1 = short,2 = long) */
813 TRUE, /* pc_relative */
815 complain_overflow_signed, /* complain_on_overflow */
816 bfd_elf_generic_reloc, /* special_function */
817 AARCH64_R_STR (GOT_LD_PREL19), /* name */
818 FALSE, /* partial_inplace */
819 0xffffe0, /* src_mask */
820 0xffffe0, /* dst_mask */
821 TRUE), /* pcrel_offset */
823 /* Get to the page for the GOT entry for the symbol
824 (G(S) - P) using an ADRP instruction. */
825 HOWTO (AARCH64_R (ADR_GOT_PAGE), /* type */
827 2, /* size (0 = byte, 1 = short, 2 = long) */
829 TRUE, /* pc_relative */
831 complain_overflow_dont, /* complain_on_overflow */
832 bfd_elf_generic_reloc, /* special_function */
833 AARCH64_R_STR (ADR_GOT_PAGE), /* name */
834 FALSE, /* partial_inplace */
835 0x1fffff, /* src_mask */
836 0x1fffff, /* dst_mask */
837 TRUE), /* pcrel_offset */
839 /* LD64: GOT offset G(S) & 0xff8 */
840 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC), /* type */
842 2, /* size (0 = byte, 1 = short, 2 = long) */
844 FALSE, /* pc_relative */
846 complain_overflow_dont, /* complain_on_overflow */
847 bfd_elf_generic_reloc, /* special_function */
848 AARCH64_R_STR (LD64_GOT_LO12_NC), /* name */
849 FALSE, /* partial_inplace */
850 0xff8, /* src_mask */
851 0xff8, /* dst_mask */
852 FALSE), /* pcrel_offset */
854 /* LD32: GOT offset G(S) & 0xffc */
855 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC), /* type */
857 2, /* size (0 = byte, 1 = short, 2 = long) */
859 FALSE, /* pc_relative */
861 complain_overflow_dont, /* complain_on_overflow */
862 bfd_elf_generic_reloc, /* special_function */
863 AARCH64_R_STR (LD32_GOT_LO12_NC), /* name */
864 FALSE, /* partial_inplace */
865 0xffc, /* src_mask */
866 0xffc, /* dst_mask */
867 FALSE), /* pcrel_offset */
869 /* LD64: GOT offset for the symbol. */
870 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15), /* type */
872 2, /* size (0 = byte, 1 = short, 2 = long) */
874 FALSE, /* pc_relative */
876 complain_overflow_unsigned, /* complain_on_overflow */
877 bfd_elf_generic_reloc, /* special_function */
878 AARCH64_R_STR (LD64_GOTOFF_LO15), /* name */
879 FALSE, /* partial_inplace */
880 0x7ff8, /* src_mask */
881 0x7ff8, /* dst_mask */
882 FALSE), /* pcrel_offset */
884 /* LD32: GOT offset to the page address of GOT table.
885 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
886 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14), /* type */
888 2, /* size (0 = byte, 1 = short, 2 = long) */
890 FALSE, /* pc_relative */
892 complain_overflow_unsigned, /* complain_on_overflow */
893 bfd_elf_generic_reloc, /* special_function */
894 AARCH64_R_STR (LD32_GOTPAGE_LO14), /* name */
895 FALSE, /* partial_inplace */
896 0x5ffc, /* src_mask */
897 0x5ffc, /* dst_mask */
898 FALSE), /* pcrel_offset */
900 /* LD64: GOT offset to the page address of GOT table.
901 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
902 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15), /* type */
904 2, /* size (0 = byte, 1 = short, 2 = long) */
906 FALSE, /* pc_relative */
908 complain_overflow_unsigned, /* complain_on_overflow */
909 bfd_elf_generic_reloc, /* special_function */
910 AARCH64_R_STR (LD64_GOTPAGE_LO15), /* name */
911 FALSE, /* partial_inplace */
912 0x7ff8, /* src_mask */
913 0x7ff8, /* dst_mask */
914 FALSE), /* pcrel_offset */
916 /* Get to the page for the GOT entry for the symbol
917 (G(S) - P) using an ADRP instruction. */
918 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21), /* type */
920 2, /* size (0 = byte, 1 = short, 2 = long) */
922 TRUE, /* pc_relative */
924 complain_overflow_dont, /* complain_on_overflow */
925 bfd_elf_generic_reloc, /* special_function */
926 AARCH64_R_STR (TLSGD_ADR_PAGE21), /* name */
927 FALSE, /* partial_inplace */
928 0x1fffff, /* src_mask */
929 0x1fffff, /* dst_mask */
930 TRUE), /* pcrel_offset */
932 HOWTO (AARCH64_R (TLSGD_ADR_PREL21), /* type */
934 2, /* size (0 = byte, 1 = short, 2 = long) */
936 TRUE, /* pc_relative */
938 complain_overflow_dont, /* complain_on_overflow */
939 bfd_elf_generic_reloc, /* special_function */
940 AARCH64_R_STR (TLSGD_ADR_PREL21), /* name */
941 FALSE, /* partial_inplace */
942 0x1fffff, /* src_mask */
943 0x1fffff, /* dst_mask */
944 TRUE), /* pcrel_offset */
946 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
947 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC), /* type */
949 2, /* size (0 = byte, 1 = short, 2 = long) */
951 FALSE, /* pc_relative */
953 complain_overflow_dont, /* complain_on_overflow */
954 bfd_elf_generic_reloc, /* special_function */
955 AARCH64_R_STR (TLSGD_ADD_LO12_NC), /* name */
956 FALSE, /* partial_inplace */
957 0xfff, /* src_mask */
958 0xfff, /* dst_mask */
959 FALSE), /* pcrel_offset */
961 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
963 2, /* size (0 = byte, 1 = short, 2 = long) */
965 FALSE, /* pc_relative */
967 complain_overflow_dont, /* complain_on_overflow */
968 bfd_elf_generic_reloc, /* special_function */
969 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1), /* name */
970 FALSE, /* partial_inplace */
971 0xffff, /* src_mask */
972 0xffff, /* dst_mask */
973 FALSE), /* pcrel_offset */
975 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC), /* type */
977 2, /* size (0 = byte, 1 = short, 2 = long) */
979 FALSE, /* pc_relative */
981 complain_overflow_dont, /* complain_on_overflow */
982 bfd_elf_generic_reloc, /* special_function */
983 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC), /* name */
984 FALSE, /* partial_inplace */
985 0xffff, /* src_mask */
986 0xffff, /* dst_mask */
987 FALSE), /* pcrel_offset */
989 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21), /* type */
991 2, /* size (0 = byte, 1 = short, 2 = long) */
993 FALSE, /* pc_relative */
995 complain_overflow_dont, /* complain_on_overflow */
996 bfd_elf_generic_reloc, /* special_function */
997 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21), /* name */
998 FALSE, /* partial_inplace */
999 0x1fffff, /* src_mask */
1000 0x1fffff, /* dst_mask */
1001 FALSE), /* pcrel_offset */
1003 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC), /* type */
1005 2, /* size (0 = byte, 1 = short, 2 = long) */
1007 FALSE, /* pc_relative */
1009 complain_overflow_dont, /* complain_on_overflow */
1010 bfd_elf_generic_reloc, /* special_function */
1011 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC), /* name */
1012 FALSE, /* partial_inplace */
1013 0xff8, /* src_mask */
1014 0xff8, /* dst_mask */
1015 FALSE), /* pcrel_offset */
1017 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC), /* type */
1019 2, /* size (0 = byte, 1 = short, 2 = long) */
1021 FALSE, /* pc_relative */
1023 complain_overflow_dont, /* complain_on_overflow */
1024 bfd_elf_generic_reloc, /* special_function */
1025 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC), /* name */
1026 FALSE, /* partial_inplace */
1027 0xffc, /* src_mask */
1028 0xffc, /* dst_mask */
1029 FALSE), /* pcrel_offset */
1031 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19), /* type */
1033 2, /* size (0 = byte, 1 = short, 2 = long) */
1035 FALSE, /* pc_relative */
1037 complain_overflow_dont, /* complain_on_overflow */
1038 bfd_elf_generic_reloc, /* special_function */
1039 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19), /* name */
1040 FALSE, /* partial_inplace */
1041 0x1ffffc, /* src_mask */
1042 0x1ffffc, /* dst_mask */
1043 FALSE), /* pcrel_offset */
1045 /* Unsigned 12 bit byte offset to module TLS base address. */
1046 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12), /* type */
1048 2, /* size (0 = byte, 1 = short, 2 = long) */
1050 FALSE, /* pc_relative */
1052 complain_overflow_unsigned, /* complain_on_overflow */
1053 bfd_elf_generic_reloc, /* special_function */
1054 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12), /* name */
1055 FALSE, /* partial_inplace */
1056 0xfff, /* src_mask */
1057 0xfff, /* dst_mask */
1058 FALSE), /* pcrel_offset */
1060 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1061 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC), /* type */
1063 2, /* size (0 = byte, 1 = short, 2 = long) */
1065 FALSE, /* pc_relative */
1067 complain_overflow_dont, /* complain_on_overflow */
1068 bfd_elf_generic_reloc, /* special_function */
1069 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC), /* name */
1070 FALSE, /* partial_inplace */
1071 0xfff, /* src_mask */
1072 0xfff, /* dst_mask */
1073 FALSE), /* pcrel_offset */
1075 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1076 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC), /* type */
1078 2, /* size (0 = byte, 1 = short, 2 = long) */
1080 FALSE, /* pc_relative */
1082 complain_overflow_dont, /* complain_on_overflow */
1083 bfd_elf_generic_reloc, /* special_function */
1084 AARCH64_R_STR (TLSLD_ADD_LO12_NC), /* name */
1085 FALSE, /* partial_inplace */
1086 0xfff, /* src_mask */
1087 0xfff, /* dst_mask */
1088 FALSE), /* pcrel_offset */
1090 /* Get to the page for the GOT entry for the symbol
1091 (G(S) - P) using an ADRP instruction. */
1092 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21), /* type */
1093 12, /* rightshift */
1094 2, /* size (0 = byte, 1 = short, 2 = long) */
1096 TRUE, /* pc_relative */
1098 complain_overflow_signed, /* complain_on_overflow */
1099 bfd_elf_generic_reloc, /* special_function */
1100 AARCH64_R_STR (TLSLD_ADR_PAGE21), /* name */
1101 FALSE, /* partial_inplace */
1102 0x1fffff, /* src_mask */
1103 0x1fffff, /* dst_mask */
1104 TRUE), /* pcrel_offset */
1106 HOWTO (AARCH64_R (TLSLD_ADR_PREL21), /* type */
1108 2, /* size (0 = byte, 1 = short, 2 = long) */
1110 TRUE, /* pc_relative */
1112 complain_overflow_signed, /* complain_on_overflow */
1113 bfd_elf_generic_reloc, /* special_function */
1114 AARCH64_R_STR (TLSLD_ADR_PREL21), /* name */
1115 FALSE, /* partial_inplace */
1116 0x1fffff, /* src_mask */
1117 0x1fffff, /* dst_mask */
1118 TRUE), /* pcrel_offset */
1120 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
1121 32, /* rightshift */
1122 2, /* size (0 = byte, 1 = short, 2 = long) */
1124 FALSE, /* pc_relative */
1126 complain_overflow_unsigned, /* complain_on_overflow */
1127 bfd_elf_generic_reloc, /* special_function */
1128 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2), /* name */
1129 FALSE, /* partial_inplace */
1130 0xffff, /* src_mask */
1131 0xffff, /* dst_mask */
1132 FALSE), /* pcrel_offset */
1134 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1), /* type */
1135 16, /* rightshift */
1136 2, /* size (0 = byte, 1 = short, 2 = long) */
1138 FALSE, /* pc_relative */
1140 complain_overflow_dont, /* complain_on_overflow */
1141 bfd_elf_generic_reloc, /* special_function */
1142 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1), /* name */
1143 FALSE, /* partial_inplace */
1144 0xffff, /* src_mask */
1145 0xffff, /* dst_mask */
1146 FALSE), /* pcrel_offset */
1148 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC), /* type */
1149 16, /* rightshift */
1150 2, /* size (0 = byte, 1 = short, 2 = long) */
1152 FALSE, /* pc_relative */
1154 complain_overflow_dont, /* complain_on_overflow */
1155 bfd_elf_generic_reloc, /* special_function */
1156 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC), /* name */
1157 FALSE, /* partial_inplace */
1158 0xffff, /* src_mask */
1159 0xffff, /* dst_mask */
1160 FALSE), /* pcrel_offset */
1162 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0), /* type */
1164 2, /* size (0 = byte, 1 = short, 2 = long) */
1166 FALSE, /* pc_relative */
1168 complain_overflow_dont, /* complain_on_overflow */
1169 bfd_elf_generic_reloc, /* special_function */
1170 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0), /* name */
1171 FALSE, /* partial_inplace */
1172 0xffff, /* src_mask */
1173 0xffff, /* dst_mask */
1174 FALSE), /* pcrel_offset */
1176 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC), /* type */
1178 2, /* size (0 = byte, 1 = short, 2 = long) */
1180 FALSE, /* pc_relative */
1182 complain_overflow_dont, /* complain_on_overflow */
1183 bfd_elf_generic_reloc, /* special_function */
1184 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC), /* name */
1185 FALSE, /* partial_inplace */
1186 0xffff, /* src_mask */
1187 0xffff, /* dst_mask */
1188 FALSE), /* pcrel_offset */
1190 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12), /* type */
1191 12, /* rightshift */
1192 2, /* size (0 = byte, 1 = short, 2 = long) */
1194 FALSE, /* pc_relative */
1196 complain_overflow_unsigned, /* complain_on_overflow */
1197 bfd_elf_generic_reloc, /* special_function */
1198 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12), /* name */
1199 FALSE, /* partial_inplace */
1200 0xfff, /* src_mask */
1201 0xfff, /* dst_mask */
1202 FALSE), /* pcrel_offset */
1204 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12), /* type */
1206 2, /* size (0 = byte, 1 = short, 2 = long) */
1208 FALSE, /* pc_relative */
1210 complain_overflow_unsigned, /* complain_on_overflow */
1211 bfd_elf_generic_reloc, /* special_function */
1212 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12), /* name */
1213 FALSE, /* partial_inplace */
1214 0xfff, /* src_mask */
1215 0xfff, /* dst_mask */
1216 FALSE), /* pcrel_offset */
1218 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC), /* type */
1220 2, /* size (0 = byte, 1 = short, 2 = long) */
1222 FALSE, /* pc_relative */
1224 complain_overflow_dont, /* complain_on_overflow */
1225 bfd_elf_generic_reloc, /* special_function */
1226 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC), /* name */
1227 FALSE, /* partial_inplace */
1228 0xfff, /* src_mask */
1229 0xfff, /* dst_mask */
1230 FALSE), /* pcrel_offset */
1232 HOWTO (AARCH64_R (TLSDESC_LD_PREL19), /* type */
1234 2, /* size (0 = byte, 1 = short, 2 = long) */
1236 TRUE, /* pc_relative */
1238 complain_overflow_dont, /* complain_on_overflow */
1239 bfd_elf_generic_reloc, /* special_function */
1240 AARCH64_R_STR (TLSDESC_LD_PREL19), /* name */
1241 FALSE, /* partial_inplace */
1242 0x0ffffe0, /* src_mask */
1243 0x0ffffe0, /* dst_mask */
1244 TRUE), /* pcrel_offset */
1246 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21), /* type */
1248 2, /* size (0 = byte, 1 = short, 2 = long) */
1250 TRUE, /* pc_relative */
1252 complain_overflow_dont, /* complain_on_overflow */
1253 bfd_elf_generic_reloc, /* special_function */
1254 AARCH64_R_STR (TLSDESC_ADR_PREL21), /* name */
1255 FALSE, /* partial_inplace */
1256 0x1fffff, /* src_mask */
1257 0x1fffff, /* dst_mask */
1258 TRUE), /* pcrel_offset */
1260 /* Get to the page for the GOT entry for the symbol
1261 (G(S) - P) using an ADRP instruction. */
1262 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21), /* type */
1263 12, /* rightshift */
1264 2, /* size (0 = byte, 1 = short, 2 = long) */
1266 TRUE, /* pc_relative */
1268 complain_overflow_dont, /* complain_on_overflow */
1269 bfd_elf_generic_reloc, /* special_function */
1270 AARCH64_R_STR (TLSDESC_ADR_PAGE21), /* name */
1271 FALSE, /* partial_inplace */
1272 0x1fffff, /* src_mask */
1273 0x1fffff, /* dst_mask */
1274 TRUE), /* pcrel_offset */
1276 /* LD64: GOT offset G(S) & 0xff8. */
1277 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC), /* type */
1279 2, /* size (0 = byte, 1 = short, 2 = long) */
1281 FALSE, /* pc_relative */
1283 complain_overflow_dont, /* complain_on_overflow */
1284 bfd_elf_generic_reloc, /* special_function */
1285 AARCH64_R_STR (TLSDESC_LD64_LO12_NC), /* name */
1286 FALSE, /* partial_inplace */
1287 0xff8, /* src_mask */
1288 0xff8, /* dst_mask */
1289 FALSE), /* pcrel_offset */
1291 /* LD32: GOT offset G(S) & 0xffc. */
1292 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC), /* type */
1294 2, /* size (0 = byte, 1 = short, 2 = long) */
1296 FALSE, /* pc_relative */
1298 complain_overflow_dont, /* complain_on_overflow */
1299 bfd_elf_generic_reloc, /* special_function */
1300 AARCH64_R_STR (TLSDESC_LD32_LO12_NC), /* name */
1301 FALSE, /* partial_inplace */
1302 0xffc, /* src_mask */
1303 0xffc, /* dst_mask */
1304 FALSE), /* pcrel_offset */
1306 /* ADD: GOT offset G(S) & 0xfff. */
1307 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC), /* type */
1309 2, /* size (0 = byte, 1 = short, 2 = long) */
1311 FALSE, /* pc_relative */
1313 complain_overflow_dont, /* complain_on_overflow */
1314 bfd_elf_generic_reloc, /* special_function */
1315 AARCH64_R_STR (TLSDESC_ADD_LO12_NC), /* name */
1316 FALSE, /* partial_inplace */
1317 0xfff, /* src_mask */
1318 0xfff, /* dst_mask */
1319 FALSE), /* pcrel_offset */
1321 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1), /* type */
1322 16, /* rightshift */
1323 2, /* size (0 = byte, 1 = short, 2 = long) */
1325 FALSE, /* pc_relative */
1327 complain_overflow_dont, /* complain_on_overflow */
1328 bfd_elf_generic_reloc, /* special_function */
1329 AARCH64_R_STR (TLSDESC_OFF_G1), /* name */
1330 FALSE, /* partial_inplace */
1331 0xffff, /* src_mask */
1332 0xffff, /* dst_mask */
1333 FALSE), /* pcrel_offset */
1335 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC), /* type */
1337 2, /* size (0 = byte, 1 = short, 2 = long) */
1339 FALSE, /* pc_relative */
1341 complain_overflow_dont, /* complain_on_overflow */
1342 bfd_elf_generic_reloc, /* special_function */
1343 AARCH64_R_STR (TLSDESC_OFF_G0_NC), /* name */
1344 FALSE, /* partial_inplace */
1345 0xffff, /* src_mask */
1346 0xffff, /* dst_mask */
1347 FALSE), /* pcrel_offset */
1349 HOWTO64 (AARCH64_R (TLSDESC_LDR), /* type */
1351 2, /* size (0 = byte, 1 = short, 2 = long) */
1353 FALSE, /* pc_relative */
1355 complain_overflow_dont, /* complain_on_overflow */
1356 bfd_elf_generic_reloc, /* special_function */
1357 AARCH64_R_STR (TLSDESC_LDR), /* name */
1358 FALSE, /* partial_inplace */
1361 FALSE), /* pcrel_offset */
1363 HOWTO64 (AARCH64_R (TLSDESC_ADD), /* type */
1365 2, /* size (0 = byte, 1 = short, 2 = long) */
1367 FALSE, /* pc_relative */
1369 complain_overflow_dont, /* complain_on_overflow */
1370 bfd_elf_generic_reloc, /* special_function */
1371 AARCH64_R_STR (TLSDESC_ADD), /* name */
1372 FALSE, /* partial_inplace */
1375 FALSE), /* pcrel_offset */
1377 HOWTO (AARCH64_R (TLSDESC_CALL), /* type */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1381 FALSE, /* pc_relative */
1383 complain_overflow_dont, /* complain_on_overflow */
1384 bfd_elf_generic_reloc, /* special_function */
1385 AARCH64_R_STR (TLSDESC_CALL), /* name */
1386 FALSE, /* partial_inplace */
1389 FALSE), /* pcrel_offset */
1391 HOWTO (AARCH64_R (COPY), /* type */
1393 2, /* size (0 = byte, 1 = short, 2 = long) */
1395 FALSE, /* pc_relative */
1397 complain_overflow_bitfield, /* complain_on_overflow */
1398 bfd_elf_generic_reloc, /* special_function */
1399 AARCH64_R_STR (COPY), /* name */
1400 TRUE, /* partial_inplace */
1401 0xffffffff, /* src_mask */
1402 0xffffffff, /* dst_mask */
1403 FALSE), /* pcrel_offset */
1405 HOWTO (AARCH64_R (GLOB_DAT), /* type */
1407 2, /* size (0 = byte, 1 = short, 2 = long) */
1409 FALSE, /* pc_relative */
1411 complain_overflow_bitfield, /* complain_on_overflow */
1412 bfd_elf_generic_reloc, /* special_function */
1413 AARCH64_R_STR (GLOB_DAT), /* name */
1414 TRUE, /* partial_inplace */
1415 0xffffffff, /* src_mask */
1416 0xffffffff, /* dst_mask */
1417 FALSE), /* pcrel_offset */
1419 HOWTO (AARCH64_R (JUMP_SLOT), /* type */
1421 2, /* size (0 = byte, 1 = short, 2 = long) */
1423 FALSE, /* pc_relative */
1425 complain_overflow_bitfield, /* complain_on_overflow */
1426 bfd_elf_generic_reloc, /* special_function */
1427 AARCH64_R_STR (JUMP_SLOT), /* name */
1428 TRUE, /* partial_inplace */
1429 0xffffffff, /* src_mask */
1430 0xffffffff, /* dst_mask */
1431 FALSE), /* pcrel_offset */
1433 HOWTO (AARCH64_R (RELATIVE), /* type */
1435 2, /* size (0 = byte, 1 = short, 2 = long) */
1437 FALSE, /* pc_relative */
1439 complain_overflow_bitfield, /* complain_on_overflow */
1440 bfd_elf_generic_reloc, /* special_function */
1441 AARCH64_R_STR (RELATIVE), /* name */
1442 TRUE, /* partial_inplace */
1443 ALL_ONES, /* src_mask */
1444 ALL_ONES, /* dst_mask */
1445 FALSE), /* pcrel_offset */
1447 HOWTO (AARCH64_R (TLS_DTPMOD), /* type */
1449 2, /* size (0 = byte, 1 = short, 2 = long) */
1451 FALSE, /* pc_relative */
1453 complain_overflow_dont, /* complain_on_overflow */
1454 bfd_elf_generic_reloc, /* special_function */
1456 AARCH64_R_STR (TLS_DTPMOD64), /* name */
1458 AARCH64_R_STR (TLS_DTPMOD), /* name */
1460 FALSE, /* partial_inplace */
1462 ALL_ONES, /* dst_mask */
1463 FALSE), /* pc_reloffset */
1465 HOWTO (AARCH64_R (TLS_DTPREL), /* type */
1467 2, /* size (0 = byte, 1 = short, 2 = long) */
1469 FALSE, /* pc_relative */
1471 complain_overflow_dont, /* complain_on_overflow */
1472 bfd_elf_generic_reloc, /* special_function */
1474 AARCH64_R_STR (TLS_DTPREL64), /* name */
1476 AARCH64_R_STR (TLS_DTPREL), /* name */
1478 FALSE, /* partial_inplace */
1480 ALL_ONES, /* dst_mask */
1481 FALSE), /* pcrel_offset */
1483 HOWTO (AARCH64_R (TLS_TPREL), /* type */
1485 2, /* size (0 = byte, 1 = short, 2 = long) */
1487 FALSE, /* pc_relative */
1489 complain_overflow_dont, /* complain_on_overflow */
1490 bfd_elf_generic_reloc, /* special_function */
1492 AARCH64_R_STR (TLS_TPREL64), /* name */
1494 AARCH64_R_STR (TLS_TPREL), /* name */
1496 FALSE, /* partial_inplace */
1498 ALL_ONES, /* dst_mask */
1499 FALSE), /* pcrel_offset */
1501 HOWTO (AARCH64_R (TLSDESC), /* type */
1503 2, /* size (0 = byte, 1 = short, 2 = long) */
1505 FALSE, /* pc_relative */
1507 complain_overflow_dont, /* complain_on_overflow */
1508 bfd_elf_generic_reloc, /* special_function */
1509 AARCH64_R_STR (TLSDESC), /* name */
1510 FALSE, /* partial_inplace */
1512 ALL_ONES, /* dst_mask */
1513 FALSE), /* pcrel_offset */
1515 HOWTO (AARCH64_R (IRELATIVE), /* type */
1517 2, /* size (0 = byte, 1 = short, 2 = long) */
1519 FALSE, /* pc_relative */
1521 complain_overflow_bitfield, /* complain_on_overflow */
1522 bfd_elf_generic_reloc, /* special_function */
1523 AARCH64_R_STR (IRELATIVE), /* name */
1524 FALSE, /* partial_inplace */
1526 ALL_ONES, /* dst_mask */
1527 FALSE), /* pcrel_offset */
1532 static reloc_howto_type elfNN_aarch64_howto_none =
1533 HOWTO (R_AARCH64_NONE, /* type */
1535 3, /* size (0 = byte, 1 = short, 2 = long) */
1537 FALSE, /* pc_relative */
1539 complain_overflow_dont,/* complain_on_overflow */
1540 bfd_elf_generic_reloc, /* special_function */
1541 "R_AARCH64_NONE", /* name */
1542 FALSE, /* partial_inplace */
1545 FALSE); /* pcrel_offset */
1547 /* Given HOWTO, return the bfd internal relocation enumerator. */
1549 static bfd_reloc_code_real_type
1550 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type *howto)
1553 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table);
1554 const ptrdiff_t offset
1555 = howto - elfNN_aarch64_howto_table;
1557 if (offset > 0 && offset < size - 1)
1558 return BFD_RELOC_AARCH64_RELOC_START + offset;
1560 if (howto == &elfNN_aarch64_howto_none)
1561 return BFD_RELOC_AARCH64_NONE;
1563 return BFD_RELOC_AARCH64_RELOC_START;
1566 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1568 static bfd_reloc_code_real_type
1569 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type)
1571 static bfd_boolean initialized_p = FALSE;
1572 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1573 static unsigned int offsets[R_AARCH64_end];
1575 if (initialized_p == FALSE)
1579 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
1580 if (elfNN_aarch64_howto_table[i].type != 0)
1581 offsets[elfNN_aarch64_howto_table[i].type] = i;
1583 initialized_p = TRUE;
1586 if (r_type == R_AARCH64_NONE || r_type == R_AARCH64_NULL)
1587 return BFD_RELOC_AARCH64_NONE;
1589 /* PR 17512: file: b371e70a. */
1590 if (r_type >= R_AARCH64_end)
1592 _bfd_error_handler (_("Invalid AArch64 reloc number: %d"), r_type);
1593 bfd_set_error (bfd_error_bad_value);
1594 return BFD_RELOC_AARCH64_NONE;
1597 return BFD_RELOC_AARCH64_RELOC_START + offsets[r_type];
1600 struct elf_aarch64_reloc_map
1602 bfd_reloc_code_real_type from;
1603 bfd_reloc_code_real_type to;
1606 /* Map bfd generic reloc to AArch64-specific reloc. */
1607 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map[] =
1609 {BFD_RELOC_NONE, BFD_RELOC_AARCH64_NONE},
1611 /* Basic data relocations. */
1612 {BFD_RELOC_CTOR, BFD_RELOC_AARCH64_NN},
1613 {BFD_RELOC_64, BFD_RELOC_AARCH64_64},
1614 {BFD_RELOC_32, BFD_RELOC_AARCH64_32},
1615 {BFD_RELOC_16, BFD_RELOC_AARCH64_16},
1616 {BFD_RELOC_64_PCREL, BFD_RELOC_AARCH64_64_PCREL},
1617 {BFD_RELOC_32_PCREL, BFD_RELOC_AARCH64_32_PCREL},
1618 {BFD_RELOC_16_PCREL, BFD_RELOC_AARCH64_16_PCREL},
1621 /* Given the bfd internal relocation enumerator in CODE, return the
1622 corresponding howto entry. */
1624 static reloc_howto_type *
1625 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
1629 /* Convert bfd generic reloc to AArch64-specific reloc. */
1630 if (code < BFD_RELOC_AARCH64_RELOC_START
1631 || code > BFD_RELOC_AARCH64_RELOC_END)
1632 for (i = 0; i < ARRAY_SIZE (elf_aarch64_reloc_map); i++)
1633 if (elf_aarch64_reloc_map[i].from == code)
1635 code = elf_aarch64_reloc_map[i].to;
1639 if (code > BFD_RELOC_AARCH64_RELOC_START
1640 && code < BFD_RELOC_AARCH64_RELOC_END)
1641 if (elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START].type)
1642 return &elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START];
1644 if (code == BFD_RELOC_AARCH64_NONE)
1645 return &elfNN_aarch64_howto_none;
1650 static reloc_howto_type *
1651 elfNN_aarch64_howto_from_type (unsigned int r_type)
1653 bfd_reloc_code_real_type val;
1654 reloc_howto_type *howto;
1659 bfd_set_error (bfd_error_bad_value);
1664 if (r_type == R_AARCH64_NONE)
1665 return &elfNN_aarch64_howto_none;
1667 val = elfNN_aarch64_bfd_reloc_from_type (r_type);
1668 howto = elfNN_aarch64_howto_from_bfd_reloc (val);
1673 bfd_set_error (bfd_error_bad_value);
1678 elfNN_aarch64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
1679 Elf_Internal_Rela *elf_reloc)
1681 unsigned int r_type;
1683 r_type = ELFNN_R_TYPE (elf_reloc->r_info);
1684 bfd_reloc->howto = elfNN_aarch64_howto_from_type (r_type);
1687 static reloc_howto_type *
1688 elfNN_aarch64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1689 bfd_reloc_code_real_type code)
1691 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (code);
1696 bfd_set_error (bfd_error_bad_value);
1700 static reloc_howto_type *
1701 elfNN_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1706 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
1707 if (elfNN_aarch64_howto_table[i].name != NULL
1708 && strcasecmp (elfNN_aarch64_howto_table[i].name, r_name) == 0)
1709 return &elfNN_aarch64_howto_table[i];
1714 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
1715 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1716 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
1717 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1719 /* The linker script knows the section names for placement.
1720 The entry_names are used to do simple name mangling on the stubs.
1721 Given a function name, and its type, the stub can be found. The
1722 name can be changed. The only requirement is the %s be present. */
1723 #define STUB_ENTRY_NAME "__%s_veneer"
1725 /* The name of the dynamic interpreter. This is put in the .interp
1727 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1729 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1730 (((1 << 25) - 1) << 2)
1731 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1734 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1735 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1738 aarch64_valid_for_adrp_p (bfd_vma value, bfd_vma place)
1740 bfd_signed_vma offset = (bfd_signed_vma) (PG (value) - PG (place)) >> 12;
1741 return offset <= AARCH64_MAX_ADRP_IMM && offset >= AARCH64_MIN_ADRP_IMM;
1745 aarch64_valid_branch_p (bfd_vma value, bfd_vma place)
1747 bfd_signed_vma offset = (bfd_signed_vma) (value - place);
1748 return (offset <= AARCH64_MAX_FWD_BRANCH_OFFSET
1749 && offset >= AARCH64_MAX_BWD_BRANCH_OFFSET);
1752 static const uint32_t aarch64_adrp_branch_stub [] =
1754 0x90000010, /* adrp ip0, X */
1755 /* R_AARCH64_ADR_HI21_PCREL(X) */
1756 0x91000210, /* add ip0, ip0, :lo12:X */
1757 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
1758 0xd61f0200, /* br ip0 */
1761 static const uint32_t aarch64_long_branch_stub[] =
1764 0x58000090, /* ldr ip0, 1f */
1766 0x18000090, /* ldr wip0, 1f */
1768 0x10000011, /* adr ip1, #0 */
1769 0x8b110210, /* add ip0, ip0, ip1 */
1770 0xd61f0200, /* br ip0 */
1771 0x00000000, /* 1: .xword or .word
1772 R_AARCH64_PRELNN(X) + 12
1777 static const uint32_t aarch64_erratum_835769_stub[] =
1779 0x00000000, /* Placeholder for multiply accumulate. */
1780 0x14000000, /* b <label> */
1783 static const uint32_t aarch64_erratum_843419_stub[] =
1785 0x00000000, /* Placeholder for LDR instruction. */
1786 0x14000000, /* b <label> */
1789 /* Section name for stubs is the associated section name plus this
1791 #define STUB_SUFFIX ".stub"
1793 enum elf_aarch64_stub_type
1796 aarch64_stub_adrp_branch,
1797 aarch64_stub_long_branch,
1798 aarch64_stub_erratum_835769_veneer,
1799 aarch64_stub_erratum_843419_veneer,
1802 struct elf_aarch64_stub_hash_entry
1804 /* Base hash table entry structure. */
1805 struct bfd_hash_entry root;
1807 /* The stub section. */
1810 /* Offset within stub_sec of the beginning of this stub. */
1811 bfd_vma stub_offset;
1813 /* Given the symbol's value and its section we can determine its final
1814 value when building the stubs (so the stub knows where to jump). */
1815 bfd_vma target_value;
1816 asection *target_section;
1818 enum elf_aarch64_stub_type stub_type;
1820 /* The symbol table entry, if any, that this was derived from. */
1821 struct elf_aarch64_link_hash_entry *h;
1823 /* Destination symbol type */
1824 unsigned char st_type;
1826 /* Where this stub is being called from, or, in the case of combined
1827 stub sections, the first input section in the group. */
1830 /* The name for the local symbol at the start of this stub. The
1831 stub name in the hash table has to be unique; this does not, so
1832 it can be friendlier. */
1835 /* The instruction which caused this stub to be generated (only valid for
1836 erratum 835769 workaround stubs at present). */
1837 uint32_t veneered_insn;
1839 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
1840 bfd_vma adrp_offset;
1843 /* Used to build a map of a section. This is required for mixed-endian
1846 typedef struct elf_elf_section_map
1851 elf_aarch64_section_map;
1854 typedef struct _aarch64_elf_section_data
1856 struct bfd_elf_section_data elf;
1857 unsigned int mapcount;
1858 unsigned int mapsize;
1859 elf_aarch64_section_map *map;
1861 _aarch64_elf_section_data;
1863 #define elf_aarch64_section_data(sec) \
1864 ((_aarch64_elf_section_data *) elf_section_data (sec))
1866 /* The size of the thread control block which is defined to be two pointers. */
1867 #define TCB_SIZE (ARCH_SIZE/8)*2
1869 struct elf_aarch64_local_symbol
1871 unsigned int got_type;
1872 bfd_signed_vma got_refcount;
1875 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
1876 offset is from the end of the jump table and reserved entries
1879 The magic value (bfd_vma) -1 indicates that an offset has not be
1881 bfd_vma tlsdesc_got_jump_table_offset;
1884 struct elf_aarch64_obj_tdata
1886 struct elf_obj_tdata root;
1888 /* local symbol descriptors */
1889 struct elf_aarch64_local_symbol *locals;
1891 /* Zero to warn when linking objects with incompatible enum sizes. */
1892 int no_enum_size_warning;
1894 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
1895 int no_wchar_size_warning;
1898 #define elf_aarch64_tdata(bfd) \
1899 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
1901 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
1903 #define is_aarch64_elf(bfd) \
1904 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
1905 && elf_tdata (bfd) != NULL \
1906 && elf_object_id (bfd) == AARCH64_ELF_DATA)
1909 elfNN_aarch64_mkobject (bfd *abfd)
1911 return bfd_elf_allocate_object (abfd, sizeof (struct elf_aarch64_obj_tdata),
1915 #define elf_aarch64_hash_entry(ent) \
1916 ((struct elf_aarch64_link_hash_entry *)(ent))
1918 #define GOT_UNKNOWN 0
1919 #define GOT_NORMAL 1
1920 #define GOT_TLS_GD 2
1921 #define GOT_TLS_IE 4
1922 #define GOT_TLSDESC_GD 8
1924 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
1926 /* AArch64 ELF linker hash entry. */
1927 struct elf_aarch64_link_hash_entry
1929 struct elf_link_hash_entry root;
1931 /* Track dynamic relocs copied for this symbol. */
1932 struct elf_dyn_relocs *dyn_relocs;
1934 /* Since PLT entries have variable size, we need to record the
1935 index into .got.plt instead of recomputing it from the PLT
1937 bfd_signed_vma plt_got_offset;
1939 /* Bit mask representing the type of GOT entry(s) if any required by
1941 unsigned int got_type;
1943 /* A pointer to the most recently used stub hash entry against this
1945 struct elf_aarch64_stub_hash_entry *stub_cache;
1947 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
1948 is from the end of the jump table and reserved entries within the PLTGOT.
1950 The magic value (bfd_vma) -1 indicates that an offset has not
1952 bfd_vma tlsdesc_got_jump_table_offset;
1956 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry *h,
1958 unsigned long r_symndx)
1961 return elf_aarch64_hash_entry (h)->got_type;
1963 if (! elf_aarch64_locals (abfd))
1966 return elf_aarch64_locals (abfd)[r_symndx].got_type;
1969 /* Get the AArch64 elf linker hash table from a link_info structure. */
1970 #define elf_aarch64_hash_table(info) \
1971 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
1973 #define aarch64_stub_hash_lookup(table, string, create, copy) \
1974 ((struct elf_aarch64_stub_hash_entry *) \
1975 bfd_hash_lookup ((table), (string), (create), (copy)))
1977 /* AArch64 ELF linker hash table. */
1978 struct elf_aarch64_link_hash_table
1980 /* The main hash table. */
1981 struct elf_link_hash_table root;
1983 /* Nonzero to force PIC branch veneers. */
1986 /* Fix erratum 835769. */
1987 int fix_erratum_835769;
1989 /* Fix erratum 843419. */
1990 int fix_erratum_843419;
1992 /* Enable ADRP->ADR rewrite for erratum 843419 workaround. */
1993 int fix_erratum_843419_adr;
1995 /* The number of bytes in the initial entry in the PLT. */
1996 bfd_size_type plt_header_size;
1998 /* The number of bytes in the subsequent PLT etries. */
1999 bfd_size_type plt_entry_size;
2001 /* Short-cuts to get to dynamic linker sections. */
2005 /* Small local sym cache. */
2006 struct sym_cache sym_cache;
2008 /* For convenience in allocate_dynrelocs. */
2011 /* The amount of space used by the reserved portion of the sgotplt
2012 section, plus whatever space is used by the jump slots. */
2013 bfd_vma sgotplt_jump_table_size;
2015 /* The stub hash table. */
2016 struct bfd_hash_table stub_hash_table;
2018 /* Linker stub bfd. */
2021 /* Linker call-backs. */
2022 asection *(*add_stub_section) (const char *, asection *);
2023 void (*layout_sections_again) (void);
2025 /* Array to keep track of which stub sections have been created, and
2026 information on stub grouping. */
2029 /* This is the section to which stubs in the group will be
2032 /* The stub section. */
2036 /* Assorted information used by elfNN_aarch64_size_stubs. */
2037 unsigned int bfd_count;
2039 asection **input_list;
2041 /* The offset into splt of the PLT entry for the TLS descriptor
2042 resolver. Special values are 0, if not necessary (or not found
2043 to be necessary yet), and -1 if needed but not determined
2045 bfd_vma tlsdesc_plt;
2047 /* The GOT offset for the lazy trampoline. Communicated to the
2048 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
2049 indicates an offset is not allocated. */
2050 bfd_vma dt_tlsdesc_got;
2052 /* Used by local STT_GNU_IFUNC symbols. */
2053 htab_t loc_hash_table;
2054 void * loc_hash_memory;
2057 /* Create an entry in an AArch64 ELF linker hash table. */
2059 static struct bfd_hash_entry *
2060 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
2061 struct bfd_hash_table *table,
2064 struct elf_aarch64_link_hash_entry *ret =
2065 (struct elf_aarch64_link_hash_entry *) entry;
2067 /* Allocate the structure if it has not already been allocated by a
2070 ret = bfd_hash_allocate (table,
2071 sizeof (struct elf_aarch64_link_hash_entry));
2073 return (struct bfd_hash_entry *) ret;
2075 /* Call the allocation method of the superclass. */
2076 ret = ((struct elf_aarch64_link_hash_entry *)
2077 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2081 ret->dyn_relocs = NULL;
2082 ret->got_type = GOT_UNKNOWN;
2083 ret->plt_got_offset = (bfd_vma) - 1;
2084 ret->stub_cache = NULL;
2085 ret->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
2088 return (struct bfd_hash_entry *) ret;
2091 /* Initialize an entry in the stub hash table. */
2093 static struct bfd_hash_entry *
2094 stub_hash_newfunc (struct bfd_hash_entry *entry,
2095 struct bfd_hash_table *table, const char *string)
2097 /* Allocate the structure if it has not already been allocated by a
2101 entry = bfd_hash_allocate (table,
2103 elf_aarch64_stub_hash_entry));
2108 /* Call the allocation method of the superclass. */
2109 entry = bfd_hash_newfunc (entry, table, string);
2112 struct elf_aarch64_stub_hash_entry *eh;
2114 /* Initialize the local fields. */
2115 eh = (struct elf_aarch64_stub_hash_entry *) entry;
2116 eh->adrp_offset = 0;
2117 eh->stub_sec = NULL;
2118 eh->stub_offset = 0;
2119 eh->target_value = 0;
2120 eh->target_section = NULL;
2121 eh->stub_type = aarch64_stub_none;
2129 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
2130 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2131 as global symbol. We reuse indx and dynstr_index for local symbol
2132 hash since they aren't used by global symbols in this backend. */
2135 elfNN_aarch64_local_htab_hash (const void *ptr)
2137 struct elf_link_hash_entry *h
2138 = (struct elf_link_hash_entry *) ptr;
2139 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
2142 /* Compare local hash entries. */
2145 elfNN_aarch64_local_htab_eq (const void *ptr1, const void *ptr2)
2147 struct elf_link_hash_entry *h1
2148 = (struct elf_link_hash_entry *) ptr1;
2149 struct elf_link_hash_entry *h2
2150 = (struct elf_link_hash_entry *) ptr2;
2152 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
2155 /* Find and/or create a hash entry for local symbol. */
2157 static struct elf_link_hash_entry *
2158 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table *htab,
2159 bfd *abfd, const Elf_Internal_Rela *rel,
2162 struct elf_aarch64_link_hash_entry e, *ret;
2163 asection *sec = abfd->sections;
2164 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
2165 ELFNN_R_SYM (rel->r_info));
2168 e.root.indx = sec->id;
2169 e.root.dynstr_index = ELFNN_R_SYM (rel->r_info);
2170 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
2171 create ? INSERT : NO_INSERT);
2178 ret = (struct elf_aarch64_link_hash_entry *) *slot;
2182 ret = (struct elf_aarch64_link_hash_entry *)
2183 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
2184 sizeof (struct elf_aarch64_link_hash_entry));
2187 memset (ret, 0, sizeof (*ret));
2188 ret->root.indx = sec->id;
2189 ret->root.dynstr_index = ELFNN_R_SYM (rel->r_info);
2190 ret->root.dynindx = -1;
2196 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2199 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
2200 struct elf_link_hash_entry *dir,
2201 struct elf_link_hash_entry *ind)
2203 struct elf_aarch64_link_hash_entry *edir, *eind;
2205 edir = (struct elf_aarch64_link_hash_entry *) dir;
2206 eind = (struct elf_aarch64_link_hash_entry *) ind;
2208 if (eind->dyn_relocs != NULL)
2210 if (edir->dyn_relocs != NULL)
2212 struct elf_dyn_relocs **pp;
2213 struct elf_dyn_relocs *p;
2215 /* Add reloc counts against the indirect sym to the direct sym
2216 list. Merge any entries against the same section. */
2217 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
2219 struct elf_dyn_relocs *q;
2221 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2222 if (q->sec == p->sec)
2224 q->pc_count += p->pc_count;
2225 q->count += p->count;
2232 *pp = edir->dyn_relocs;
2235 edir->dyn_relocs = eind->dyn_relocs;
2236 eind->dyn_relocs = NULL;
2239 if (ind->root.type == bfd_link_hash_indirect)
2241 /* Copy over PLT info. */
2242 if (dir->got.refcount <= 0)
2244 edir->got_type = eind->got_type;
2245 eind->got_type = GOT_UNKNOWN;
2249 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2252 /* Destroy an AArch64 elf linker hash table. */
2255 elfNN_aarch64_link_hash_table_free (bfd *obfd)
2257 struct elf_aarch64_link_hash_table *ret
2258 = (struct elf_aarch64_link_hash_table *) obfd->link.hash;
2260 if (ret->loc_hash_table)
2261 htab_delete (ret->loc_hash_table);
2262 if (ret->loc_hash_memory)
2263 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
2265 bfd_hash_table_free (&ret->stub_hash_table);
2266 _bfd_elf_link_hash_table_free (obfd);
2269 /* Create an AArch64 elf linker hash table. */
2271 static struct bfd_link_hash_table *
2272 elfNN_aarch64_link_hash_table_create (bfd *abfd)
2274 struct elf_aarch64_link_hash_table *ret;
2275 bfd_size_type amt = sizeof (struct elf_aarch64_link_hash_table);
2277 ret = bfd_zmalloc (amt);
2281 if (!_bfd_elf_link_hash_table_init
2282 (&ret->root, abfd, elfNN_aarch64_link_hash_newfunc,
2283 sizeof (struct elf_aarch64_link_hash_entry), AARCH64_ELF_DATA))
2289 ret->plt_header_size = PLT_ENTRY_SIZE;
2290 ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
2292 ret->dt_tlsdesc_got = (bfd_vma) - 1;
2294 if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
2295 sizeof (struct elf_aarch64_stub_hash_entry)))
2297 _bfd_elf_link_hash_table_free (abfd);
2301 ret->loc_hash_table = htab_try_create (1024,
2302 elfNN_aarch64_local_htab_hash,
2303 elfNN_aarch64_local_htab_eq,
2305 ret->loc_hash_memory = objalloc_create ();
2306 if (!ret->loc_hash_table || !ret->loc_hash_memory)
2308 elfNN_aarch64_link_hash_table_free (abfd);
2311 ret->root.root.hash_table_free = elfNN_aarch64_link_hash_table_free;
2313 return &ret->root.root;
2317 aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
2318 bfd_vma offset, bfd_vma value)
2320 reloc_howto_type *howto;
2323 howto = elfNN_aarch64_howto_from_type (r_type);
2324 place = (input_section->output_section->vma + input_section->output_offset
2327 r_type = elfNN_aarch64_bfd_reloc_from_type (r_type);
2328 value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE);
2329 return _bfd_aarch64_elf_put_addend (input_bfd,
2330 input_section->contents + offset, r_type,
2334 static enum elf_aarch64_stub_type
2335 aarch64_select_branch_stub (bfd_vma value, bfd_vma place)
2337 if (aarch64_valid_for_adrp_p (value, place))
2338 return aarch64_stub_adrp_branch;
2339 return aarch64_stub_long_branch;
2342 /* Determine the type of stub needed, if any, for a call. */
2344 static enum elf_aarch64_stub_type
2345 aarch64_type_of_stub (struct bfd_link_info *info,
2346 asection *input_sec,
2347 const Elf_Internal_Rela *rel,
2349 unsigned char st_type,
2350 struct elf_aarch64_link_hash_entry *hash,
2351 bfd_vma destination)
2354 bfd_signed_vma branch_offset;
2355 unsigned int r_type;
2356 struct elf_aarch64_link_hash_table *globals;
2357 enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
2358 bfd_boolean via_plt_p;
2360 if (st_type != STT_FUNC
2361 && (sym_sec != bfd_abs_section_ptr))
2364 globals = elf_aarch64_hash_table (info);
2365 via_plt_p = (globals->root.splt != NULL && hash != NULL
2366 && hash->root.plt.offset != (bfd_vma) - 1);
2367 /* Make sure call to plt stub can fit into the branch range. */
2369 destination = (globals->root.splt->output_section->vma
2370 + globals->root.splt->output_offset
2371 + hash->root.plt.offset);
2373 /* Determine where the call point is. */
2374 location = (input_sec->output_offset
2375 + input_sec->output_section->vma + rel->r_offset);
2377 branch_offset = (bfd_signed_vma) (destination - location);
2379 r_type = ELFNN_R_TYPE (rel->r_info);
2381 /* We don't want to redirect any old unconditional jump in this way,
2382 only one which is being used for a sibcall, where it is
2383 acceptable for the IP0 and IP1 registers to be clobbered. */
2384 if ((r_type == AARCH64_R (CALL26) || r_type == AARCH64_R (JUMP26))
2385 && (branch_offset > AARCH64_MAX_FWD_BRANCH_OFFSET
2386 || branch_offset < AARCH64_MAX_BWD_BRANCH_OFFSET))
2388 stub_type = aarch64_stub_long_branch;
2394 /* Build a name for an entry in the stub hash table. */
2397 elfNN_aarch64_stub_name (const asection *input_section,
2398 const asection *sym_sec,
2399 const struct elf_aarch64_link_hash_entry *hash,
2400 const Elf_Internal_Rela *rel)
2407 len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
2408 stub_name = bfd_malloc (len);
2409 if (stub_name != NULL)
2410 snprintf (stub_name, len, "%08x_%s+%" BFD_VMA_FMT "x",
2411 (unsigned int) input_section->id,
2412 hash->root.root.root.string,
2417 len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2418 stub_name = bfd_malloc (len);
2419 if (stub_name != NULL)
2420 snprintf (stub_name, len, "%08x_%x:%x+%" BFD_VMA_FMT "x",
2421 (unsigned int) input_section->id,
2422 (unsigned int) sym_sec->id,
2423 (unsigned int) ELFNN_R_SYM (rel->r_info),
2430 /* Look up an entry in the stub hash. Stub entries are cached because
2431 creating the stub name takes a bit of time. */
2433 static struct elf_aarch64_stub_hash_entry *
2434 elfNN_aarch64_get_stub_entry (const asection *input_section,
2435 const asection *sym_sec,
2436 struct elf_link_hash_entry *hash,
2437 const Elf_Internal_Rela *rel,
2438 struct elf_aarch64_link_hash_table *htab)
2440 struct elf_aarch64_stub_hash_entry *stub_entry;
2441 struct elf_aarch64_link_hash_entry *h =
2442 (struct elf_aarch64_link_hash_entry *) hash;
2443 const asection *id_sec;
2445 if ((input_section->flags & SEC_CODE) == 0)
2448 /* If this input section is part of a group of sections sharing one
2449 stub section, then use the id of the first section in the group.
2450 Stub names need to include a section id, as there may well be
2451 more than one stub used to reach say, printf, and we need to
2452 distinguish between them. */
2453 id_sec = htab->stub_group[input_section->id].link_sec;
2455 if (h != NULL && h->stub_cache != NULL
2456 && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
2458 stub_entry = h->stub_cache;
2464 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, h, rel);
2465 if (stub_name == NULL)
2468 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
2469 stub_name, FALSE, FALSE);
2471 h->stub_cache = stub_entry;
2480 /* Create a stub section. */
2483 _bfd_aarch64_create_stub_section (asection *section,
2484 struct elf_aarch64_link_hash_table *htab)
2490 namelen = strlen (section->name);
2491 len = namelen + sizeof (STUB_SUFFIX);
2492 s_name = bfd_alloc (htab->stub_bfd, len);
2496 memcpy (s_name, section->name, namelen);
2497 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
2498 return (*htab->add_stub_section) (s_name, section);
2502 /* Find or create a stub section for a link section.
2504 Fix or create the stub section used to collect stubs attached to
2505 the specified link section. */
2508 _bfd_aarch64_get_stub_for_link_section (asection *link_section,
2509 struct elf_aarch64_link_hash_table *htab)
2511 if (htab->stub_group[link_section->id].stub_sec == NULL)
2512 htab->stub_group[link_section->id].stub_sec
2513 = _bfd_aarch64_create_stub_section (link_section, htab);
2514 return htab->stub_group[link_section->id].stub_sec;
2518 /* Find or create a stub section in the stub group for an input
2522 _bfd_aarch64_create_or_find_stub_sec (asection *section,
2523 struct elf_aarch64_link_hash_table *htab)
2525 asection *link_sec = htab->stub_group[section->id].link_sec;
2526 return _bfd_aarch64_get_stub_for_link_section (link_sec, htab);
2530 /* Add a new stub entry in the stub group associated with an input
2531 section to the stub hash. Not all fields of the new stub entry are
2534 static struct elf_aarch64_stub_hash_entry *
2535 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name,
2537 struct elf_aarch64_link_hash_table *htab)
2541 struct elf_aarch64_stub_hash_entry *stub_entry;
2543 link_sec = htab->stub_group[section->id].link_sec;
2544 stub_sec = _bfd_aarch64_create_or_find_stub_sec (section, htab);
2546 /* Enter this entry into the linker stub hash table. */
2547 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
2549 if (stub_entry == NULL)
2551 (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
2552 section->owner, stub_name);
2556 stub_entry->stub_sec = stub_sec;
2557 stub_entry->stub_offset = 0;
2558 stub_entry->id_sec = link_sec;
2563 /* Add a new stub entry in the final stub section to the stub hash.
2564 Not all fields of the new stub entry are initialised. */
2566 static struct elf_aarch64_stub_hash_entry *
2567 _bfd_aarch64_add_stub_entry_after (const char *stub_name,
2568 asection *link_section,
2569 struct elf_aarch64_link_hash_table *htab)
2572 struct elf_aarch64_stub_hash_entry *stub_entry;
2574 stub_sec = _bfd_aarch64_get_stub_for_link_section (link_section, htab);
2575 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
2577 if (stub_entry == NULL)
2579 (*_bfd_error_handler) (_("cannot create stub entry %s"), stub_name);
2583 stub_entry->stub_sec = stub_sec;
2584 stub_entry->stub_offset = 0;
2585 stub_entry->id_sec = link_section;
2592 aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
2593 void *in_arg ATTRIBUTE_UNUSED)
2595 struct elf_aarch64_stub_hash_entry *stub_entry;
2600 bfd_vma veneered_insn_loc;
2601 bfd_vma veneer_entry_loc;
2602 bfd_signed_vma branch_offset = 0;
2603 unsigned int template_size;
2604 const uint32_t *template;
2607 /* Massage our args to the form they really have. */
2608 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
2610 stub_sec = stub_entry->stub_sec;
2612 /* Make a note of the offset within the stubs for this entry. */
2613 stub_entry->stub_offset = stub_sec->size;
2614 loc = stub_sec->contents + stub_entry->stub_offset;
2616 stub_bfd = stub_sec->owner;
2618 /* This is the address of the stub destination. */
2619 sym_value = (stub_entry->target_value
2620 + stub_entry->target_section->output_offset
2621 + stub_entry->target_section->output_section->vma);
2623 if (stub_entry->stub_type == aarch64_stub_long_branch)
2625 bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
2626 + stub_sec->output_offset);
2628 /* See if we can relax the stub. */
2629 if (aarch64_valid_for_adrp_p (sym_value, place))
2630 stub_entry->stub_type = aarch64_select_branch_stub (sym_value, place);
2633 switch (stub_entry->stub_type)
2635 case aarch64_stub_adrp_branch:
2636 template = aarch64_adrp_branch_stub;
2637 template_size = sizeof (aarch64_adrp_branch_stub);
2639 case aarch64_stub_long_branch:
2640 template = aarch64_long_branch_stub;
2641 template_size = sizeof (aarch64_long_branch_stub);
2643 case aarch64_stub_erratum_835769_veneer:
2644 template = aarch64_erratum_835769_stub;
2645 template_size = sizeof (aarch64_erratum_835769_stub);
2647 case aarch64_stub_erratum_843419_veneer:
2648 template = aarch64_erratum_843419_stub;
2649 template_size = sizeof (aarch64_erratum_843419_stub);
2655 for (i = 0; i < (template_size / sizeof template[0]); i++)
2657 bfd_putl32 (template[i], loc);
2661 template_size = (template_size + 7) & ~7;
2662 stub_sec->size += template_size;
2664 switch (stub_entry->stub_type)
2666 case aarch64_stub_adrp_branch:
2667 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
2668 stub_entry->stub_offset, sym_value))
2669 /* The stub would not have been relaxed if the offset was out
2673 if (aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC), stub_bfd, stub_sec,
2674 stub_entry->stub_offset + 4, sym_value))
2678 case aarch64_stub_long_branch:
2679 /* We want the value relative to the address 12 bytes back from the
2681 if (aarch64_relocate (AARCH64_R (PRELNN), stub_bfd, stub_sec,
2682 stub_entry->stub_offset + 16, sym_value + 12))
2686 case aarch64_stub_erratum_835769_veneer:
2687 veneered_insn_loc = stub_entry->target_section->output_section->vma
2688 + stub_entry->target_section->output_offset
2689 + stub_entry->target_value;
2690 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
2691 + stub_entry->stub_sec->output_offset
2692 + stub_entry->stub_offset;
2693 branch_offset = veneered_insn_loc - veneer_entry_loc;
2694 branch_offset >>= 2;
2695 branch_offset &= 0x3ffffff;
2696 bfd_putl32 (stub_entry->veneered_insn,
2697 stub_sec->contents + stub_entry->stub_offset);
2698 bfd_putl32 (template[1] | branch_offset,
2699 stub_sec->contents + stub_entry->stub_offset + 4);
2702 case aarch64_stub_erratum_843419_veneer:
2703 if (aarch64_relocate (AARCH64_R (JUMP26), stub_bfd, stub_sec,
2704 stub_entry->stub_offset + 4, sym_value + 4))
2715 /* As above, but don't actually build the stub. Just bump offset so
2716 we know stub section sizes. */
2719 aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
2720 void *in_arg ATTRIBUTE_UNUSED)
2722 struct elf_aarch64_stub_hash_entry *stub_entry;
2725 /* Massage our args to the form they really have. */
2726 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
2728 switch (stub_entry->stub_type)
2730 case aarch64_stub_adrp_branch:
2731 size = sizeof (aarch64_adrp_branch_stub);
2733 case aarch64_stub_long_branch:
2734 size = sizeof (aarch64_long_branch_stub);
2736 case aarch64_stub_erratum_835769_veneer:
2737 size = sizeof (aarch64_erratum_835769_stub);
2739 case aarch64_stub_erratum_843419_veneer:
2740 size = sizeof (aarch64_erratum_843419_stub);
2746 size = (size + 7) & ~7;
2747 stub_entry->stub_sec->size += size;
2751 /* External entry points for sizing and building linker stubs. */
2753 /* Set up various things so that we can make a list of input sections
2754 for each output section included in the link. Returns -1 on error,
2755 0 when no stubs will be needed, and 1 on success. */
2758 elfNN_aarch64_setup_section_lists (bfd *output_bfd,
2759 struct bfd_link_info *info)
2762 unsigned int bfd_count;
2763 int top_id, top_index;
2765 asection **input_list, **list;
2767 struct elf_aarch64_link_hash_table *htab =
2768 elf_aarch64_hash_table (info);
2770 if (!is_elf_hash_table (htab))
2773 /* Count the number of input BFDs and find the top input section id. */
2774 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
2775 input_bfd != NULL; input_bfd = input_bfd->link.next)
2778 for (section = input_bfd->sections;
2779 section != NULL; section = section->next)
2781 if (top_id < section->id)
2782 top_id = section->id;
2785 htab->bfd_count = bfd_count;
2787 amt = sizeof (struct map_stub) * (top_id + 1);
2788 htab->stub_group = bfd_zmalloc (amt);
2789 if (htab->stub_group == NULL)
2792 /* We can't use output_bfd->section_count here to find the top output
2793 section index as some sections may have been removed, and
2794 _bfd_strip_section_from_output doesn't renumber the indices. */
2795 for (section = output_bfd->sections, top_index = 0;
2796 section != NULL; section = section->next)
2798 if (top_index < section->index)
2799 top_index = section->index;
2802 htab->top_index = top_index;
2803 amt = sizeof (asection *) * (top_index + 1);
2804 input_list = bfd_malloc (amt);
2805 htab->input_list = input_list;
2806 if (input_list == NULL)
2809 /* For sections we aren't interested in, mark their entries with a
2810 value we can check later. */
2811 list = input_list + top_index;
2813 *list = bfd_abs_section_ptr;
2814 while (list-- != input_list);
2816 for (section = output_bfd->sections;
2817 section != NULL; section = section->next)
2819 if ((section->flags & SEC_CODE) != 0)
2820 input_list[section->index] = NULL;
2826 /* Used by elfNN_aarch64_next_input_section and group_sections. */
2827 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
2829 /* The linker repeatedly calls this function for each input section,
2830 in the order that input sections are linked into output sections.
2831 Build lists of input sections to determine groupings between which
2832 we may insert linker stubs. */
2835 elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec)
2837 struct elf_aarch64_link_hash_table *htab =
2838 elf_aarch64_hash_table (info);
2840 if (isec->output_section->index <= htab->top_index)
2842 asection **list = htab->input_list + isec->output_section->index;
2844 if (*list != bfd_abs_section_ptr)
2846 /* Steal the link_sec pointer for our list. */
2847 /* This happens to make the list in reverse order,
2848 which is what we want. */
2849 PREV_SEC (isec) = *list;
2855 /* See whether we can group stub sections together. Grouping stub
2856 sections may result in fewer stubs. More importantly, we need to
2857 put all .init* and .fini* stubs at the beginning of the .init or
2858 .fini output sections respectively, because glibc splits the
2859 _init and _fini functions into multiple parts. Putting a stub in
2860 the middle of a function is not a good idea. */
2863 group_sections (struct elf_aarch64_link_hash_table *htab,
2864 bfd_size_type stub_group_size,
2865 bfd_boolean stubs_always_before_branch)
2867 asection **list = htab->input_list + htab->top_index;
2871 asection *tail = *list;
2873 if (tail == bfd_abs_section_ptr)
2876 while (tail != NULL)
2880 bfd_size_type total;
2884 while ((prev = PREV_SEC (curr)) != NULL
2885 && ((total += curr->output_offset - prev->output_offset)
2889 /* OK, the size from the start of CURR to the end is less
2890 than stub_group_size and thus can be handled by one stub
2891 section. (Or the tail section is itself larger than
2892 stub_group_size, in which case we may be toast.)
2893 We should really be keeping track of the total size of
2894 stubs added here, as stubs contribute to the final output
2898 prev = PREV_SEC (tail);
2899 /* Set up this stub group. */
2900 htab->stub_group[tail->id].link_sec = curr;
2902 while (tail != curr && (tail = prev) != NULL);
2904 /* But wait, there's more! Input sections up to stub_group_size
2905 bytes before the stub section can be handled by it too. */
2906 if (!stubs_always_before_branch)
2910 && ((total += tail->output_offset - prev->output_offset)
2914 prev = PREV_SEC (tail);
2915 htab->stub_group[tail->id].link_sec = curr;
2921 while (list-- != htab->input_list);
2923 free (htab->input_list);
2928 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
2930 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
2931 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
2932 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
2933 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
2934 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
2935 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
2937 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
2938 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
2939 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
2940 #define AARCH64_ZR 0x1f
2942 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
2943 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
2945 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
2946 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
2947 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
2948 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
2949 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
2950 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
2951 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
2952 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
2953 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
2954 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
2955 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
2956 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
2957 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
2958 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
2959 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
2960 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
2961 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
2962 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
2964 /* Classify an INSN if it is indeed a load/store.
2966 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
2968 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
2971 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned.
2976 aarch64_mem_op_p (uint32_t insn, unsigned int *rt, unsigned int *rt2,
2977 bfd_boolean *pair, bfd_boolean *load)
2985 /* Bail out quickly if INSN doesn't fall into the the load-store
2987 if (!AARCH64_LDST (insn))
2992 if (AARCH64_LDST_EX (insn))
2994 *rt = AARCH64_RT (insn);
2996 if (AARCH64_BIT (insn, 21) == 1)
2999 *rt2 = AARCH64_RT2 (insn);
3001 *load = AARCH64_LD (insn);
3004 else if (AARCH64_LDST_NAP (insn)
3005 || AARCH64_LDSTP_PI (insn)
3006 || AARCH64_LDSTP_O (insn)
3007 || AARCH64_LDSTP_PRE (insn))
3010 *rt = AARCH64_RT (insn);
3011 *rt2 = AARCH64_RT2 (insn);
3012 *load = AARCH64_LD (insn);
3015 else if (AARCH64_LDST_PCREL (insn)
3016 || AARCH64_LDST_UI (insn)
3017 || AARCH64_LDST_PIIMM (insn)
3018 || AARCH64_LDST_U (insn)
3019 || AARCH64_LDST_PREIMM (insn)
3020 || AARCH64_LDST_RO (insn)
3021 || AARCH64_LDST_UIMM (insn))
3023 *rt = AARCH64_RT (insn);
3025 if (AARCH64_LDST_PCREL (insn))
3027 opc = AARCH64_BITS (insn, 22, 2);
3028 v = AARCH64_BIT (insn, 26);
3029 opc_v = opc | (v << 2);
3030 *load = (opc_v == 1 || opc_v == 2 || opc_v == 3
3031 || opc_v == 5 || opc_v == 7);
3034 else if (AARCH64_LDST_SIMD_M (insn)
3035 || AARCH64_LDST_SIMD_M_PI (insn))
3037 *rt = AARCH64_RT (insn);
3038 *load = AARCH64_BIT (insn, 22);
3039 opcode = (insn >> 12) & 0xf;
3066 else if (AARCH64_LDST_SIMD_S (insn)
3067 || AARCH64_LDST_SIMD_S_PI (insn))
3069 *rt = AARCH64_RT (insn);
3070 r = (insn >> 21) & 1;
3071 *load = AARCH64_BIT (insn, 22);
3072 opcode = (insn >> 13) & 0x7;
3084 *rt2 = *rt + (r == 0 ? 2 : 3);
3092 *rt2 = *rt + (r == 0 ? 2 : 3);
3104 /* Return TRUE if INSN is multiply-accumulate. */
3107 aarch64_mlxl_p (uint32_t insn)
3109 uint32_t op31 = AARCH64_OP31 (insn);
3111 if (AARCH64_MAC (insn)
3112 && (op31 == 0 || op31 == 1 || op31 == 5)
3113 /* Exclude MUL instructions which are encoded as a multiple accumulate
3115 && AARCH64_RA (insn) != AARCH64_ZR)
3121 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3122 it is possible for a 64-bit multiply-accumulate instruction to generate an
3123 incorrect result. The details are quite complex and hard to
3124 determine statically, since branches in the code may exist in some
3125 circumstances, but all cases end with a memory (load, store, or
3126 prefetch) instruction followed immediately by the multiply-accumulate
3127 operation. We employ a linker patching technique, by moving the potentially
3128 affected multiply-accumulate instruction into a patch region and replacing
3129 the original instruction with a branch to the patch. This function checks
3130 if INSN_1 is the memory operation followed by a multiply-accumulate
3131 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3132 if INSN_1 and INSN_2 are safe. */
3135 aarch64_erratum_sequence (uint32_t insn_1, uint32_t insn_2)
3145 if (aarch64_mlxl_p (insn_2)
3146 && aarch64_mem_op_p (insn_1, &rt, &rt2, &pair, &load))
3148 /* Any SIMD memory op is independent of the subsequent MLA
3149 by definition of the erratum. */
3150 if (AARCH64_BIT (insn_1, 26))
3153 /* If not SIMD, check for integer memory ops and MLA relationship. */
3154 rn = AARCH64_RN (insn_2);
3155 ra = AARCH64_RA (insn_2);
3156 rm = AARCH64_RM (insn_2);
3158 /* If this is a load and there's a true(RAW) dependency, we are safe
3159 and this is not an erratum sequence. */
3161 (rt == rn || rt == rm || rt == ra
3162 || (pair && (rt2 == rn || rt2 == rm || rt2 == ra))))
3165 /* We conservatively put out stubs for all other cases (including
3173 /* Used to order a list of mapping symbols by address. */
3176 elf_aarch64_compare_mapping (const void *a, const void *b)
3178 const elf_aarch64_section_map *amap = (const elf_aarch64_section_map *) a;
3179 const elf_aarch64_section_map *bmap = (const elf_aarch64_section_map *) b;
3181 if (amap->vma > bmap->vma)
3183 else if (amap->vma < bmap->vma)
3185 else if (amap->type > bmap->type)
3186 /* Ensure results do not depend on the host qsort for objects with
3187 multiple mapping symbols at the same address by sorting on type
3190 else if (amap->type < bmap->type)
3198 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes)
3200 char *stub_name = (char *) bfd_malloc
3201 (strlen ("__erratum_835769_veneer_") + 16);
3202 sprintf (stub_name,"__erratum_835769_veneer_%d", num_fixes);
3206 /* Scan for Cortex-A53 erratum 835769 sequence.
3208 Return TRUE else FALSE on abnormal termination. */
3211 _bfd_aarch64_erratum_835769_scan (bfd *input_bfd,
3212 struct bfd_link_info *info,
3213 unsigned int *num_fixes_p)
3216 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
3217 unsigned int num_fixes = *num_fixes_p;
3222 for (section = input_bfd->sections;
3224 section = section->next)
3226 bfd_byte *contents = NULL;
3227 struct _aarch64_elf_section_data *sec_data;
3230 if (elf_section_type (section) != SHT_PROGBITS
3231 || (elf_section_flags (section) & SHF_EXECINSTR) == 0
3232 || (section->flags & SEC_EXCLUDE) != 0
3233 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
3234 || (section->output_section == bfd_abs_section_ptr))
3237 if (elf_section_data (section)->this_hdr.contents != NULL)
3238 contents = elf_section_data (section)->this_hdr.contents;
3239 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
3242 sec_data = elf_aarch64_section_data (section);
3244 qsort (sec_data->map, sec_data->mapcount,
3245 sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
3247 for (span = 0; span < sec_data->mapcount; span++)
3249 unsigned int span_start = sec_data->map[span].vma;
3250 unsigned int span_end = ((span == sec_data->mapcount - 1)
3251 ? sec_data->map[0].vma + section->size
3252 : sec_data->map[span + 1].vma);
3254 char span_type = sec_data->map[span].type;
3256 if (span_type == 'd')
3259 for (i = span_start; i + 4 < span_end; i += 4)
3261 uint32_t insn_1 = bfd_getl32 (contents + i);
3262 uint32_t insn_2 = bfd_getl32 (contents + i + 4);
3264 if (aarch64_erratum_sequence (insn_1, insn_2))
3266 struct elf_aarch64_stub_hash_entry *stub_entry;
3267 char *stub_name = _bfd_aarch64_erratum_835769_stub_name (num_fixes);
3271 stub_entry = _bfd_aarch64_add_stub_entry_in_group (stub_name,
3277 stub_entry->stub_type = aarch64_stub_erratum_835769_veneer;
3278 stub_entry->target_section = section;
3279 stub_entry->target_value = i + 4;
3280 stub_entry->veneered_insn = insn_2;
3281 stub_entry->output_name = stub_name;
3286 if (elf_section_data (section)->this_hdr.contents == NULL)
3290 *num_fixes_p = num_fixes;
3296 /* Test if instruction INSN is ADRP. */
3299 _bfd_aarch64_adrp_p (uint32_t insn)
3301 return ((insn & 0x9f000000) == 0x90000000);
3305 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
3308 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1, uint32_t insn_2,
3316 return (aarch64_mem_op_p (insn_2, &rt, &rt2, &pair, &load)
3319 && AARCH64_LDST_UIMM (insn_3)
3320 && AARCH64_RN (insn_3) == AARCH64_RD (insn_1));
3324 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
3326 Return TRUE if section CONTENTS at offset I contains one of the
3327 erratum 843419 sequences, otherwise return FALSE. If a sequence is
3328 seen set P_VENEER_I to the offset of the final LOAD/STORE
3329 instruction in the sequence.
3333 _bfd_aarch64_erratum_843419_p (bfd_byte *contents, bfd_vma vma,
3334 bfd_vma i, bfd_vma span_end,
3335 bfd_vma *p_veneer_i)
3337 uint32_t insn_1 = bfd_getl32 (contents + i);
3339 if (!_bfd_aarch64_adrp_p (insn_1))
3342 if (span_end < i + 12)
3345 uint32_t insn_2 = bfd_getl32 (contents + i + 4);
3346 uint32_t insn_3 = bfd_getl32 (contents + i + 8);
3348 if ((vma & 0xfff) != 0xff8 && (vma & 0xfff) != 0xffc)
3351 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1, insn_2, insn_3))
3353 *p_veneer_i = i + 8;
3357 if (span_end < i + 16)
3360 uint32_t insn_4 = bfd_getl32 (contents + i + 12);
3362 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1, insn_2, insn_4))
3364 *p_veneer_i = i + 12;
3372 /* Resize all stub sections. */
3375 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table *htab)
3379 /* OK, we've added some stubs. Find out the new size of the
3381 for (section = htab->stub_bfd->sections;
3382 section != NULL; section = section->next)
3384 /* Ignore non-stub sections. */
3385 if (!strstr (section->name, STUB_SUFFIX))
3390 bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
3392 for (section = htab->stub_bfd->sections;
3393 section != NULL; section = section->next)
3395 if (!strstr (section->name, STUB_SUFFIX))
3401 /* Ensure all stub sections have a size which is a multiple of
3402 4096. This is important in order to ensure that the insertion
3403 of stub sections does not in itself move existing code around
3404 in such a way that new errata sequences are created. */
3405 if (htab->fix_erratum_843419)
3407 section->size = BFD_ALIGN (section->size, 0x1000);
3412 /* Construct an erratum 843419 workaround stub name.
3416 _bfd_aarch64_erratum_843419_stub_name (asection *input_section,
3419 const bfd_size_type len = 8 + 4 + 1 + 8 + 1 + 16 + 1;
3420 char *stub_name = bfd_malloc (len);
3422 if (stub_name != NULL)
3423 snprintf (stub_name, len, "e843419@%04x_%08x_%" BFD_VMA_FMT "x",
3424 input_section->owner->id,
3430 /* Build a stub_entry structure describing an 843419 fixup.
3432 The stub_entry constructed is populated with the bit pattern INSN
3433 of the instruction located at OFFSET within input SECTION.
3435 Returns TRUE on success. */
3438 _bfd_aarch64_erratum_843419_fixup (uint32_t insn,
3439 bfd_vma adrp_offset,
3440 bfd_vma ldst_offset,
3442 struct bfd_link_info *info)
3444 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
3446 struct elf_aarch64_stub_hash_entry *stub_entry;
3448 stub_name = _bfd_aarch64_erratum_843419_stub_name (section, ldst_offset);
3449 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3457 /* We always place an 843419 workaround veneer in the stub section
3458 attached to the input section in which an erratum sequence has
3459 been found. This ensures that later in the link process (in
3460 elfNN_aarch64_write_section) when we copy the veneered
3461 instruction from the input section into the stub section the
3462 copied instruction will have had any relocations applied to it.
3463 If we placed workaround veneers in any other stub section then we
3464 could not assume that all relocations have been processed on the
3465 corresponding input section at the point we output the stub
3469 stub_entry = _bfd_aarch64_add_stub_entry_after (stub_name, section, htab);
3470 if (stub_entry == NULL)
3476 stub_entry->adrp_offset = adrp_offset;
3477 stub_entry->target_value = ldst_offset;
3478 stub_entry->target_section = section;
3479 stub_entry->stub_type = aarch64_stub_erratum_843419_veneer;
3480 stub_entry->veneered_insn = insn;
3481 stub_entry->output_name = stub_name;
3487 /* Scan an input section looking for the signature of erratum 843419.
3489 Scans input SECTION in INPUT_BFD looking for erratum 843419
3490 signatures, for each signature found a stub_entry is created
3491 describing the location of the erratum for subsequent fixup.
3493 Return TRUE on successful scan, FALSE on failure to scan.
3497 _bfd_aarch64_erratum_843419_scan (bfd *input_bfd, asection *section,
3498 struct bfd_link_info *info)
3500 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
3505 if (elf_section_type (section) != SHT_PROGBITS
3506 || (elf_section_flags (section) & SHF_EXECINSTR) == 0
3507 || (section->flags & SEC_EXCLUDE) != 0
3508 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
3509 || (section->output_section == bfd_abs_section_ptr))
3514 bfd_byte *contents = NULL;
3515 struct _aarch64_elf_section_data *sec_data;
3518 if (elf_section_data (section)->this_hdr.contents != NULL)
3519 contents = elf_section_data (section)->this_hdr.contents;
3520 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
3523 sec_data = elf_aarch64_section_data (section);
3525 qsort (sec_data->map, sec_data->mapcount,
3526 sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
3528 for (span = 0; span < sec_data->mapcount; span++)
3530 unsigned int span_start = sec_data->map[span].vma;
3531 unsigned int span_end = ((span == sec_data->mapcount - 1)
3532 ? sec_data->map[0].vma + section->size
3533 : sec_data->map[span + 1].vma);
3535 char span_type = sec_data->map[span].type;
3537 if (span_type == 'd')
3540 for (i = span_start; i + 8 < span_end; i += 4)
3542 bfd_vma vma = (section->output_section->vma
3543 + section->output_offset
3547 if (_bfd_aarch64_erratum_843419_p
3548 (contents, vma, i, span_end, &veneer_i))
3550 uint32_t insn = bfd_getl32 (contents + veneer_i);
3552 if (!_bfd_aarch64_erratum_843419_fixup (insn, i, veneer_i,
3559 if (elf_section_data (section)->this_hdr.contents == NULL)
3568 /* Determine and set the size of the stub section for a final link.
3570 The basic idea here is to examine all the relocations looking for
3571 PC-relative calls to a target that is unreachable with a "bl"
3575 elfNN_aarch64_size_stubs (bfd *output_bfd,
3577 struct bfd_link_info *info,
3578 bfd_signed_vma group_size,
3579 asection * (*add_stub_section) (const char *,
3581 void (*layout_sections_again) (void))
3583 bfd_size_type stub_group_size;
3584 bfd_boolean stubs_always_before_branch;
3585 bfd_boolean stub_changed = FALSE;
3586 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
3587 unsigned int num_erratum_835769_fixes = 0;
3589 /* Propagate mach to stub bfd, because it may not have been
3590 finalized when we created stub_bfd. */
3591 bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
3592 bfd_get_mach (output_bfd));
3594 /* Stash our params away. */
3595 htab->stub_bfd = stub_bfd;
3596 htab->add_stub_section = add_stub_section;
3597 htab->layout_sections_again = layout_sections_again;
3598 stubs_always_before_branch = group_size < 0;
3600 stub_group_size = -group_size;
3602 stub_group_size = group_size;
3604 if (stub_group_size == 1)
3606 /* Default values. */
3607 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
3608 stub_group_size = 127 * 1024 * 1024;
3611 group_sections (htab, stub_group_size, stubs_always_before_branch);
3613 (*htab->layout_sections_again) ();
3615 if (htab->fix_erratum_835769)
3619 for (input_bfd = info->input_bfds;
3620 input_bfd != NULL; input_bfd = input_bfd->link.next)
3621 if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info,
3622 &num_erratum_835769_fixes))
3625 _bfd_aarch64_resize_stubs (htab);
3626 (*htab->layout_sections_again) ();
3629 if (htab->fix_erratum_843419)
3633 for (input_bfd = info->input_bfds;
3635 input_bfd = input_bfd->link.next)
3639 for (section = input_bfd->sections;
3641 section = section->next)
3642 if (!_bfd_aarch64_erratum_843419_scan (input_bfd, section, info))
3646 _bfd_aarch64_resize_stubs (htab);
3647 (*htab->layout_sections_again) ();
3654 for (input_bfd = info->input_bfds;
3655 input_bfd != NULL; input_bfd = input_bfd->link.next)
3657 Elf_Internal_Shdr *symtab_hdr;
3659 Elf_Internal_Sym *local_syms = NULL;
3661 /* We'll need the symbol table in a second. */
3662 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3663 if (symtab_hdr->sh_info == 0)
3666 /* Walk over each section attached to the input bfd. */
3667 for (section = input_bfd->sections;
3668 section != NULL; section = section->next)
3670 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
3672 /* If there aren't any relocs, then there's nothing more
3674 if ((section->flags & SEC_RELOC) == 0
3675 || section->reloc_count == 0
3676 || (section->flags & SEC_CODE) == 0)
3679 /* If this section is a link-once section that will be
3680 discarded, then don't create any stubs. */
3681 if (section->output_section == NULL
3682 || section->output_section->owner != output_bfd)
3685 /* Get the relocs. */
3687 = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
3688 NULL, info->keep_memory);
3689 if (internal_relocs == NULL)
3690 goto error_ret_free_local;
3692 /* Now examine each relocation. */
3693 irela = internal_relocs;
3694 irelaend = irela + section->reloc_count;
3695 for (; irela < irelaend; irela++)
3697 unsigned int r_type, r_indx;
3698 enum elf_aarch64_stub_type stub_type;
3699 struct elf_aarch64_stub_hash_entry *stub_entry;
3702 bfd_vma destination;
3703 struct elf_aarch64_link_hash_entry *hash;
3704 const char *sym_name;
3706 const asection *id_sec;
3707 unsigned char st_type;
3710 r_type = ELFNN_R_TYPE (irela->r_info);
3711 r_indx = ELFNN_R_SYM (irela->r_info);
3713 if (r_type >= (unsigned int) R_AARCH64_end)
3715 bfd_set_error (bfd_error_bad_value);
3716 error_ret_free_internal:
3717 if (elf_section_data (section)->relocs == NULL)
3718 free (internal_relocs);
3719 goto error_ret_free_local;
3722 /* Only look for stubs on unconditional branch and
3723 branch and link instructions. */
3724 if (r_type != (unsigned int) AARCH64_R (CALL26)
3725 && r_type != (unsigned int) AARCH64_R (JUMP26))
3728 /* Now determine the call target, its name, value,
3735 if (r_indx < symtab_hdr->sh_info)
3737 /* It's a local symbol. */
3738 Elf_Internal_Sym *sym;
3739 Elf_Internal_Shdr *hdr;
3741 if (local_syms == NULL)
3744 = (Elf_Internal_Sym *) symtab_hdr->contents;
3745 if (local_syms == NULL)
3747 = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
3748 symtab_hdr->sh_info, 0,
3750 if (local_syms == NULL)
3751 goto error_ret_free_internal;
3754 sym = local_syms + r_indx;
3755 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
3756 sym_sec = hdr->bfd_section;
3758 /* This is an undefined symbol. It can never
3762 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
3763 sym_value = sym->st_value;
3764 destination = (sym_value + irela->r_addend
3765 + sym_sec->output_offset
3766 + sym_sec->output_section->vma);
3767 st_type = ELF_ST_TYPE (sym->st_info);
3769 = bfd_elf_string_from_elf_section (input_bfd,
3770 symtab_hdr->sh_link,
3777 e_indx = r_indx - symtab_hdr->sh_info;
3778 hash = ((struct elf_aarch64_link_hash_entry *)
3779 elf_sym_hashes (input_bfd)[e_indx]);
3781 while (hash->root.root.type == bfd_link_hash_indirect
3782 || hash->root.root.type == bfd_link_hash_warning)
3783 hash = ((struct elf_aarch64_link_hash_entry *)
3784 hash->root.root.u.i.link);
3786 if (hash->root.root.type == bfd_link_hash_defined
3787 || hash->root.root.type == bfd_link_hash_defweak)
3789 struct elf_aarch64_link_hash_table *globals =
3790 elf_aarch64_hash_table (info);
3791 sym_sec = hash->root.root.u.def.section;
3792 sym_value = hash->root.root.u.def.value;
3793 /* For a destination in a shared library,
3794 use the PLT stub as target address to
3795 decide whether a branch stub is
3797 if (globals->root.splt != NULL && hash != NULL
3798 && hash->root.plt.offset != (bfd_vma) - 1)
3800 sym_sec = globals->root.splt;
3801 sym_value = hash->root.plt.offset;
3802 if (sym_sec->output_section != NULL)
3803 destination = (sym_value
3804 + sym_sec->output_offset
3806 sym_sec->output_section->vma);
3808 else if (sym_sec->output_section != NULL)
3809 destination = (sym_value + irela->r_addend
3810 + sym_sec->output_offset
3811 + sym_sec->output_section->vma);
3813 else if (hash->root.root.type == bfd_link_hash_undefined
3814 || (hash->root.root.type
3815 == bfd_link_hash_undefweak))
3817 /* For a shared library, use the PLT stub as
3818 target address to decide whether a long
3819 branch stub is needed.
3820 For absolute code, they cannot be handled. */
3821 struct elf_aarch64_link_hash_table *globals =
3822 elf_aarch64_hash_table (info);
3824 if (globals->root.splt != NULL && hash != NULL
3825 && hash->root.plt.offset != (bfd_vma) - 1)
3827 sym_sec = globals->root.splt;
3828 sym_value = hash->root.plt.offset;
3829 if (sym_sec->output_section != NULL)
3830 destination = (sym_value
3831 + sym_sec->output_offset
3833 sym_sec->output_section->vma);
3840 bfd_set_error (bfd_error_bad_value);
3841 goto error_ret_free_internal;
3843 st_type = ELF_ST_TYPE (hash->root.type);
3844 sym_name = hash->root.root.root.string;
3847 /* Determine what (if any) linker stub is needed. */
3848 stub_type = aarch64_type_of_stub
3849 (info, section, irela, sym_sec, st_type, hash, destination);
3850 if (stub_type == aarch64_stub_none)
3853 /* Support for grouping stub sections. */
3854 id_sec = htab->stub_group[section->id].link_sec;
3856 /* Get the name of this stub. */
3857 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash,
3860 goto error_ret_free_internal;
3863 aarch64_stub_hash_lookup (&htab->stub_hash_table,
3864 stub_name, FALSE, FALSE);
3865 if (stub_entry != NULL)
3867 /* The proper stub has already been created. */
3872 stub_entry = _bfd_aarch64_add_stub_entry_in_group
3873 (stub_name, section, htab);
3874 if (stub_entry == NULL)
3877 goto error_ret_free_internal;
3880 stub_entry->target_value = sym_value;
3881 stub_entry->target_section = sym_sec;
3882 stub_entry->stub_type = stub_type;
3883 stub_entry->h = hash;
3884 stub_entry->st_type = st_type;
3886 if (sym_name == NULL)
3887 sym_name = "unnamed";
3888 len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
3889 stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
3890 if (stub_entry->output_name == NULL)
3893 goto error_ret_free_internal;
3896 snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
3899 stub_changed = TRUE;
3902 /* We're done with the internal relocs, free them. */
3903 if (elf_section_data (section)->relocs == NULL)
3904 free (internal_relocs);
3911 _bfd_aarch64_resize_stubs (htab);
3913 /* Ask the linker to do its stuff. */
3914 (*htab->layout_sections_again) ();
3915 stub_changed = FALSE;
3920 error_ret_free_local:
3924 /* Build all the stubs associated with the current output file. The
3925 stubs are kept in a hash table attached to the main linker hash
3926 table. We also set up the .plt entries for statically linked PIC
3927 functions here. This function is called via aarch64_elf_finish in the
3931 elfNN_aarch64_build_stubs (struct bfd_link_info *info)
3934 struct bfd_hash_table *table;
3935 struct elf_aarch64_link_hash_table *htab;
3937 htab = elf_aarch64_hash_table (info);
3939 for (stub_sec = htab->stub_bfd->sections;
3940 stub_sec != NULL; stub_sec = stub_sec->next)
3944 /* Ignore non-stub sections. */
3945 if (!strstr (stub_sec->name, STUB_SUFFIX))
3948 /* Allocate memory to hold the linker stubs. */
3949 size = stub_sec->size;
3950 stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
3951 if (stub_sec->contents == NULL && size != 0)
3955 bfd_putl32 (0x14000000 | (size >> 2), stub_sec->contents);
3956 stub_sec->size += 4;
3959 /* Build the stubs as directed by the stub hash table. */
3960 table = &htab->stub_hash_table;
3961 bfd_hash_traverse (table, aarch64_build_one_stub, info);
3967 /* Add an entry to the code/data map for section SEC. */
3970 elfNN_aarch64_section_map_add (asection *sec, char type, bfd_vma vma)
3972 struct _aarch64_elf_section_data *sec_data =
3973 elf_aarch64_section_data (sec);
3974 unsigned int newidx;
3976 if (sec_data->map == NULL)
3978 sec_data->map = bfd_malloc (sizeof (elf_aarch64_section_map));
3979 sec_data->mapcount = 0;
3980 sec_data->mapsize = 1;
3983 newidx = sec_data->mapcount++;
3985 if (sec_data->mapcount > sec_data->mapsize)
3987 sec_data->mapsize *= 2;
3988 sec_data->map = bfd_realloc_or_free
3989 (sec_data->map, sec_data->mapsize * sizeof (elf_aarch64_section_map));
3994 sec_data->map[newidx].vma = vma;
3995 sec_data->map[newidx].type = type;
4000 /* Initialise maps of insn/data for input BFDs. */
4002 bfd_elfNN_aarch64_init_maps (bfd *abfd)
4004 Elf_Internal_Sym *isymbuf;
4005 Elf_Internal_Shdr *hdr;
4006 unsigned int i, localsyms;
4008 /* Make sure that we are dealing with an AArch64 elf binary. */
4009 if (!is_aarch64_elf (abfd))
4012 if ((abfd->flags & DYNAMIC) != 0)
4015 hdr = &elf_symtab_hdr (abfd);
4016 localsyms = hdr->sh_info;
4018 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
4019 should contain the number of local symbols, which should come before any
4020 global symbols. Mapping symbols are always local. */
4021 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL);
4023 /* No internal symbols read? Skip this BFD. */
4024 if (isymbuf == NULL)
4027 for (i = 0; i < localsyms; i++)
4029 Elf_Internal_Sym *isym = &isymbuf[i];
4030 asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
4033 if (sec != NULL && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
4035 name = bfd_elf_string_from_elf_section (abfd,
4039 if (bfd_is_aarch64_special_symbol_name
4040 (name, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP))
4041 elfNN_aarch64_section_map_add (sec, name[1], isym->st_value);
4046 /* Set option values needed during linking. */
4048 bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
4049 struct bfd_link_info *link_info,
4051 int no_wchar_warn, int pic_veneer,
4052 int fix_erratum_835769,
4053 int fix_erratum_843419)
4055 struct elf_aarch64_link_hash_table *globals;
4057 globals = elf_aarch64_hash_table (link_info);
4058 globals->pic_veneer = pic_veneer;
4059 globals->fix_erratum_835769 = fix_erratum_835769;
4060 globals->fix_erratum_843419 = fix_erratum_843419;
4061 globals->fix_erratum_843419_adr = TRUE;
4063 BFD_ASSERT (is_aarch64_elf (output_bfd));
4064 elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
4065 elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
4069 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
4070 struct elf_aarch64_link_hash_table
4071 *globals, struct bfd_link_info *info,
4072 bfd_vma value, bfd *output_bfd,
4073 bfd_boolean *unresolved_reloc_p)
4075 bfd_vma off = (bfd_vma) - 1;
4076 asection *basegot = globals->root.sgot;
4077 bfd_boolean dyn = globals->root.dynamic_sections_created;
4081 BFD_ASSERT (basegot != NULL);
4082 off = h->got.offset;
4083 BFD_ASSERT (off != (bfd_vma) - 1);
4084 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
4085 || (bfd_link_pic (info)
4086 && SYMBOL_REFERENCES_LOCAL (info, h))
4087 || (ELF_ST_VISIBILITY (h->other)
4088 && h->root.type == bfd_link_hash_undefweak))
4090 /* This is actually a static link, or it is a -Bsymbolic link
4091 and the symbol is defined locally. We must initialize this
4092 entry in the global offset table. Since the offset must
4093 always be a multiple of 8 (4 in the case of ILP32), we use
4094 the least significant bit to record whether we have
4095 initialized it already.
4096 When doing a dynamic link, we create a .rel(a).got relocation
4097 entry to initialize the value. This is done in the
4098 finish_dynamic_symbol routine. */
4103 bfd_put_NN (output_bfd, value, basegot->contents + off);
4108 *unresolved_reloc_p = FALSE;
4110 off = off + basegot->output_section->vma + basegot->output_offset;
4116 /* Change R_TYPE to a more efficient access model where possible,
4117 return the new reloc type. */
4119 static bfd_reloc_code_real_type
4120 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
4121 struct elf_link_hash_entry *h)
4123 bfd_boolean is_local = h == NULL;
4127 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4128 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
4130 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4131 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
4133 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
4135 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4138 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
4140 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4141 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
4143 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
4144 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
4146 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4147 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
4149 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4150 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
4152 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
4153 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
4155 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
4158 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
4160 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
4161 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
4163 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4164 case BFD_RELOC_AARCH64_TLSDESC_CALL:
4165 /* Instructions with these relocations will become NOPs. */
4166 return BFD_RELOC_AARCH64_NONE;
4176 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
4180 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4181 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
4182 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
4183 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
4184 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
4185 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
4188 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
4189 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
4190 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
4191 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
4192 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
4193 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
4196 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4197 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4198 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
4199 case BFD_RELOC_AARCH64_TLSDESC_CALL:
4200 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
4201 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
4202 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
4203 return GOT_TLSDESC_GD;
4205 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4206 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
4207 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
4208 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
4218 aarch64_can_relax_tls (bfd *input_bfd,
4219 struct bfd_link_info *info,
4220 bfd_reloc_code_real_type r_type,
4221 struct elf_link_hash_entry *h,
4222 unsigned long r_symndx)
4224 unsigned int symbol_got_type;
4225 unsigned int reloc_got_type;
4227 if (! IS_AARCH64_TLS_RELAX_RELOC (r_type))
4230 symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
4231 reloc_got_type = aarch64_reloc_got_type (r_type);
4233 if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
4236 if (bfd_link_pic (info))
4239 if (h && h->root.type == bfd_link_hash_undefweak)
4245 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
4248 static bfd_reloc_code_real_type
4249 aarch64_tls_transition (bfd *input_bfd,
4250 struct bfd_link_info *info,
4251 unsigned int r_type,
4252 struct elf_link_hash_entry *h,
4253 unsigned long r_symndx)
4255 bfd_reloc_code_real_type bfd_r_type
4256 = elfNN_aarch64_bfd_reloc_from_type (r_type);
4258 if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
4261 return aarch64_tls_transition_without_check (bfd_r_type, h);
4264 /* Return the base VMA address which should be subtracted from real addresses
4265 when resolving R_AARCH64_TLS_DTPREL relocation. */
4268 dtpoff_base (struct bfd_link_info *info)
4270 /* If tls_sec is NULL, we should have signalled an error already. */
4271 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4272 return elf_hash_table (info)->tls_sec->vma;
4275 /* Return the base VMA address which should be subtracted from real addresses
4276 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
4279 tpoff_base (struct bfd_link_info *info)
4281 struct elf_link_hash_table *htab = elf_hash_table (info);
4283 /* If tls_sec is NULL, we should have signalled an error already. */
4284 BFD_ASSERT (htab->tls_sec != NULL);
4286 bfd_vma base = align_power ((bfd_vma) TCB_SIZE,
4287 htab->tls_sec->alignment_power);
4288 return htab->tls_sec->vma - base;
4292 symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
4293 unsigned long r_symndx)
4295 /* Calculate the address of the GOT entry for symbol
4296 referred to in h. */
4298 return &h->got.offset;
4302 struct elf_aarch64_local_symbol *l;
4304 l = elf_aarch64_locals (input_bfd);
4305 return &l[r_symndx].got_offset;
4310 symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
4311 unsigned long r_symndx)
4314 p = symbol_got_offset_ref (input_bfd, h, r_symndx);
4319 symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
4320 unsigned long r_symndx)
4323 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
4328 symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
4329 unsigned long r_symndx)
4332 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
4338 symbol_tlsdesc_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
4339 unsigned long r_symndx)
4341 /* Calculate the address of the GOT entry for symbol
4342 referred to in h. */
4345 struct elf_aarch64_link_hash_entry *eh;
4346 eh = (struct elf_aarch64_link_hash_entry *) h;
4347 return &eh->tlsdesc_got_jump_table_offset;
4352 struct elf_aarch64_local_symbol *l;
4354 l = elf_aarch64_locals (input_bfd);
4355 return &l[r_symndx].tlsdesc_got_jump_table_offset;
4360 symbol_tlsdesc_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
4361 unsigned long r_symndx)
4364 p = symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
4369 symbol_tlsdesc_got_offset_mark_p (bfd *input_bfd,
4370 struct elf_link_hash_entry *h,
4371 unsigned long r_symndx)
4374 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
4379 symbol_tlsdesc_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
4380 unsigned long r_symndx)
4383 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
4388 /* Data for make_branch_to_erratum_835769_stub(). */
4390 struct erratum_835769_branch_to_stub_data
4392 struct bfd_link_info *info;
4393 asection *output_section;
4397 /* Helper to insert branches to erratum 835769 stubs in the right
4398 places for a particular section. */
4401 make_branch_to_erratum_835769_stub (struct bfd_hash_entry *gen_entry,
4404 struct elf_aarch64_stub_hash_entry *stub_entry;
4405 struct erratum_835769_branch_to_stub_data *data;
4407 unsigned long branch_insn = 0;
4408 bfd_vma veneered_insn_loc, veneer_entry_loc;
4409 bfd_signed_vma branch_offset;
4410 unsigned int target;
4413 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
4414 data = (struct erratum_835769_branch_to_stub_data *) in_arg;
4416 if (stub_entry->target_section != data->output_section
4417 || stub_entry->stub_type != aarch64_stub_erratum_835769_veneer)
4420 contents = data->contents;
4421 veneered_insn_loc = stub_entry->target_section->output_section->vma
4422 + stub_entry->target_section->output_offset
4423 + stub_entry->target_value;
4424 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
4425 + stub_entry->stub_sec->output_offset
4426 + stub_entry->stub_offset;
4427 branch_offset = veneer_entry_loc - veneered_insn_loc;
4429 abfd = stub_entry->target_section->owner;
4430 if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
4431 (*_bfd_error_handler)
4432 (_("%B: error: Erratum 835769 stub out "
4433 "of range (input file too large)"), abfd);
4435 target = stub_entry->target_value;
4436 branch_insn = 0x14000000;
4437 branch_offset >>= 2;
4438 branch_offset &= 0x3ffffff;
4439 branch_insn |= branch_offset;
4440 bfd_putl32 (branch_insn, &contents[target]);
4447 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
4450 struct elf_aarch64_stub_hash_entry *stub_entry
4451 = (struct elf_aarch64_stub_hash_entry *) gen_entry;
4452 struct erratum_835769_branch_to_stub_data *data
4453 = (struct erratum_835769_branch_to_stub_data *) in_arg;
4454 struct bfd_link_info *info;
4455 struct elf_aarch64_link_hash_table *htab;
4463 contents = data->contents;
4464 section = data->output_section;
4466 htab = elf_aarch64_hash_table (info);
4468 if (stub_entry->target_section != section
4469 || stub_entry->stub_type != aarch64_stub_erratum_843419_veneer)
4472 insn = bfd_getl32 (contents + stub_entry->target_value);
4474 stub_entry->stub_sec->contents + stub_entry->stub_offset);
4476 place = (section->output_section->vma + section->output_offset
4477 + stub_entry->adrp_offset);
4478 insn = bfd_getl32 (contents + stub_entry->adrp_offset);
4480 if ((insn & AARCH64_ADRP_OP_MASK) != AARCH64_ADRP_OP)
4483 bfd_signed_vma imm =
4484 (_bfd_aarch64_sign_extend
4485 ((bfd_vma) _bfd_aarch64_decode_adrp_imm (insn) << 12, 33)
4488 if (htab->fix_erratum_843419_adr
4489 && (imm >= AARCH64_MIN_ADRP_IMM && imm <= AARCH64_MAX_ADRP_IMM))
4491 insn = (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP, imm)
4492 | AARCH64_RT (insn));
4493 bfd_putl32 (insn, contents + stub_entry->adrp_offset);
4497 bfd_vma veneered_insn_loc;
4498 bfd_vma veneer_entry_loc;
4499 bfd_signed_vma branch_offset;
4500 uint32_t branch_insn;
4502 veneered_insn_loc = stub_entry->target_section->output_section->vma
4503 + stub_entry->target_section->output_offset
4504 + stub_entry->target_value;
4505 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
4506 + stub_entry->stub_sec->output_offset
4507 + stub_entry->stub_offset;
4508 branch_offset = veneer_entry_loc - veneered_insn_loc;
4510 abfd = stub_entry->target_section->owner;
4511 if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
4512 (*_bfd_error_handler)
4513 (_("%B: error: Erratum 843419 stub out "
4514 "of range (input file too large)"), abfd);
4516 branch_insn = 0x14000000;
4517 branch_offset >>= 2;
4518 branch_offset &= 0x3ffffff;
4519 branch_insn |= branch_offset;
4520 bfd_putl32 (branch_insn, contents + stub_entry->target_value);
4527 elfNN_aarch64_write_section (bfd *output_bfd ATTRIBUTE_UNUSED,
4528 struct bfd_link_info *link_info,
4533 struct elf_aarch64_link_hash_table *globals =
4534 elf_aarch64_hash_table (link_info);
4536 if (globals == NULL)
4539 /* Fix code to point to erratum 835769 stubs. */
4540 if (globals->fix_erratum_835769)
4542 struct erratum_835769_branch_to_stub_data data;
4544 data.info = link_info;
4545 data.output_section = sec;
4546 data.contents = contents;
4547 bfd_hash_traverse (&globals->stub_hash_table,
4548 make_branch_to_erratum_835769_stub, &data);
4551 if (globals->fix_erratum_843419)
4553 struct erratum_835769_branch_to_stub_data data;
4555 data.info = link_info;
4556 data.output_section = sec;
4557 data.contents = contents;
4558 bfd_hash_traverse (&globals->stub_hash_table,
4559 _bfd_aarch64_erratum_843419_branch_to_stub, &data);
4565 /* Perform a relocation as part of a final link. */
4566 static bfd_reloc_status_type
4567 elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
4570 asection *input_section,
4572 Elf_Internal_Rela *rel,
4574 struct bfd_link_info *info,
4576 struct elf_link_hash_entry *h,
4577 bfd_boolean *unresolved_reloc_p,
4578 bfd_boolean save_addend,
4579 bfd_vma *saved_addend,
4580 Elf_Internal_Sym *sym)
4582 Elf_Internal_Shdr *symtab_hdr;
4583 unsigned int r_type = howto->type;
4584 bfd_reloc_code_real_type bfd_r_type
4585 = elfNN_aarch64_bfd_reloc_from_howto (howto);
4586 bfd_reloc_code_real_type new_bfd_r_type;
4587 unsigned long r_symndx;
4588 bfd_byte *hit_data = contents + rel->r_offset;
4590 bfd_signed_vma signed_addend;
4591 struct elf_aarch64_link_hash_table *globals;
4592 bfd_boolean weak_undef_p;
4595 globals = elf_aarch64_hash_table (info);
4597 symtab_hdr = &elf_symtab_hdr (input_bfd);
4599 BFD_ASSERT (is_aarch64_elf (input_bfd));
4601 r_symndx = ELFNN_R_SYM (rel->r_info);
4603 /* It is possible to have linker relaxations on some TLS access
4604 models. Update our information here. */
4605 new_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, h, r_symndx);
4606 if (new_bfd_r_type != bfd_r_type)
4608 bfd_r_type = new_bfd_r_type;
4609 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
4610 BFD_ASSERT (howto != NULL);
4611 r_type = howto->type;
4614 place = input_section->output_section->vma
4615 + input_section->output_offset + rel->r_offset;
4617 /* Get addend, accumulating the addend for consecutive relocs
4618 which refer to the same offset. */
4619 signed_addend = saved_addend ? *saved_addend : 0;
4620 signed_addend += rel->r_addend;
4622 weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
4623 : bfd_is_und_section (sym_sec));
4625 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
4626 it here if it is defined in a non-shared object. */
4628 && h->type == STT_GNU_IFUNC
4635 if ((input_section->flags & SEC_ALLOC) == 0
4636 || h->plt.offset == (bfd_vma) -1)
4639 /* STT_GNU_IFUNC symbol must go through PLT. */
4640 plt = globals->root.splt ? globals->root.splt : globals->root.iplt;
4641 value = (plt->output_section->vma + plt->output_offset + h->plt.offset);
4646 if (h->root.root.string)
4647 name = h->root.root.string;
4649 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4651 (*_bfd_error_handler)
4652 (_("%B: relocation %s against STT_GNU_IFUNC "
4653 "symbol `%s' isn't handled by %s"), input_bfd,
4654 howto->name, name, __FUNCTION__);
4655 bfd_set_error (bfd_error_bad_value);
4658 case BFD_RELOC_AARCH64_NN:
4659 if (rel->r_addend != 0)
4661 if (h->root.root.string)
4662 name = h->root.root.string;
4664 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
4666 (*_bfd_error_handler)
4667 (_("%B: relocation %s against STT_GNU_IFUNC "
4668 "symbol `%s' has non-zero addend: %d"),
4669 input_bfd, howto->name, name, rel->r_addend);
4670 bfd_set_error (bfd_error_bad_value);
4674 /* Generate dynamic relocation only when there is a
4675 non-GOT reference in a shared object. */
4676 if (bfd_link_pic (info) && h->non_got_ref)
4678 Elf_Internal_Rela outrel;
4681 /* Need a dynamic relocation to get the real function
4683 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
4687 if (outrel.r_offset == (bfd_vma) -1
4688 || outrel.r_offset == (bfd_vma) -2)
4691 outrel.r_offset += (input_section->output_section->vma
4692 + input_section->output_offset);
4694 if (h->dynindx == -1
4696 || bfd_link_executable (info))
4698 /* This symbol is resolved locally. */
4699 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
4700 outrel.r_addend = (h->root.u.def.value
4701 + h->root.u.def.section->output_section->vma
4702 + h->root.u.def.section->output_offset);
4706 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
4707 outrel.r_addend = 0;
4710 sreloc = globals->root.irelifunc;
4711 elf_append_rela (output_bfd, sreloc, &outrel);
4713 /* If this reloc is against an external symbol, we
4714 do not want to fiddle with the addend. Otherwise,
4715 we need to include the symbol value so that it
4716 becomes an addend for the dynamic reloc. For an
4717 internal symbol, we have updated addend. */
4718 return bfd_reloc_ok;
4721 case BFD_RELOC_AARCH64_CALL26:
4722 case BFD_RELOC_AARCH64_JUMP26:
4723 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
4726 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
4728 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4729 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
4730 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
4731 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
4732 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
4733 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
4734 base_got = globals->root.sgot;
4735 off = h->got.offset;
4737 if (base_got == NULL)
4740 if (off == (bfd_vma) -1)
4744 /* We can't use h->got.offset here to save state, or
4745 even just remember the offset, as finish_dynamic_symbol
4746 would use that as offset into .got. */
4748 if (globals->root.splt != NULL)
4750 plt_index = ((h->plt.offset - globals->plt_header_size) /
4751 globals->plt_entry_size);
4752 off = (plt_index + 3) * GOT_ENTRY_SIZE;
4753 base_got = globals->root.sgotplt;
4757 plt_index = h->plt.offset / globals->plt_entry_size;
4758 off = plt_index * GOT_ENTRY_SIZE;
4759 base_got = globals->root.igotplt;
4762 if (h->dynindx == -1
4766 /* This references the local definition. We must
4767 initialize this entry in the global offset table.
4768 Since the offset must always be a multiple of 8,
4769 we use the least significant bit to record
4770 whether we have initialized it already.
4772 When doing a dynamic link, we create a .rela.got
4773 relocation entry to initialize the value. This
4774 is done in the finish_dynamic_symbol routine. */
4779 bfd_put_NN (output_bfd, value,
4780 base_got->contents + off);
4781 /* Note that this is harmless as -1 | 1 still is -1. */
4785 value = (base_got->output_section->vma
4786 + base_got->output_offset + off);
4789 value = aarch64_calculate_got_entry_vma (h, globals, info,
4791 unresolved_reloc_p);
4792 if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
4793 || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
4794 addend = (globals->root.sgot->output_section->vma
4795 + globals->root.sgot->output_offset);
4796 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
4797 addend, weak_undef_p);
4798 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
4799 case BFD_RELOC_AARCH64_ADD_LO12:
4800 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
4807 case BFD_RELOC_AARCH64_NONE:
4808 case BFD_RELOC_AARCH64_TLSDESC_CALL:
4809 *unresolved_reloc_p = FALSE;
4810 return bfd_reloc_ok;
4812 case BFD_RELOC_AARCH64_NN:
4814 /* When generating a shared object or relocatable executable, these
4815 relocations are copied into the output file to be resolved at
4817 if (((bfd_link_pic (info) == TRUE)
4818 || globals->root.is_relocatable_executable)
4819 && (input_section->flags & SEC_ALLOC)
4821 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4822 || h->root.type != bfd_link_hash_undefweak))
4824 Elf_Internal_Rela outrel;
4826 bfd_boolean skip, relocate;
4829 *unresolved_reloc_p = FALSE;
4834 outrel.r_addend = signed_addend;
4836 _bfd_elf_section_offset (output_bfd, info, input_section,
4838 if (outrel.r_offset == (bfd_vma) - 1)
4840 else if (outrel.r_offset == (bfd_vma) - 2)
4846 outrel.r_offset += (input_section->output_section->vma
4847 + input_section->output_offset);
4850 memset (&outrel, 0, sizeof outrel);
4853 && (!bfd_link_pic (info)
4854 || !SYMBOLIC_BIND (info, h)
4855 || !h->def_regular))
4856 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
4861 /* On SVR4-ish systems, the dynamic loader cannot
4862 relocate the text and data segments independently,
4863 so the symbol does not matter. */
4865 outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
4866 outrel.r_addend += value;
4869 sreloc = elf_section_data (input_section)->sreloc;
4870 if (sreloc == NULL || sreloc->contents == NULL)
4871 return bfd_reloc_notsupported;
4873 loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
4874 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4876 if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
4878 /* Sanity to check that we have previously allocated
4879 sufficient space in the relocation section for the
4880 number of relocations we actually want to emit. */
4884 /* If this reloc is against an external symbol, we do not want to
4885 fiddle with the addend. Otherwise, we need to include the symbol
4886 value so that it becomes an addend for the dynamic reloc. */
4888 return bfd_reloc_ok;
4890 return _bfd_final_link_relocate (howto, input_bfd, input_section,
4891 contents, rel->r_offset, value,
4895 value += signed_addend;
4898 case BFD_RELOC_AARCH64_CALL26:
4899 case BFD_RELOC_AARCH64_JUMP26:
4901 asection *splt = globals->root.splt;
4902 bfd_boolean via_plt_p =
4903 splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
4905 /* A call to an undefined weak symbol is converted to a jump to
4906 the next instruction unless a PLT entry will be created.
4907 The jump to the next instruction is optimized as a NOP.
4908 Do the same for local undefined symbols. */
4909 if (weak_undef_p && ! via_plt_p)
4911 bfd_putl32 (INSN_NOP, hit_data);
4912 return bfd_reloc_ok;
4915 /* If the call goes through a PLT entry, make sure to
4916 check distance to the right destination address. */
4918 value = (splt->output_section->vma
4919 + splt->output_offset + h->plt.offset);
4921 /* Check if a stub has to be inserted because the destination
4923 struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
4924 if (! aarch64_valid_branch_p (value, place))
4925 /* The target is out of reach, so redirect the branch to
4926 the local stub for this function. */
4927 stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
4929 if (stub_entry != NULL)
4930 value = (stub_entry->stub_offset
4931 + stub_entry->stub_sec->output_offset
4932 + stub_entry->stub_sec->output_section->vma);
4934 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
4935 signed_addend, weak_undef_p);
4936 *unresolved_reloc_p = FALSE;
4939 case BFD_RELOC_AARCH64_16_PCREL:
4940 case BFD_RELOC_AARCH64_32_PCREL:
4941 case BFD_RELOC_AARCH64_64_PCREL:
4942 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
4943 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
4944 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
4945 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
4946 if (bfd_link_pic (info)
4947 && (input_section->flags & SEC_ALLOC) != 0
4948 && (input_section->flags & SEC_READONLY) != 0
4952 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
4954 (*_bfd_error_handler)
4955 (_("%B: relocation %s against external symbol `%s' can not be used"
4956 " when making a shared object; recompile with -fPIC"),
4957 input_bfd, elfNN_aarch64_howto_table[howto_index].name,
4958 h->root.root.string);
4959 bfd_set_error (bfd_error_bad_value);
4963 case BFD_RELOC_AARCH64_16:
4965 case BFD_RELOC_AARCH64_32:
4967 case BFD_RELOC_AARCH64_ADD_LO12:
4968 case BFD_RELOC_AARCH64_BRANCH19:
4969 case BFD_RELOC_AARCH64_LDST128_LO12:
4970 case BFD_RELOC_AARCH64_LDST16_LO12:
4971 case BFD_RELOC_AARCH64_LDST32_LO12:
4972 case BFD_RELOC_AARCH64_LDST64_LO12:
4973 case BFD_RELOC_AARCH64_LDST8_LO12:
4974 case BFD_RELOC_AARCH64_MOVW_G0:
4975 case BFD_RELOC_AARCH64_MOVW_G0_NC:
4976 case BFD_RELOC_AARCH64_MOVW_G0_S:
4977 case BFD_RELOC_AARCH64_MOVW_G1:
4978 case BFD_RELOC_AARCH64_MOVW_G1_NC:
4979 case BFD_RELOC_AARCH64_MOVW_G1_S:
4980 case BFD_RELOC_AARCH64_MOVW_G2:
4981 case BFD_RELOC_AARCH64_MOVW_G2_NC:
4982 case BFD_RELOC_AARCH64_MOVW_G2_S:
4983 case BFD_RELOC_AARCH64_MOVW_G3:
4984 case BFD_RELOC_AARCH64_TSTBR14:
4985 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
4986 signed_addend, weak_undef_p);
4989 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4990 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
4991 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
4992 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
4993 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
4994 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
4995 if (globals->root.sgot == NULL)
4996 BFD_ASSERT (h != NULL);
5001 value = aarch64_calculate_got_entry_vma (h, globals, info, value,
5003 unresolved_reloc_p);
5004 if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5005 || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
5006 addend = (globals->root.sgot->output_section->vma
5007 + globals->root.sgot->output_offset);
5008 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5009 addend, weak_undef_p);
5014 struct elf_aarch64_local_symbol *locals
5015 = elf_aarch64_locals (input_bfd);
5019 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
5020 (*_bfd_error_handler)
5021 (_("%B: Local symbol descriptor table be NULL when applying "
5022 "relocation %s against local symbol"),
5023 input_bfd, elfNN_aarch64_howto_table[howto_index].name);
5027 off = symbol_got_offset (input_bfd, h, r_symndx);
5028 base_got = globals->root.sgot;
5029 bfd_vma got_entry_addr = (base_got->output_section->vma
5030 + base_got->output_offset + off);
5032 if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
5034 bfd_put_64 (output_bfd, value, base_got->contents + off);
5036 if (bfd_link_pic (info))
5039 Elf_Internal_Rela outrel;
5041 /* For local symbol, we have done absolute relocation in static
5042 linking stageh. While for share library, we need to update
5043 the content of GOT entry according to the share objects
5044 loading base address. So we need to generate a
5045 R_AARCH64_RELATIVE reloc for dynamic linker. */
5046 s = globals->root.srelgot;
5050 outrel.r_offset = got_entry_addr;
5051 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
5052 outrel.r_addend = value;
5053 elf_append_rela (output_bfd, s, &outrel);
5056 symbol_got_offset_mark (input_bfd, h, r_symndx);
5059 /* Update the relocation value to GOT entry addr as we have transformed
5060 the direct data access into indirect data access through GOT. */
5061 value = got_entry_addr;
5063 if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5064 || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
5065 addend = base_got->output_section->vma + base_got->output_offset;
5067 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5068 addend, weak_undef_p);
5073 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
5074 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
5075 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
5076 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5077 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
5078 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
5079 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
5080 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
5081 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
5082 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
5083 if (globals->root.sgot == NULL)
5084 return bfd_reloc_notsupported;
5086 value = (symbol_got_offset (input_bfd, h, r_symndx)
5087 + globals->root.sgot->output_section->vma
5088 + globals->root.sgot->output_offset);
5090 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5092 *unresolved_reloc_p = FALSE;
5095 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12:
5096 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5097 signed_addend - dtpoff_base (info),
5101 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
5102 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
5103 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
5104 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
5105 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
5106 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
5107 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
5108 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
5109 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5110 signed_addend - tpoff_base (info),
5112 *unresolved_reloc_p = FALSE;
5115 case BFD_RELOC_AARCH64_TLSDESC_ADD:
5116 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
5117 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
5118 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
5119 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
5120 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
5121 case BFD_RELOC_AARCH64_TLSDESC_LDR:
5122 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
5123 if (globals->root.sgot == NULL)
5124 return bfd_reloc_notsupported;
5125 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
5126 + globals->root.sgotplt->output_section->vma
5127 + globals->root.sgotplt->output_offset
5128 + globals->sgotplt_jump_table_size);
5130 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5132 *unresolved_reloc_p = FALSE;
5136 return bfd_reloc_notsupported;
5140 *saved_addend = value;
5142 /* Only apply the final relocation in a sequence. */
5144 return bfd_reloc_continue;
5146 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
5150 /* Handle TLS relaxations. Relaxing is possible for symbols that use
5151 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
5154 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
5155 is to then call final_link_relocate. Return other values in the
5158 static bfd_reloc_status_type
5159 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
5160 bfd *input_bfd, bfd_byte *contents,
5161 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h)
5163 bfd_boolean is_local = h == NULL;
5164 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
5167 BFD_ASSERT (globals && input_bfd && contents && rel);
5169 switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
5171 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
5172 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
5175 /* GD->LE relaxation:
5176 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
5178 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
5180 bfd_putl32 (0xd2a00000, contents + rel->r_offset);
5181 return bfd_reloc_continue;
5185 /* GD->IE relaxation:
5186 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
5188 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
5190 return bfd_reloc_continue;
5193 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
5197 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
5200 /* Tiny TLSDESC->LE relaxation:
5201 ldr x1, :tlsdesc:var => movz x0, #:tprel_g1:var
5202 adr x0, :tlsdesc:var => movk x0, #:tprel_g0_nc:var
5206 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
5207 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
5209 rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
5210 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
5211 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5213 bfd_putl32 (0xd2a00000, contents + rel->r_offset);
5214 bfd_putl32 (0xf2800000, contents + rel->r_offset + 4);
5215 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
5216 return bfd_reloc_continue;
5220 /* Tiny TLSDESC->IE relaxation:
5221 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
5222 adr x0, :tlsdesc:var => nop
5226 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
5227 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
5229 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5230 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5232 bfd_putl32 (0x58000000, contents + rel->r_offset);
5233 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
5234 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
5235 return bfd_reloc_continue;
5238 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
5241 /* Tiny GD->LE relaxation:
5242 adr x0, :tlsgd:var => mrs x1, tpidr_el0
5243 bl __tls_get_addr => add x0, x1, #:tprel_hi12:x, lsl #12
5244 nop => add x0, x0, #:tprel_lo12_nc:x
5247 /* First kill the tls_get_addr reloc on the bl instruction. */
5248 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
5250 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 0);
5251 bfd_putl32 (0x91400020, contents + rel->r_offset + 4);
5252 bfd_putl32 (0x91000000, contents + rel->r_offset + 8);
5254 rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
5255 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC));
5256 rel[1].r_offset = rel->r_offset + 8;
5258 /* Move the current relocation to the second instruction in
5261 rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
5262 AARCH64_R (TLSLE_ADD_TPREL_HI12));
5263 return bfd_reloc_continue;
5267 /* Tiny GD->IE relaxation:
5268 adr x0, :tlsgd:var => ldr x0, :gottprel:var
5269 bl __tls_get_addr => mrs x1, tpidr_el0
5270 nop => add x0, x0, x1
5273 /* First kill the tls_get_addr reloc on the bl instruction. */
5274 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
5275 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5277 bfd_putl32 (0x58000000, contents + rel->r_offset);
5278 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
5279 bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
5280 return bfd_reloc_continue;
5283 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
5284 return bfd_reloc_continue;
5286 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
5289 /* GD->LE relaxation:
5290 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
5292 bfd_putl32 (0xf2800000, contents + rel->r_offset);
5293 return bfd_reloc_continue;
5297 /* GD->IE relaxation:
5298 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
5300 insn = bfd_getl32 (contents + rel->r_offset);
5302 bfd_putl32 (insn, contents + rel->r_offset);
5303 return bfd_reloc_continue;
5306 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
5309 /* GD->LE relaxation
5310 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
5311 bl __tls_get_addr => mrs x1, tpidr_el0
5312 nop => add x0, x1, x0
5315 /* First kill the tls_get_addr reloc on the bl instruction. */
5316 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
5317 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5319 bfd_putl32 (0xf2800000, contents + rel->r_offset);
5320 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
5321 bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
5322 return bfd_reloc_continue;
5326 /* GD->IE relaxation
5327 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
5328 BL __tls_get_addr => mrs x1, tpidr_el0
5330 NOP => add x0, x1, x0
5333 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
5335 /* Remove the relocation on the BL instruction. */
5336 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5338 bfd_putl32 (0xf9400000, contents + rel->r_offset);
5340 /* We choose to fixup the BL and NOP instructions using the
5341 offset from the second relocation to allow flexibility in
5342 scheduling instructions between the ADD and BL. */
5343 bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
5344 bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
5345 return bfd_reloc_continue;
5348 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
5349 case BFD_RELOC_AARCH64_TLSDESC_CALL:
5350 /* GD->IE/LE relaxation:
5351 add x0, x0, #:tlsdesc_lo12:var => nop
5354 bfd_putl32 (INSN_NOP, contents + rel->r_offset);
5355 return bfd_reloc_ok;
5357 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5358 /* IE->LE relaxation:
5359 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
5363 insn = bfd_getl32 (contents + rel->r_offset);
5364 bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
5366 return bfd_reloc_continue;
5368 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
5369 /* IE->LE relaxation:
5370 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
5374 insn = bfd_getl32 (contents + rel->r_offset);
5375 bfd_putl32 (0xf2800000 | (insn & 0x1f), contents + rel->r_offset);
5377 return bfd_reloc_continue;
5380 return bfd_reloc_continue;
5383 return bfd_reloc_ok;
5386 /* Relocate an AArch64 ELF section. */
5389 elfNN_aarch64_relocate_section (bfd *output_bfd,
5390 struct bfd_link_info *info,
5392 asection *input_section,
5394 Elf_Internal_Rela *relocs,
5395 Elf_Internal_Sym *local_syms,
5396 asection **local_sections)
5398 Elf_Internal_Shdr *symtab_hdr;
5399 struct elf_link_hash_entry **sym_hashes;
5400 Elf_Internal_Rela *rel;
5401 Elf_Internal_Rela *relend;
5403 struct elf_aarch64_link_hash_table *globals;
5404 bfd_boolean save_addend = FALSE;
5407 globals = elf_aarch64_hash_table (info);
5409 symtab_hdr = &elf_symtab_hdr (input_bfd);
5410 sym_hashes = elf_sym_hashes (input_bfd);
5413 relend = relocs + input_section->reloc_count;
5414 for (; rel < relend; rel++)
5416 unsigned int r_type;
5417 bfd_reloc_code_real_type bfd_r_type;
5418 bfd_reloc_code_real_type relaxed_bfd_r_type;
5419 reloc_howto_type *howto;
5420 unsigned long r_symndx;
5421 Elf_Internal_Sym *sym;
5423 struct elf_link_hash_entry *h;
5425 bfd_reloc_status_type r;
5428 bfd_boolean unresolved_reloc = FALSE;
5429 char *error_message = NULL;
5431 r_symndx = ELFNN_R_SYM (rel->r_info);
5432 r_type = ELFNN_R_TYPE (rel->r_info);
5434 bfd_reloc.howto = elfNN_aarch64_howto_from_type (r_type);
5435 howto = bfd_reloc.howto;
5439 (*_bfd_error_handler)
5440 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
5441 input_bfd, input_section, r_type);
5444 bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
5450 if (r_symndx < symtab_hdr->sh_info)
5452 sym = local_syms + r_symndx;
5453 sym_type = ELFNN_ST_TYPE (sym->st_info);
5454 sec = local_sections[r_symndx];
5456 /* An object file might have a reference to a local
5457 undefined symbol. This is a daft object file, but we
5458 should at least do something about it. */
5459 if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
5460 && bfd_is_und_section (sec)
5461 && ELF_ST_BIND (sym->st_info) != STB_WEAK)
5463 if (!info->callbacks->undefined_symbol
5464 (info, bfd_elf_string_from_elf_section
5465 (input_bfd, symtab_hdr->sh_link, sym->st_name),
5466 input_bfd, input_section, rel->r_offset, TRUE))
5470 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
5472 /* Relocate against local STT_GNU_IFUNC symbol. */
5473 if (!bfd_link_relocatable (info)
5474 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
5476 h = elfNN_aarch64_get_local_sym_hash (globals, input_bfd,
5481 /* Set STT_GNU_IFUNC symbol value. */
5482 h->root.u.def.value = sym->st_value;
5483 h->root.u.def.section = sec;
5488 bfd_boolean warned, ignored;
5490 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
5491 r_symndx, symtab_hdr, sym_hashes,
5493 unresolved_reloc, warned, ignored);
5498 if (sec != NULL && discarded_section (sec))
5499 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
5500 rel, 1, relend, howto, 0, contents);
5502 if (bfd_link_relocatable (info))
5506 name = h->root.root.string;
5509 name = (bfd_elf_string_from_elf_section
5510 (input_bfd, symtab_hdr->sh_link, sym->st_name));
5511 if (name == NULL || *name == '\0')
5512 name = bfd_section_name (input_bfd, sec);
5516 && r_type != R_AARCH64_NONE
5517 && r_type != R_AARCH64_NULL
5519 || h->root.type == bfd_link_hash_defined
5520 || h->root.type == bfd_link_hash_defweak)
5521 && IS_AARCH64_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
5523 (*_bfd_error_handler)
5524 ((sym_type == STT_TLS
5525 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
5526 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
5528 input_section, (long) rel->r_offset, howto->name, name);
5531 /* We relax only if we can see that there can be a valid transition
5532 from a reloc type to another.
5533 We call elfNN_aarch64_final_link_relocate unless we're completely
5534 done, i.e., the relaxation produced the final output we want. */
5536 relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
5538 if (relaxed_bfd_r_type != bfd_r_type)
5540 bfd_r_type = relaxed_bfd_r_type;
5541 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
5542 BFD_ASSERT (howto != NULL);
5543 r_type = howto->type;
5544 r = elfNN_aarch64_tls_relax (globals, input_bfd, contents, rel, h);
5545 unresolved_reloc = 0;
5548 r = bfd_reloc_continue;
5550 /* There may be multiple consecutive relocations for the
5551 same offset. In that case we are supposed to treat the
5552 output of each relocation as the addend for the next. */
5553 if (rel + 1 < relend
5554 && rel->r_offset == rel[1].r_offset
5555 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NONE
5556 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NULL)
5559 save_addend = FALSE;
5561 if (r == bfd_reloc_continue)
5562 r = elfNN_aarch64_final_link_relocate (howto, input_bfd, output_bfd,
5563 input_section, contents, rel,
5564 relocation, info, sec,
5565 h, &unresolved_reloc,
5566 save_addend, &addend, sym);
5568 switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
5570 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
5571 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
5572 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
5573 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
5574 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
5575 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
5576 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
5578 bfd_boolean need_relocs = FALSE;
5583 off = symbol_got_offset (input_bfd, h, r_symndx);
5584 indx = h && h->dynindx != -1 ? h->dynindx : 0;
5587 (bfd_link_pic (info) || indx != 0) &&
5589 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5590 || h->root.type != bfd_link_hash_undefweak);
5592 BFD_ASSERT (globals->root.srelgot != NULL);
5596 Elf_Internal_Rela rela;
5597 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPMOD));
5599 rela.r_offset = globals->root.sgot->output_section->vma +
5600 globals->root.sgot->output_offset + off;
5603 loc = globals->root.srelgot->contents;
5604 loc += globals->root.srelgot->reloc_count++
5605 * RELOC_SIZE (htab);
5606 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
5608 bfd_reloc_code_real_type real_type =
5609 elfNN_aarch64_bfd_reloc_from_type (r_type);
5611 if (real_type == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
5612 || real_type == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
5613 || real_type == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC)
5615 /* For local dynamic, don't generate DTPREL in any case.
5616 Initialize the DTPREL slot into zero, so we get module
5617 base address when invoke runtime TLS resolver. */
5618 bfd_put_NN (output_bfd, 0,
5619 globals->root.sgot->contents + off
5624 bfd_put_NN (output_bfd,
5625 relocation - dtpoff_base (info),
5626 globals->root.sgot->contents + off
5631 /* This TLS symbol is global. We emit a
5632 relocation to fixup the tls offset at load
5635 ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPREL));
5638 (globals->root.sgot->output_section->vma
5639 + globals->root.sgot->output_offset + off
5642 loc = globals->root.srelgot->contents;
5643 loc += globals->root.srelgot->reloc_count++
5644 * RELOC_SIZE (globals);
5645 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
5646 bfd_put_NN (output_bfd, (bfd_vma) 0,
5647 globals->root.sgot->contents + off
5653 bfd_put_NN (output_bfd, (bfd_vma) 1,
5654 globals->root.sgot->contents + off);
5655 bfd_put_NN (output_bfd,
5656 relocation - dtpoff_base (info),
5657 globals->root.sgot->contents + off
5661 symbol_got_offset_mark (input_bfd, h, r_symndx);
5665 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5666 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
5667 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
5668 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
5670 bfd_boolean need_relocs = FALSE;
5675 off = symbol_got_offset (input_bfd, h, r_symndx);
5677 indx = h && h->dynindx != -1 ? h->dynindx : 0;
5680 (bfd_link_pic (info) || indx != 0) &&
5682 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5683 || h->root.type != bfd_link_hash_undefweak);
5685 BFD_ASSERT (globals->root.srelgot != NULL);
5689 Elf_Internal_Rela rela;
5692 rela.r_addend = relocation - dtpoff_base (info);
5696 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_TPREL));
5697 rela.r_offset = globals->root.sgot->output_section->vma +
5698 globals->root.sgot->output_offset + off;
5700 loc = globals->root.srelgot->contents;
5701 loc += globals->root.srelgot->reloc_count++
5702 * RELOC_SIZE (htab);
5704 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
5706 bfd_put_NN (output_bfd, rela.r_addend,
5707 globals->root.sgot->contents + off);
5710 bfd_put_NN (output_bfd, relocation - tpoff_base (info),
5711 globals->root.sgot->contents + off);
5713 symbol_got_offset_mark (input_bfd, h, r_symndx);
5717 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
5718 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
5719 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
5720 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
5721 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
5722 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
5724 bfd_boolean need_relocs = FALSE;
5725 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
5726 bfd_vma off = symbol_tlsdesc_got_offset (input_bfd, h, r_symndx);
5728 need_relocs = (h == NULL
5729 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5730 || h->root.type != bfd_link_hash_undefweak);
5732 BFD_ASSERT (globals->root.srelgot != NULL);
5733 BFD_ASSERT (globals->root.sgot != NULL);
5738 Elf_Internal_Rela rela;
5739 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
5742 rela.r_offset = (globals->root.sgotplt->output_section->vma
5743 + globals->root.sgotplt->output_offset
5744 + off + globals->sgotplt_jump_table_size);
5747 rela.r_addend = relocation - dtpoff_base (info);
5749 /* Allocate the next available slot in the PLT reloc
5750 section to hold our R_AARCH64_TLSDESC, the next
5751 available slot is determined from reloc_count,
5752 which we step. But note, reloc_count was
5753 artifically moved down while allocating slots for
5754 real PLT relocs such that all of the PLT relocs
5755 will fit above the initial reloc_count and the
5756 extra stuff will fit below. */
5757 loc = globals->root.srelplt->contents;
5758 loc += globals->root.srelplt->reloc_count++
5759 * RELOC_SIZE (globals);
5761 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
5763 bfd_put_NN (output_bfd, (bfd_vma) 0,
5764 globals->root.sgotplt->contents + off +
5765 globals->sgotplt_jump_table_size);
5766 bfd_put_NN (output_bfd, (bfd_vma) 0,
5767 globals->root.sgotplt->contents + off +
5768 globals->sgotplt_jump_table_size +
5772 symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
5783 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
5784 because such sections are not SEC_ALLOC and thus ld.so will
5785 not process them. */
5786 if (unresolved_reloc
5787 && !((input_section->flags & SEC_DEBUGGING) != 0
5789 && _bfd_elf_section_offset (output_bfd, info, input_section,
5790 +rel->r_offset) != (bfd_vma) - 1)
5792 (*_bfd_error_handler)
5794 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
5795 input_bfd, input_section, (long) rel->r_offset, howto->name,
5796 h->root.root.string);
5800 if (r != bfd_reloc_ok && r != bfd_reloc_continue)
5802 bfd_reloc_code_real_type real_r_type
5803 = elfNN_aarch64_bfd_reloc_from_type (r_type);
5807 case bfd_reloc_overflow:
5808 if (!(*info->callbacks->reloc_overflow)
5809 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
5810 input_bfd, input_section, rel->r_offset))
5812 if (real_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5813 || real_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
5815 (*info->callbacks->warning)
5817 _("Too many GOT entries for -fpic, "
5818 "please recompile with -fPIC"),
5819 name, input_bfd, input_section, rel->r_offset);
5824 case bfd_reloc_undefined:
5825 if (!((*info->callbacks->undefined_symbol)
5826 (info, name, input_bfd, input_section,
5827 rel->r_offset, TRUE)))
5831 case bfd_reloc_outofrange:
5832 error_message = _("out of range");
5835 case bfd_reloc_notsupported:
5836 error_message = _("unsupported relocation");
5839 case bfd_reloc_dangerous:
5840 /* error_message should already be set. */
5844 error_message = _("unknown error");
5848 BFD_ASSERT (error_message != NULL);
5849 if (!((*info->callbacks->reloc_dangerous)
5850 (info, error_message, input_bfd, input_section,
5861 /* Set the right machine number. */
5864 elfNN_aarch64_object_p (bfd *abfd)
5867 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64_ilp32);
5869 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64);
5874 /* Function to keep AArch64 specific flags in the ELF header. */
5877 elfNN_aarch64_set_private_flags (bfd *abfd, flagword flags)
5879 if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
5884 elf_elfheader (abfd)->e_flags = flags;
5885 elf_flags_init (abfd) = TRUE;
5891 /* Merge backend specific data from an object file to the output
5892 object file when linking. */
5895 elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
5899 bfd_boolean flags_compatible = TRUE;
5902 /* Check if we have the same endianess. */
5903 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
5906 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
5909 /* The input BFD must have had its flags initialised. */
5910 /* The following seems bogus to me -- The flags are initialized in
5911 the assembler but I don't think an elf_flags_init field is
5912 written into the object. */
5913 /* BFD_ASSERT (elf_flags_init (ibfd)); */
5915 in_flags = elf_elfheader (ibfd)->e_flags;
5916 out_flags = elf_elfheader (obfd)->e_flags;
5918 if (!elf_flags_init (obfd))
5920 /* If the input is the default architecture and had the default
5921 flags then do not bother setting the flags for the output
5922 architecture, instead allow future merges to do this. If no
5923 future merges ever set these flags then they will retain their
5924 uninitialised values, which surprise surprise, correspond
5925 to the default values. */
5926 if (bfd_get_arch_info (ibfd)->the_default
5927 && elf_elfheader (ibfd)->e_flags == 0)
5930 elf_flags_init (obfd) = TRUE;
5931 elf_elfheader (obfd)->e_flags = in_flags;
5933 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5934 && bfd_get_arch_info (obfd)->the_default)
5935 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5936 bfd_get_mach (ibfd));
5941 /* Identical flags must be compatible. */
5942 if (in_flags == out_flags)
5945 /* Check to see if the input BFD actually contains any sections. If
5946 not, its flags may not have been initialised either, but it
5947 cannot actually cause any incompatiblity. Do not short-circuit
5948 dynamic objects; their section list may be emptied by
5949 elf_link_add_object_symbols.
5951 Also check to see if there are no code sections in the input.
5952 In this case there is no need to check for code specific flags.
5953 XXX - do we need to worry about floating-point format compatability
5954 in data sections ? */
5955 if (!(ibfd->flags & DYNAMIC))
5957 bfd_boolean null_input_bfd = TRUE;
5958 bfd_boolean only_data_sections = TRUE;
5960 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
5962 if ((bfd_get_section_flags (ibfd, sec)
5963 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
5964 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
5965 only_data_sections = FALSE;
5967 null_input_bfd = FALSE;
5971 if (null_input_bfd || only_data_sections)
5975 return flags_compatible;
5978 /* Display the flags field. */
5981 elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
5983 FILE *file = (FILE *) ptr;
5984 unsigned long flags;
5986 BFD_ASSERT (abfd != NULL && ptr != NULL);
5988 /* Print normal ELF private data. */
5989 _bfd_elf_print_private_bfd_data (abfd, ptr);
5991 flags = elf_elfheader (abfd)->e_flags;
5992 /* Ignore init flag - it may not be set, despite the flags field
5993 containing valid data. */
5995 /* xgettext:c-format */
5996 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
5999 fprintf (file, _("<Unrecognised flag bits set>"));
6006 /* Update the got entry reference counts for the section being removed. */
6009 elfNN_aarch64_gc_sweep_hook (bfd *abfd,
6010 struct bfd_link_info *info,
6012 const Elf_Internal_Rela * relocs)
6014 struct elf_aarch64_link_hash_table *htab;
6015 Elf_Internal_Shdr *symtab_hdr;
6016 struct elf_link_hash_entry **sym_hashes;
6017 struct elf_aarch64_local_symbol *locals;
6018 const Elf_Internal_Rela *rel, *relend;
6020 if (bfd_link_relocatable (info))
6023 htab = elf_aarch64_hash_table (info);
6028 elf_section_data (sec)->local_dynrel = NULL;
6030 symtab_hdr = &elf_symtab_hdr (abfd);
6031 sym_hashes = elf_sym_hashes (abfd);
6033 locals = elf_aarch64_locals (abfd);
6035 relend = relocs + sec->reloc_count;
6036 for (rel = relocs; rel < relend; rel++)
6038 unsigned long r_symndx;
6039 unsigned int r_type;
6040 struct elf_link_hash_entry *h = NULL;
6042 r_symndx = ELFNN_R_SYM (rel->r_info);
6044 if (r_symndx >= symtab_hdr->sh_info)
6047 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
6048 while (h->root.type == bfd_link_hash_indirect
6049 || h->root.type == bfd_link_hash_warning)
6050 h = (struct elf_link_hash_entry *) h->root.u.i.link;
6054 Elf_Internal_Sym *isym;
6056 /* A local symbol. */
6057 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
6060 /* Check relocation against local STT_GNU_IFUNC symbol. */
6062 && ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
6064 h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel, FALSE);
6072 struct elf_aarch64_link_hash_entry *eh;
6073 struct elf_dyn_relocs **pp;
6074 struct elf_dyn_relocs *p;
6076 eh = (struct elf_aarch64_link_hash_entry *) h;
6078 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
6081 /* Everything must go for SEC. */
6087 r_type = ELFNN_R_TYPE (rel->r_info);
6088 switch (aarch64_tls_transition (abfd,info, r_type, h ,r_symndx))
6090 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
6091 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
6092 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
6093 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
6094 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
6095 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
6096 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
6097 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
6098 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
6099 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
6100 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
6101 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
6102 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
6103 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
6104 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
6105 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
6106 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
6107 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
6108 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
6109 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
6110 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
6111 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
6114 if (h->got.refcount > 0)
6115 h->got.refcount -= 1;
6117 if (h->type == STT_GNU_IFUNC)
6119 if (h->plt.refcount > 0)
6120 h->plt.refcount -= 1;
6123 else if (locals != NULL)
6125 if (locals[r_symndx].got_refcount > 0)
6126 locals[r_symndx].got_refcount -= 1;
6130 case BFD_RELOC_AARCH64_CALL26:
6131 case BFD_RELOC_AARCH64_JUMP26:
6132 /* If this is a local symbol then we resolve it
6133 directly without creating a PLT entry. */
6137 if (h->plt.refcount > 0)
6138 h->plt.refcount -= 1;
6141 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
6142 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
6143 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
6144 case BFD_RELOC_AARCH64_MOVW_G0_NC:
6145 case BFD_RELOC_AARCH64_MOVW_G1_NC:
6146 case BFD_RELOC_AARCH64_MOVW_G2_NC:
6147 case BFD_RELOC_AARCH64_MOVW_G3:
6148 case BFD_RELOC_AARCH64_NN:
6149 if (h != NULL && bfd_link_executable (info))
6151 if (h->plt.refcount > 0)
6152 h->plt.refcount -= 1;
6164 /* Adjust a symbol defined by a dynamic object and referenced by a
6165 regular object. The current definition is in some section of the
6166 dynamic object, but we're not including those sections. We have to
6167 change the definition to something the rest of the link can
6171 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
6172 struct elf_link_hash_entry *h)
6174 struct elf_aarch64_link_hash_table *htab;
6177 /* If this is a function, put it in the procedure linkage table. We
6178 will fill in the contents of the procedure linkage table later,
6179 when we know the address of the .got section. */
6180 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
6182 if (h->plt.refcount <= 0
6183 || (h->type != STT_GNU_IFUNC
6184 && (SYMBOL_CALLS_LOCAL (info, h)
6185 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
6186 && h->root.type == bfd_link_hash_undefweak))))
6188 /* This case can occur if we saw a CALL26 reloc in
6189 an input file, but the symbol wasn't referred to
6190 by a dynamic object or all references were
6191 garbage collected. In which case we can end up
6193 h->plt.offset = (bfd_vma) - 1;
6200 /* Otherwise, reset to -1. */
6201 h->plt.offset = (bfd_vma) - 1;
6204 /* If this is a weak symbol, and there is a real definition, the
6205 processor independent code will have arranged for us to see the
6206 real definition first, and we can just use the same value. */
6207 if (h->u.weakdef != NULL)
6209 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
6210 || h->u.weakdef->root.type == bfd_link_hash_defweak);
6211 h->root.u.def.section = h->u.weakdef->root.u.def.section;
6212 h->root.u.def.value = h->u.weakdef->root.u.def.value;
6213 if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
6214 h->non_got_ref = h->u.weakdef->non_got_ref;
6218 /* If we are creating a shared library, we must presume that the
6219 only references to the symbol are via the global offset table.
6220 For such cases we need not do anything here; the relocations will
6221 be handled correctly by relocate_section. */
6222 if (bfd_link_pic (info))
6225 /* If there are no references to this symbol that do not use the
6226 GOT, we don't need to generate a copy reloc. */
6227 if (!h->non_got_ref)
6230 /* If -z nocopyreloc was given, we won't generate them either. */
6231 if (info->nocopyreloc)
6237 /* We must allocate the symbol in our .dynbss section, which will
6238 become part of the .bss section of the executable. There will be
6239 an entry for this symbol in the .dynsym section. The dynamic
6240 object will contain position independent code, so all references
6241 from the dynamic object to this symbol will go through the global
6242 offset table. The dynamic linker will use the .dynsym entry to
6243 determine the address it must put in the global offset table, so
6244 both the dynamic object and the regular object will refer to the
6245 same memory location for the variable. */
6247 htab = elf_aarch64_hash_table (info);
6249 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
6250 to copy the initial value out of the dynamic object and into the
6251 runtime process image. */
6252 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
6254 htab->srelbss->size += RELOC_SIZE (htab);
6260 return _bfd_elf_adjust_dynamic_copy (info, h, s);
6265 elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
6267 struct elf_aarch64_local_symbol *locals;
6268 locals = elf_aarch64_locals (abfd);
6271 locals = (struct elf_aarch64_local_symbol *)
6272 bfd_zalloc (abfd, number * sizeof (struct elf_aarch64_local_symbol));
6275 elf_aarch64_locals (abfd) = locals;
6280 /* Create the .got section to hold the global offset table. */
6283 aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
6285 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
6288 struct elf_link_hash_entry *h;
6289 struct elf_link_hash_table *htab = elf_hash_table (info);
6291 /* This function may be called more than once. */
6292 s = bfd_get_linker_section (abfd, ".got");
6296 flags = bed->dynamic_sec_flags;
6298 s = bfd_make_section_anyway_with_flags (abfd,
6299 (bed->rela_plts_and_copies_p
6300 ? ".rela.got" : ".rel.got"),
6301 (bed->dynamic_sec_flags
6304 || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
6308 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
6310 || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
6313 htab->sgot->size += GOT_ENTRY_SIZE;
6315 if (bed->want_got_sym)
6317 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
6318 (or .got.plt) section. We don't do this in the linker script
6319 because we don't want to define the symbol if we are not creating
6320 a global offset table. */
6321 h = _bfd_elf_define_linkage_sym (abfd, info, s,
6322 "_GLOBAL_OFFSET_TABLE_");
6323 elf_hash_table (info)->hgot = h;
6328 if (bed->want_got_plt)
6330 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
6332 || !bfd_set_section_alignment (abfd, s,
6333 bed->s->log_file_align))
6338 /* The first bit of the global offset table is the header. */
6339 s->size += bed->got_header_size;
6344 /* Look through the relocs for a section during the first phase. */
6347 elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
6348 asection *sec, const Elf_Internal_Rela *relocs)
6350 Elf_Internal_Shdr *symtab_hdr;
6351 struct elf_link_hash_entry **sym_hashes;
6352 const Elf_Internal_Rela *rel;
6353 const Elf_Internal_Rela *rel_end;
6356 struct elf_aarch64_link_hash_table *htab;
6358 if (bfd_link_relocatable (info))
6361 BFD_ASSERT (is_aarch64_elf (abfd));
6363 htab = elf_aarch64_hash_table (info);
6366 symtab_hdr = &elf_symtab_hdr (abfd);
6367 sym_hashes = elf_sym_hashes (abfd);
6369 rel_end = relocs + sec->reloc_count;
6370 for (rel = relocs; rel < rel_end; rel++)
6372 struct elf_link_hash_entry *h;
6373 unsigned long r_symndx;
6374 unsigned int r_type;
6375 bfd_reloc_code_real_type bfd_r_type;
6376 Elf_Internal_Sym *isym;
6378 r_symndx = ELFNN_R_SYM (rel->r_info);
6379 r_type = ELFNN_R_TYPE (rel->r_info);
6381 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
6383 (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
6388 if (r_symndx < symtab_hdr->sh_info)
6390 /* A local symbol. */
6391 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
6396 /* Check relocation against local STT_GNU_IFUNC symbol. */
6397 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
6399 h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel,
6404 /* Fake a STT_GNU_IFUNC symbol. */
6405 h->type = STT_GNU_IFUNC;
6408 h->forced_local = 1;
6409 h->root.type = bfd_link_hash_defined;
6416 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
6417 while (h->root.type == bfd_link_hash_indirect
6418 || h->root.type == bfd_link_hash_warning)
6419 h = (struct elf_link_hash_entry *) h->root.u.i.link;
6421 /* PR15323, ref flags aren't set for references in the same
6423 h->root.non_ir_ref = 1;
6426 /* Could be done earlier, if h were already available. */
6427 bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
6431 /* Create the ifunc sections for static executables. If we
6432 never see an indirect function symbol nor we are building
6433 a static executable, those sections will be empty and
6434 won't appear in output. */
6440 case BFD_RELOC_AARCH64_ADD_LO12:
6441 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
6442 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
6443 case BFD_RELOC_AARCH64_CALL26:
6444 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
6445 case BFD_RELOC_AARCH64_JUMP26:
6446 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
6447 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
6448 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
6449 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
6450 case BFD_RELOC_AARCH64_NN:
6451 if (htab->root.dynobj == NULL)
6452 htab->root.dynobj = abfd;
6453 if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
6458 /* It is referenced by a non-shared object. */
6460 h->root.non_ir_ref = 1;
6465 case BFD_RELOC_AARCH64_NN:
6467 /* We don't need to handle relocs into sections not going into
6468 the "real" output. */
6469 if ((sec->flags & SEC_ALLOC) == 0)
6474 if (!bfd_link_pic (info))
6477 h->plt.refcount += 1;
6478 h->pointer_equality_needed = 1;
6481 /* No need to do anything if we're not creating a shared
6483 if (! bfd_link_pic (info))
6487 struct elf_dyn_relocs *p;
6488 struct elf_dyn_relocs **head;
6490 /* We must copy these reloc types into the output file.
6491 Create a reloc section in dynobj and make room for
6495 if (htab->root.dynobj == NULL)
6496 htab->root.dynobj = abfd;
6498 sreloc = _bfd_elf_make_dynamic_reloc_section
6499 (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ TRUE);
6505 /* If this is a global symbol, we count the number of
6506 relocations we need for this symbol. */
6509 struct elf_aarch64_link_hash_entry *eh;
6510 eh = (struct elf_aarch64_link_hash_entry *) h;
6511 head = &eh->dyn_relocs;
6515 /* Track dynamic relocs needed for local syms too.
6516 We really need local syms available to do this
6522 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
6527 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
6531 /* Beware of type punned pointers vs strict aliasing
6533 vpp = &(elf_section_data (s)->local_dynrel);
6534 head = (struct elf_dyn_relocs **) vpp;
6538 if (p == NULL || p->sec != sec)
6540 bfd_size_type amt = sizeof *p;
6541 p = ((struct elf_dyn_relocs *)
6542 bfd_zalloc (htab->root.dynobj, amt));
6555 /* RR: We probably want to keep a consistency check that
6556 there are no dangling GOT_PAGE relocs. */
6557 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
6558 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
6559 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
6560 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
6561 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
6562 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
6563 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
6564 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
6565 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
6566 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
6567 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
6568 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
6569 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
6570 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
6571 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
6572 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
6573 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
6574 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
6575 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
6576 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
6577 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
6578 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
6581 unsigned old_got_type;
6583 got_type = aarch64_reloc_got_type (bfd_r_type);
6587 h->got.refcount += 1;
6588 old_got_type = elf_aarch64_hash_entry (h)->got_type;
6592 struct elf_aarch64_local_symbol *locals;
6594 if (!elfNN_aarch64_allocate_local_symbols
6595 (abfd, symtab_hdr->sh_info))
6598 locals = elf_aarch64_locals (abfd);
6599 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
6600 locals[r_symndx].got_refcount += 1;
6601 old_got_type = locals[r_symndx].got_type;
6604 /* If a variable is accessed with both general dynamic TLS
6605 methods, two slots may be created. */
6606 if (GOT_TLS_GD_ANY_P (old_got_type) && GOT_TLS_GD_ANY_P (got_type))
6607 got_type |= old_got_type;
6609 /* We will already have issued an error message if there
6610 is a TLS/non-TLS mismatch, based on the symbol type.
6611 So just combine any TLS types needed. */
6612 if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
6613 && got_type != GOT_NORMAL)
6614 got_type |= old_got_type;
6616 /* If the symbol is accessed by both IE and GD methods, we
6617 are able to relax. Turn off the GD flag, without
6618 messing up with any other kind of TLS types that may be
6620 if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
6621 got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
6623 if (old_got_type != got_type)
6626 elf_aarch64_hash_entry (h)->got_type = got_type;
6629 struct elf_aarch64_local_symbol *locals;
6630 locals = elf_aarch64_locals (abfd);
6631 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
6632 locals[r_symndx].got_type = got_type;
6636 if (htab->root.dynobj == NULL)
6637 htab->root.dynobj = abfd;
6638 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
6643 case BFD_RELOC_AARCH64_MOVW_G0_NC:
6644 case BFD_RELOC_AARCH64_MOVW_G1_NC:
6645 case BFD_RELOC_AARCH64_MOVW_G2_NC:
6646 case BFD_RELOC_AARCH64_MOVW_G3:
6647 if (bfd_link_pic (info))
6649 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
6650 (*_bfd_error_handler)
6651 (_("%B: relocation %s against `%s' can not be used when making "
6652 "a shared object; recompile with -fPIC"),
6653 abfd, elfNN_aarch64_howto_table[howto_index].name,
6654 (h) ? h->root.root.string : "a local symbol");
6655 bfd_set_error (bfd_error_bad_value);
6659 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
6660 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
6661 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
6662 if (h != NULL && bfd_link_executable (info))
6664 /* If this reloc is in a read-only section, we might
6665 need a copy reloc. We can't check reliably at this
6666 stage whether the section is read-only, as input
6667 sections have not yet been mapped to output sections.
6668 Tentatively set the flag for now, and correct in
6669 adjust_dynamic_symbol. */
6671 h->plt.refcount += 1;
6672 h->pointer_equality_needed = 1;
6674 /* FIXME:: RR need to handle these in shared libraries
6675 and essentially bomb out as these being non-PIC
6676 relocations in shared libraries. */
6679 case BFD_RELOC_AARCH64_CALL26:
6680 case BFD_RELOC_AARCH64_JUMP26:
6681 /* If this is a local symbol then we resolve it
6682 directly without creating a PLT entry. */
6687 if (h->plt.refcount <= 0)
6688 h->plt.refcount = 1;
6690 h->plt.refcount += 1;
6701 /* Treat mapping symbols as special target symbols. */
6704 elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED,
6707 return bfd_is_aarch64_special_symbol_name (sym->name,
6708 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
6711 /* This is a copy of elf_find_function () from elf.c except that
6712 AArch64 mapping symbols are ignored when looking for function names. */
6715 aarch64_elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
6719 const char **filename_ptr,
6720 const char **functionname_ptr)
6722 const char *filename = NULL;
6723 asymbol *func = NULL;
6724 bfd_vma low_func = 0;
6727 for (p = symbols; *p != NULL; p++)
6731 q = (elf_symbol_type *) * p;
6733 switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
6738 filename = bfd_asymbol_name (&q->symbol);
6742 /* Skip mapping symbols. */
6743 if ((q->symbol.flags & BSF_LOCAL)
6744 && (bfd_is_aarch64_special_symbol_name
6745 (q->symbol.name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)))
6748 if (bfd_get_section (&q->symbol) == section
6749 && q->symbol.value >= low_func && q->symbol.value <= offset)
6751 func = (asymbol *) q;
6752 low_func = q->symbol.value;
6762 *filename_ptr = filename;
6763 if (functionname_ptr)
6764 *functionname_ptr = bfd_asymbol_name (func);
6770 /* Find the nearest line to a particular section and offset, for error
6771 reporting. This code is a duplicate of the code in elf.c, except
6772 that it uses aarch64_elf_find_function. */
6775 elfNN_aarch64_find_nearest_line (bfd *abfd,
6779 const char **filename_ptr,
6780 const char **functionname_ptr,
6781 unsigned int *line_ptr,
6782 unsigned int *discriminator_ptr)
6784 bfd_boolean found = FALSE;
6786 if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
6787 filename_ptr, functionname_ptr,
6788 line_ptr, discriminator_ptr,
6789 dwarf_debug_sections, 0,
6790 &elf_tdata (abfd)->dwarf2_find_line_info))
6792 if (!*functionname_ptr)
6793 aarch64_elf_find_function (abfd, symbols, section, offset,
6794 *filename_ptr ? NULL : filename_ptr,
6800 /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
6801 toolchain uses DWARF1. */
6803 if (!_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
6804 &found, filename_ptr,
6805 functionname_ptr, line_ptr,
6806 &elf_tdata (abfd)->line_info))
6809 if (found && (*functionname_ptr || *line_ptr))
6812 if (symbols == NULL)
6815 if (!aarch64_elf_find_function (abfd, symbols, section, offset,
6816 filename_ptr, functionname_ptr))
6824 elfNN_aarch64_find_inliner_info (bfd *abfd,
6825 const char **filename_ptr,
6826 const char **functionname_ptr,
6827 unsigned int *line_ptr)
6830 found = _bfd_dwarf2_find_inliner_info
6831 (abfd, filename_ptr,
6832 functionname_ptr, line_ptr, &elf_tdata (abfd)->dwarf2_find_line_info);
6838 elfNN_aarch64_post_process_headers (bfd *abfd,
6839 struct bfd_link_info *link_info)
6841 Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
6843 i_ehdrp = elf_elfheader (abfd);
6844 i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
6846 _bfd_elf_post_process_headers (abfd, link_info);
6849 static enum elf_reloc_type_class
6850 elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
6851 const asection *rel_sec ATTRIBUTE_UNUSED,
6852 const Elf_Internal_Rela *rela)
6854 switch ((int) ELFNN_R_TYPE (rela->r_info))
6856 case AARCH64_R (RELATIVE):
6857 return reloc_class_relative;
6858 case AARCH64_R (JUMP_SLOT):
6859 return reloc_class_plt;
6860 case AARCH64_R (COPY):
6861 return reloc_class_copy;
6863 return reloc_class_normal;
6867 /* Handle an AArch64 specific section when reading an object file. This is
6868 called when bfd_section_from_shdr finds a section with an unknown
6872 elfNN_aarch64_section_from_shdr (bfd *abfd,
6873 Elf_Internal_Shdr *hdr,
6874 const char *name, int shindex)
6876 /* There ought to be a place to keep ELF backend specific flags, but
6877 at the moment there isn't one. We just keep track of the
6878 sections by their name, instead. Fortunately, the ABI gives
6879 names for all the AArch64 specific sections, so we will probably get
6881 switch (hdr->sh_type)
6883 case SHT_AARCH64_ATTRIBUTES:
6890 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
6896 /* A structure used to record a list of sections, independently
6897 of the next and prev fields in the asection structure. */
6898 typedef struct section_list
6901 struct section_list *next;
6902 struct section_list *prev;
6906 /* Unfortunately we need to keep a list of sections for which
6907 an _aarch64_elf_section_data structure has been allocated. This
6908 is because it is possible for functions like elfNN_aarch64_write_section
6909 to be called on a section which has had an elf_data_structure
6910 allocated for it (and so the used_by_bfd field is valid) but
6911 for which the AArch64 extended version of this structure - the
6912 _aarch64_elf_section_data structure - has not been allocated. */
6913 static section_list *sections_with_aarch64_elf_section_data = NULL;
6916 record_section_with_aarch64_elf_section_data (asection *sec)
6918 struct section_list *entry;
6920 entry = bfd_malloc (sizeof (*entry));
6924 entry->next = sections_with_aarch64_elf_section_data;
6926 if (entry->next != NULL)
6927 entry->next->prev = entry;
6928 sections_with_aarch64_elf_section_data = entry;
6931 static struct section_list *
6932 find_aarch64_elf_section_entry (asection *sec)
6934 struct section_list *entry;
6935 static struct section_list *last_entry = NULL;
6937 /* This is a short cut for the typical case where the sections are added
6938 to the sections_with_aarch64_elf_section_data list in forward order and
6939 then looked up here in backwards order. This makes a real difference
6940 to the ld-srec/sec64k.exp linker test. */
6941 entry = sections_with_aarch64_elf_section_data;
6942 if (last_entry != NULL)
6944 if (last_entry->sec == sec)
6946 else if (last_entry->next != NULL && last_entry->next->sec == sec)
6947 entry = last_entry->next;
6950 for (; entry; entry = entry->next)
6951 if (entry->sec == sec)
6955 /* Record the entry prior to this one - it is the entry we are
6956 most likely to want to locate next time. Also this way if we
6957 have been called from
6958 unrecord_section_with_aarch64_elf_section_data () we will not
6959 be caching a pointer that is about to be freed. */
6960 last_entry = entry->prev;
6966 unrecord_section_with_aarch64_elf_section_data (asection *sec)
6968 struct section_list *entry;
6970 entry = find_aarch64_elf_section_entry (sec);
6974 if (entry->prev != NULL)
6975 entry->prev->next = entry->next;
6976 if (entry->next != NULL)
6977 entry->next->prev = entry->prev;
6978 if (entry == sections_with_aarch64_elf_section_data)
6979 sections_with_aarch64_elf_section_data = entry->next;
6988 struct bfd_link_info *info;
6991 int (*func) (void *, const char *, Elf_Internal_Sym *,
6992 asection *, struct elf_link_hash_entry *);
6993 } output_arch_syminfo;
6995 enum map_symbol_type
7002 /* Output a single mapping symbol. */
7005 elfNN_aarch64_output_map_sym (output_arch_syminfo *osi,
7006 enum map_symbol_type type, bfd_vma offset)
7008 static const char *names[2] = { "$x", "$d" };
7009 Elf_Internal_Sym sym;
7011 sym.st_value = (osi->sec->output_section->vma
7012 + osi->sec->output_offset + offset);
7015 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
7016 sym.st_shndx = osi->sec_shndx;
7017 return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
7022 /* Output mapping symbols for PLT entries associated with H. */
7025 elfNN_aarch64_output_plt_map (struct elf_link_hash_entry *h, void *inf)
7027 output_arch_syminfo *osi = (output_arch_syminfo *) inf;
7030 if (h->root.type == bfd_link_hash_indirect)
7033 if (h->root.type == bfd_link_hash_warning)
7034 /* When warning symbols are created, they **replace** the "real"
7035 entry in the hash table, thus we never get to see the real
7036 symbol in a hash traversal. So look at it now. */
7037 h = (struct elf_link_hash_entry *) h->root.u.i.link;
7039 if (h->plt.offset == (bfd_vma) - 1)
7042 addr = h->plt.offset;
7045 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
7052 /* Output a single local symbol for a generated stub. */
7055 elfNN_aarch64_output_stub_sym (output_arch_syminfo *osi, const char *name,
7056 bfd_vma offset, bfd_vma size)
7058 Elf_Internal_Sym sym;
7060 sym.st_value = (osi->sec->output_section->vma
7061 + osi->sec->output_offset + offset);
7064 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
7065 sym.st_shndx = osi->sec_shndx;
7066 return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
7070 aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
7072 struct elf_aarch64_stub_hash_entry *stub_entry;
7076 output_arch_syminfo *osi;
7078 /* Massage our args to the form they really have. */
7079 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
7080 osi = (output_arch_syminfo *) in_arg;
7082 stub_sec = stub_entry->stub_sec;
7084 /* Ensure this stub is attached to the current section being
7086 if (stub_sec != osi->sec)
7089 addr = (bfd_vma) stub_entry->stub_offset;
7091 stub_name = stub_entry->output_name;
7093 switch (stub_entry->stub_type)
7095 case aarch64_stub_adrp_branch:
7096 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
7097 sizeof (aarch64_adrp_branch_stub)))
7099 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
7102 case aarch64_stub_long_branch:
7103 if (!elfNN_aarch64_output_stub_sym
7104 (osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
7106 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
7108 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_DATA, addr + 16))
7111 case aarch64_stub_erratum_835769_veneer:
7112 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
7113 sizeof (aarch64_erratum_835769_stub)))
7115 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
7118 case aarch64_stub_erratum_843419_veneer:
7119 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
7120 sizeof (aarch64_erratum_843419_stub)))
7122 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
7133 /* Output mapping symbols for linker generated sections. */
7136 elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
7137 struct bfd_link_info *info,
7139 int (*func) (void *, const char *,
7142 struct elf_link_hash_entry
7145 output_arch_syminfo osi;
7146 struct elf_aarch64_link_hash_table *htab;
7148 htab = elf_aarch64_hash_table (info);
7154 /* Long calls stubs. */
7155 if (htab->stub_bfd && htab->stub_bfd->sections)
7159 for (stub_sec = htab->stub_bfd->sections;
7160 stub_sec != NULL; stub_sec = stub_sec->next)
7162 /* Ignore non-stub sections. */
7163 if (!strstr (stub_sec->name, STUB_SUFFIX))
7168 osi.sec_shndx = _bfd_elf_section_from_bfd_section
7169 (output_bfd, osi.sec->output_section);
7171 /* The first instruction in a stub is always a branch. */
7172 if (!elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0))
7175 bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
7180 /* Finally, output mapping symbols for the PLT. */
7181 if (!htab->root.splt || htab->root.splt->size == 0)
7184 /* For now live without mapping symbols for the plt. */
7185 osi.sec_shndx = _bfd_elf_section_from_bfd_section
7186 (output_bfd, htab->root.splt->output_section);
7187 osi.sec = htab->root.splt;
7189 elf_link_hash_traverse (&htab->root, elfNN_aarch64_output_plt_map,
7196 /* Allocate target specific section data. */
7199 elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec)
7201 if (!sec->used_by_bfd)
7203 _aarch64_elf_section_data *sdata;
7204 bfd_size_type amt = sizeof (*sdata);
7206 sdata = bfd_zalloc (abfd, amt);
7209 sec->used_by_bfd = sdata;
7212 record_section_with_aarch64_elf_section_data (sec);
7214 return _bfd_elf_new_section_hook (abfd, sec);
7219 unrecord_section_via_map_over_sections (bfd *abfd ATTRIBUTE_UNUSED,
7221 void *ignore ATTRIBUTE_UNUSED)
7223 unrecord_section_with_aarch64_elf_section_data (sec);
7227 elfNN_aarch64_close_and_cleanup (bfd *abfd)
7230 bfd_map_over_sections (abfd,
7231 unrecord_section_via_map_over_sections, NULL);
7233 return _bfd_elf_close_and_cleanup (abfd);
7237 elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
7240 bfd_map_over_sections (abfd,
7241 unrecord_section_via_map_over_sections, NULL);
7243 return _bfd_free_cached_info (abfd);
7246 /* Create dynamic sections. This is different from the ARM backend in that
7247 the got, plt, gotplt and their relocation sections are all created in the
7248 standard part of the bfd elf backend. */
7251 elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
7252 struct bfd_link_info *info)
7254 struct elf_aarch64_link_hash_table *htab;
7256 /* We need to create .got section. */
7257 if (!aarch64_elf_create_got_section (dynobj, info))
7260 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
7263 htab = elf_aarch64_hash_table (info);
7264 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
7265 if (!bfd_link_pic (info))
7266 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
7268 if (!htab->sdynbss || (!bfd_link_pic (info) && !htab->srelbss))
7275 /* Allocate space in .plt, .got and associated reloc sections for
7279 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
7281 struct bfd_link_info *info;
7282 struct elf_aarch64_link_hash_table *htab;
7283 struct elf_aarch64_link_hash_entry *eh;
7284 struct elf_dyn_relocs *p;
7286 /* An example of a bfd_link_hash_indirect symbol is versioned
7287 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7288 -> __gxx_personality_v0(bfd_link_hash_defined)
7290 There is no need to process bfd_link_hash_indirect symbols here
7291 because we will also be presented with the concrete instance of
7292 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7293 called to copy all relevant data from the generic to the concrete
7296 if (h->root.type == bfd_link_hash_indirect)
7299 if (h->root.type == bfd_link_hash_warning)
7300 h = (struct elf_link_hash_entry *) h->root.u.i.link;
7302 info = (struct bfd_link_info *) inf;
7303 htab = elf_aarch64_hash_table (info);
7305 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7306 here if it is defined and referenced in a non-shared object. */
7307 if (h->type == STT_GNU_IFUNC
7310 else if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
7312 /* Make sure this symbol is output as a dynamic symbol.
7313 Undefined weak syms won't yet be marked as dynamic. */
7314 if (h->dynindx == -1 && !h->forced_local)
7316 if (!bfd_elf_link_record_dynamic_symbol (info, h))
7320 if (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
7322 asection *s = htab->root.splt;
7324 /* If this is the first .plt entry, make room for the special
7327 s->size += htab->plt_header_size;
7329 h->plt.offset = s->size;
7331 /* If this symbol is not defined in a regular file, and we are
7332 not generating a shared library, then set the symbol to this
7333 location in the .plt. This is required to make function
7334 pointers compare as equal between the normal executable and
7335 the shared library. */
7336 if (!bfd_link_pic (info) && !h->def_regular)
7338 h->root.u.def.section = s;
7339 h->root.u.def.value = h->plt.offset;
7342 /* Make room for this entry. For now we only create the
7343 small model PLT entries. We later need to find a way
7344 of relaxing into these from the large model PLT entries. */
7345 s->size += PLT_SMALL_ENTRY_SIZE;
7347 /* We also need to make an entry in the .got.plt section, which
7348 will be placed in the .got section by the linker script. */
7349 htab->root.sgotplt->size += GOT_ENTRY_SIZE;
7351 /* We also need to make an entry in the .rela.plt section. */
7352 htab->root.srelplt->size += RELOC_SIZE (htab);
7354 /* We need to ensure that all GOT entries that serve the PLT
7355 are consecutive with the special GOT slots [0] [1] and
7356 [2]. Any addtional relocations, such as
7357 R_AARCH64_TLSDESC, must be placed after the PLT related
7358 entries. We abuse the reloc_count such that during
7359 sizing we adjust reloc_count to indicate the number of
7360 PLT related reserved entries. In subsequent phases when
7361 filling in the contents of the reloc entries, PLT related
7362 entries are placed by computing their PLT index (0
7363 .. reloc_count). While other none PLT relocs are placed
7364 at the slot indicated by reloc_count and reloc_count is
7367 htab->root.srelplt->reloc_count++;
7371 h->plt.offset = (bfd_vma) - 1;
7377 h->plt.offset = (bfd_vma) - 1;
7381 eh = (struct elf_aarch64_link_hash_entry *) h;
7382 eh->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
7384 if (h->got.refcount > 0)
7387 unsigned got_type = elf_aarch64_hash_entry (h)->got_type;
7389 h->got.offset = (bfd_vma) - 1;
7391 dyn = htab->root.dynamic_sections_created;
7393 /* Make sure this symbol is output as a dynamic symbol.
7394 Undefined weak syms won't yet be marked as dynamic. */
7395 if (dyn && h->dynindx == -1 && !h->forced_local)
7397 if (!bfd_elf_link_record_dynamic_symbol (info, h))
7401 if (got_type == GOT_UNKNOWN)
7404 else if (got_type == GOT_NORMAL)
7406 h->got.offset = htab->root.sgot->size;
7407 htab->root.sgot->size += GOT_ENTRY_SIZE;
7408 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
7409 || h->root.type != bfd_link_hash_undefweak)
7410 && (bfd_link_pic (info)
7411 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
7413 htab->root.srelgot->size += RELOC_SIZE (htab);
7419 if (got_type & GOT_TLSDESC_GD)
7421 eh->tlsdesc_got_jump_table_offset =
7422 (htab->root.sgotplt->size
7423 - aarch64_compute_jump_table_size (htab));
7424 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
7425 h->got.offset = (bfd_vma) - 2;
7428 if (got_type & GOT_TLS_GD)
7430 h->got.offset = htab->root.sgot->size;
7431 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
7434 if (got_type & GOT_TLS_IE)
7436 h->got.offset = htab->root.sgot->size;
7437 htab->root.sgot->size += GOT_ENTRY_SIZE;
7440 indx = h && h->dynindx != -1 ? h->dynindx : 0;
7441 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
7442 || h->root.type != bfd_link_hash_undefweak)
7443 && (bfd_link_pic (info)
7445 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
7447 if (got_type & GOT_TLSDESC_GD)
7449 htab->root.srelplt->size += RELOC_SIZE (htab);
7450 /* Note reloc_count not incremented here! We have
7451 already adjusted reloc_count for this relocation
7454 /* TLSDESC PLT is now needed, but not yet determined. */
7455 htab->tlsdesc_plt = (bfd_vma) - 1;
7458 if (got_type & GOT_TLS_GD)
7459 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
7461 if (got_type & GOT_TLS_IE)
7462 htab->root.srelgot->size += RELOC_SIZE (htab);
7468 h->got.offset = (bfd_vma) - 1;
7471 if (eh->dyn_relocs == NULL)
7474 /* In the shared -Bsymbolic case, discard space allocated for
7475 dynamic pc-relative relocs against symbols which turn out to be
7476 defined in regular objects. For the normal shared case, discard
7477 space for pc-relative relocs that have become local due to symbol
7478 visibility changes. */
7480 if (bfd_link_pic (info))
7482 /* Relocs that use pc_count are those that appear on a call
7483 insn, or certain REL relocs that can generated via assembly.
7484 We want calls to protected symbols to resolve directly to the
7485 function rather than going via the plt. If people want
7486 function pointer comparisons to work as expected then they
7487 should avoid writing weird assembly. */
7488 if (SYMBOL_CALLS_LOCAL (info, h))
7490 struct elf_dyn_relocs **pp;
7492 for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
7494 p->count -= p->pc_count;
7503 /* Also discard relocs on undefined weak syms with non-default
7505 if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
7507 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
7508 eh->dyn_relocs = NULL;
7510 /* Make sure undefined weak symbols are output as a dynamic
7512 else if (h->dynindx == -1
7514 && !bfd_elf_link_record_dynamic_symbol (info, h))
7519 else if (ELIMINATE_COPY_RELOCS)
7521 /* For the non-shared case, discard space for relocs against
7522 symbols which turn out to need copy relocs or are not
7528 || (htab->root.dynamic_sections_created
7529 && (h->root.type == bfd_link_hash_undefweak
7530 || h->root.type == bfd_link_hash_undefined))))
7532 /* Make sure this symbol is output as a dynamic symbol.
7533 Undefined weak syms won't yet be marked as dynamic. */
7534 if (h->dynindx == -1
7536 && !bfd_elf_link_record_dynamic_symbol (info, h))
7539 /* If that succeeded, we know we'll be keeping all the
7541 if (h->dynindx != -1)
7545 eh->dyn_relocs = NULL;
7550 /* Finally, allocate space. */
7551 for (p = eh->dyn_relocs; p != NULL; p = p->next)
7555 sreloc = elf_section_data (p->sec)->sreloc;
7557 BFD_ASSERT (sreloc != NULL);
7559 sreloc->size += p->count * RELOC_SIZE (htab);
7565 /* Allocate space in .plt, .got and associated reloc sections for
7566 ifunc dynamic relocs. */
7569 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
7572 struct bfd_link_info *info;
7573 struct elf_aarch64_link_hash_table *htab;
7574 struct elf_aarch64_link_hash_entry *eh;
7576 /* An example of a bfd_link_hash_indirect symbol is versioned
7577 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7578 -> __gxx_personality_v0(bfd_link_hash_defined)
7580 There is no need to process bfd_link_hash_indirect symbols here
7581 because we will also be presented with the concrete instance of
7582 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7583 called to copy all relevant data from the generic to the concrete
7586 if (h->root.type == bfd_link_hash_indirect)
7589 if (h->root.type == bfd_link_hash_warning)
7590 h = (struct elf_link_hash_entry *) h->root.u.i.link;
7592 info = (struct bfd_link_info *) inf;
7593 htab = elf_aarch64_hash_table (info);
7595 eh = (struct elf_aarch64_link_hash_entry *) h;
7597 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7598 here if it is defined and referenced in a non-shared object. */
7599 if (h->type == STT_GNU_IFUNC
7601 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
7603 htab->plt_entry_size,
7604 htab->plt_header_size,
7609 /* Allocate space in .plt, .got and associated reloc sections for
7610 local dynamic relocs. */
7613 elfNN_aarch64_allocate_local_dynrelocs (void **slot, void *inf)
7615 struct elf_link_hash_entry *h
7616 = (struct elf_link_hash_entry *) *slot;
7618 if (h->type != STT_GNU_IFUNC
7622 || h->root.type != bfd_link_hash_defined)
7625 return elfNN_aarch64_allocate_dynrelocs (h, inf);
7628 /* Allocate space in .plt, .got and associated reloc sections for
7629 local ifunc dynamic relocs. */
7632 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
7634 struct elf_link_hash_entry *h
7635 = (struct elf_link_hash_entry *) *slot;
7637 if (h->type != STT_GNU_IFUNC
7641 || h->root.type != bfd_link_hash_defined)
7644 return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
7647 /* Find any dynamic relocs that apply to read-only sections. */
7650 aarch64_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
7652 struct elf_aarch64_link_hash_entry * eh;
7653 struct elf_dyn_relocs * p;
7655 eh = (struct elf_aarch64_link_hash_entry *) h;
7656 for (p = eh->dyn_relocs; p != NULL; p = p->next)
7658 asection *s = p->sec;
7660 if (s != NULL && (s->flags & SEC_READONLY) != 0)
7662 struct bfd_link_info *info = (struct bfd_link_info *) inf;
7664 info->flags |= DF_TEXTREL;
7666 /* Not an error, just cut short the traversal. */
7673 /* This is the most important function of all . Innocuosly named
7676 elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
7677 struct bfd_link_info *info)
7679 struct elf_aarch64_link_hash_table *htab;
7685 htab = elf_aarch64_hash_table ((info));
7686 dynobj = htab->root.dynobj;
7688 BFD_ASSERT (dynobj != NULL);
7690 if (htab->root.dynamic_sections_created)
7692 if (bfd_link_executable (info))
7694 s = bfd_get_linker_section (dynobj, ".interp");
7697 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
7698 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
7702 /* Set up .got offsets for local syms, and space for local dynamic
7704 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
7706 struct elf_aarch64_local_symbol *locals = NULL;
7707 Elf_Internal_Shdr *symtab_hdr;
7711 if (!is_aarch64_elf (ibfd))
7714 for (s = ibfd->sections; s != NULL; s = s->next)
7716 struct elf_dyn_relocs *p;
7718 for (p = (struct elf_dyn_relocs *)
7719 (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
7721 if (!bfd_is_abs_section (p->sec)
7722 && bfd_is_abs_section (p->sec->output_section))
7724 /* Input section has been discarded, either because
7725 it is a copy of a linkonce section or due to
7726 linker script /DISCARD/, so we'll be discarding
7729 else if (p->count != 0)
7731 srel = elf_section_data (p->sec)->sreloc;
7732 srel->size += p->count * RELOC_SIZE (htab);
7733 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
7734 info->flags |= DF_TEXTREL;
7739 locals = elf_aarch64_locals (ibfd);
7743 symtab_hdr = &elf_symtab_hdr (ibfd);
7744 srel = htab->root.srelgot;
7745 for (i = 0; i < symtab_hdr->sh_info; i++)
7747 locals[i].got_offset = (bfd_vma) - 1;
7748 locals[i].tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
7749 if (locals[i].got_refcount > 0)
7751 unsigned got_type = locals[i].got_type;
7752 if (got_type & GOT_TLSDESC_GD)
7754 locals[i].tlsdesc_got_jump_table_offset =
7755 (htab->root.sgotplt->size
7756 - aarch64_compute_jump_table_size (htab));
7757 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
7758 locals[i].got_offset = (bfd_vma) - 2;
7761 if (got_type & GOT_TLS_GD)
7763 locals[i].got_offset = htab->root.sgot->size;
7764 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
7767 if (got_type & GOT_TLS_IE
7768 || got_type & GOT_NORMAL)
7770 locals[i].got_offset = htab->root.sgot->size;
7771 htab->root.sgot->size += GOT_ENTRY_SIZE;
7774 if (got_type == GOT_UNKNOWN)
7778 if (bfd_link_pic (info))
7780 if (got_type & GOT_TLSDESC_GD)
7782 htab->root.srelplt->size += RELOC_SIZE (htab);
7783 /* Note RELOC_COUNT not incremented here! */
7784 htab->tlsdesc_plt = (bfd_vma) - 1;
7787 if (got_type & GOT_TLS_GD)
7788 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
7790 if (got_type & GOT_TLS_IE
7791 || got_type & GOT_NORMAL)
7792 htab->root.srelgot->size += RELOC_SIZE (htab);
7797 locals[i].got_refcount = (bfd_vma) - 1;
7803 /* Allocate global sym .plt and .got entries, and space for global
7804 sym dynamic relocs. */
7805 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
7808 /* Allocate global ifunc sym .plt and .got entries, and space for global
7809 ifunc sym dynamic relocs. */
7810 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_ifunc_dynrelocs,
7813 /* Allocate .plt and .got entries, and space for local symbols. */
7814 htab_traverse (htab->loc_hash_table,
7815 elfNN_aarch64_allocate_local_dynrelocs,
7818 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
7819 htab_traverse (htab->loc_hash_table,
7820 elfNN_aarch64_allocate_local_ifunc_dynrelocs,
7823 /* For every jump slot reserved in the sgotplt, reloc_count is
7824 incremented. However, when we reserve space for TLS descriptors,
7825 it's not incremented, so in order to compute the space reserved
7826 for them, it suffices to multiply the reloc count by the jump
7829 if (htab->root.srelplt)
7830 htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab);
7832 if (htab->tlsdesc_plt)
7834 if (htab->root.splt->size == 0)
7835 htab->root.splt->size += PLT_ENTRY_SIZE;
7837 htab->tlsdesc_plt = htab->root.splt->size;
7838 htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
7840 /* If we're not using lazy TLS relocations, don't generate the
7841 GOT entry required. */
7842 if (!(info->flags & DF_BIND_NOW))
7844 htab->dt_tlsdesc_got = htab->root.sgot->size;
7845 htab->root.sgot->size += GOT_ENTRY_SIZE;
7849 /* Init mapping symbols information to use later to distingush between
7850 code and data while scanning for errata. */
7851 if (htab->fix_erratum_835769 || htab->fix_erratum_843419)
7852 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
7854 if (!is_aarch64_elf (ibfd))
7856 bfd_elfNN_aarch64_init_maps (ibfd);
7859 /* We now have determined the sizes of the various dynamic sections.
7860 Allocate memory for them. */
7862 for (s = dynobj->sections; s != NULL; s = s->next)
7864 if ((s->flags & SEC_LINKER_CREATED) == 0)
7867 if (s == htab->root.splt
7868 || s == htab->root.sgot
7869 || s == htab->root.sgotplt
7870 || s == htab->root.iplt
7871 || s == htab->root.igotplt || s == htab->sdynbss)
7873 /* Strip this section if we don't need it; see the
7876 else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
7878 if (s->size != 0 && s != htab->root.srelplt)
7881 /* We use the reloc_count field as a counter if we need
7882 to copy relocs into the output file. */
7883 if (s != htab->root.srelplt)
7888 /* It's not one of our sections, so don't allocate space. */
7894 /* If we don't need this section, strip it from the
7895 output file. This is mostly to handle .rela.bss and
7896 .rela.plt. We must create both sections in
7897 create_dynamic_sections, because they must be created
7898 before the linker maps input sections to output
7899 sections. The linker does that before
7900 adjust_dynamic_symbol is called, and it is that
7901 function which decides whether anything needs to go
7902 into these sections. */
7904 s->flags |= SEC_EXCLUDE;
7908 if ((s->flags & SEC_HAS_CONTENTS) == 0)
7911 /* Allocate memory for the section contents. We use bfd_zalloc
7912 here in case unused entries are not reclaimed before the
7913 section's contents are written out. This should not happen,
7914 but this way if it does, we get a R_AARCH64_NONE reloc instead
7916 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
7917 if (s->contents == NULL)
7921 if (htab->root.dynamic_sections_created)
7923 /* Add some entries to the .dynamic section. We fill in the
7924 values later, in elfNN_aarch64_finish_dynamic_sections, but we
7925 must add the entries now so that we get the correct size for
7926 the .dynamic section. The DT_DEBUG entry is filled in by the
7927 dynamic linker and used by the debugger. */
7928 #define add_dynamic_entry(TAG, VAL) \
7929 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
7931 if (bfd_link_executable (info))
7933 if (!add_dynamic_entry (DT_DEBUG, 0))
7937 if (htab->root.splt->size != 0)
7939 if (!add_dynamic_entry (DT_PLTGOT, 0)
7940 || !add_dynamic_entry (DT_PLTRELSZ, 0)
7941 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
7942 || !add_dynamic_entry (DT_JMPREL, 0))
7945 if (htab->tlsdesc_plt
7946 && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
7947 || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
7953 if (!add_dynamic_entry (DT_RELA, 0)
7954 || !add_dynamic_entry (DT_RELASZ, 0)
7955 || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
7958 /* If any dynamic relocs apply to a read-only section,
7959 then we need a DT_TEXTREL entry. */
7960 if ((info->flags & DF_TEXTREL) == 0)
7961 elf_link_hash_traverse (& htab->root, aarch64_readonly_dynrelocs,
7964 if ((info->flags & DF_TEXTREL) != 0)
7966 if (!add_dynamic_entry (DT_TEXTREL, 0))
7971 #undef add_dynamic_entry
7977 elf_aarch64_update_plt_entry (bfd *output_bfd,
7978 bfd_reloc_code_real_type r_type,
7979 bfd_byte *plt_entry, bfd_vma value)
7981 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
7983 _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
7987 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
7988 struct elf_aarch64_link_hash_table
7989 *htab, bfd *output_bfd,
7990 struct bfd_link_info *info)
7992 bfd_byte *plt_entry;
7995 bfd_vma gotplt_entry_address;
7996 bfd_vma plt_entry_address;
7997 Elf_Internal_Rela rela;
7999 asection *plt, *gotplt, *relplt;
8001 /* When building a static executable, use .iplt, .igot.plt and
8002 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8003 if (htab->root.splt != NULL)
8005 plt = htab->root.splt;
8006 gotplt = htab->root.sgotplt;
8007 relplt = htab->root.srelplt;
8011 plt = htab->root.iplt;
8012 gotplt = htab->root.igotplt;
8013 relplt = htab->root.irelplt;
8016 /* Get the index in the procedure linkage table which
8017 corresponds to this symbol. This is the index of this symbol
8018 in all the symbols for which we are making plt entries. The
8019 first entry in the procedure linkage table is reserved.
8021 Get the offset into the .got table of the entry that
8022 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
8023 bytes. The first three are reserved for the dynamic linker.
8025 For static executables, we don't reserve anything. */
8027 if (plt == htab->root.splt)
8029 plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
8030 got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
8034 plt_index = h->plt.offset / htab->plt_entry_size;
8035 got_offset = plt_index * GOT_ENTRY_SIZE;
8038 plt_entry = plt->contents + h->plt.offset;
8039 plt_entry_address = plt->output_section->vma
8040 + plt->output_offset + h->plt.offset;
8041 gotplt_entry_address = gotplt->output_section->vma +
8042 gotplt->output_offset + got_offset;
8044 /* Copy in the boiler-plate for the PLTn entry. */
8045 memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
8047 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8048 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8049 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
8051 PG (gotplt_entry_address) -
8052 PG (plt_entry_address));
8054 /* Fill in the lo12 bits for the load from the pltgot. */
8055 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
8057 PG_OFFSET (gotplt_entry_address));
8059 /* Fill in the lo12 bits for the add from the pltgot entry. */
8060 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
8062 PG_OFFSET (gotplt_entry_address));
8064 /* All the GOTPLT Entries are essentially initialized to PLT0. */
8065 bfd_put_NN (output_bfd,
8066 plt->output_section->vma + plt->output_offset,
8067 gotplt->contents + got_offset);
8069 rela.r_offset = gotplt_entry_address;
8071 if (h->dynindx == -1
8072 || ((bfd_link_executable (info)
8073 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
8075 && h->type == STT_GNU_IFUNC))
8077 /* If an STT_GNU_IFUNC symbol is locally defined, generate
8078 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
8079 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
8080 rela.r_addend = (h->root.u.def.value
8081 + h->root.u.def.section->output_section->vma
8082 + h->root.u.def.section->output_offset);
8086 /* Fill in the entry in the .rela.plt section. */
8087 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
8091 /* Compute the relocation entry to used based on PLT index and do
8092 not adjust reloc_count. The reloc_count has already been adjusted
8093 to account for this entry. */
8094 loc = relplt->contents + plt_index * RELOC_SIZE (htab);
8095 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
8098 /* Size sections even though they're not dynamic. We use it to setup
8099 _TLS_MODULE_BASE_, if needed. */
8102 elfNN_aarch64_always_size_sections (bfd *output_bfd,
8103 struct bfd_link_info *info)
8107 if (bfd_link_relocatable (info))
8110 tls_sec = elf_hash_table (info)->tls_sec;
8114 struct elf_link_hash_entry *tlsbase;
8116 tlsbase = elf_link_hash_lookup (elf_hash_table (info),
8117 "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
8121 struct bfd_link_hash_entry *h = NULL;
8122 const struct elf_backend_data *bed =
8123 get_elf_backend_data (output_bfd);
8125 if (!(_bfd_generic_link_add_one_symbol
8126 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
8127 tls_sec, 0, NULL, FALSE, bed->collect, &h)))
8130 tlsbase->type = STT_TLS;
8131 tlsbase = (struct elf_link_hash_entry *) h;
8132 tlsbase->def_regular = 1;
8133 tlsbase->other = STV_HIDDEN;
8134 (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
8141 /* Finish up dynamic symbol handling. We set the contents of various
8142 dynamic sections here. */
8144 elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
8145 struct bfd_link_info *info,
8146 struct elf_link_hash_entry *h,
8147 Elf_Internal_Sym *sym)
8149 struct elf_aarch64_link_hash_table *htab;
8150 htab = elf_aarch64_hash_table (info);
8152 if (h->plt.offset != (bfd_vma) - 1)
8154 asection *plt, *gotplt, *relplt;
8156 /* This symbol has an entry in the procedure linkage table. Set
8159 /* When building a static executable, use .iplt, .igot.plt and
8160 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8161 if (htab->root.splt != NULL)
8163 plt = htab->root.splt;
8164 gotplt = htab->root.sgotplt;
8165 relplt = htab->root.srelplt;
8169 plt = htab->root.iplt;
8170 gotplt = htab->root.igotplt;
8171 relplt = htab->root.irelplt;
8174 /* This symbol has an entry in the procedure linkage table. Set
8176 if ((h->dynindx == -1
8177 && !((h->forced_local || bfd_link_executable (info))
8179 && h->type == STT_GNU_IFUNC))
8185 elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd, info);
8186 if (!h->def_regular)
8188 /* Mark the symbol as undefined, rather than as defined in
8189 the .plt section. */
8190 sym->st_shndx = SHN_UNDEF;
8191 /* If the symbol is weak we need to clear the value.
8192 Otherwise, the PLT entry would provide a definition for
8193 the symbol even if the symbol wasn't defined anywhere,
8194 and so the symbol would never be NULL. Leave the value if
8195 there were any relocations where pointer equality matters
8196 (this is a clue for the dynamic linker, to make function
8197 pointer comparisons work between an application and shared
8199 if (!h->ref_regular_nonweak || !h->pointer_equality_needed)
8204 if (h->got.offset != (bfd_vma) - 1
8205 && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL)
8207 Elf_Internal_Rela rela;
8210 /* This symbol has an entry in the global offset table. Set it
8212 if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
8215 rela.r_offset = (htab->root.sgot->output_section->vma
8216 + htab->root.sgot->output_offset
8217 + (h->got.offset & ~(bfd_vma) 1));
8220 && h->type == STT_GNU_IFUNC)
8222 if (bfd_link_pic (info))
8224 /* Generate R_AARCH64_GLOB_DAT. */
8231 if (!h->pointer_equality_needed)
8234 /* For non-shared object, we can't use .got.plt, which
8235 contains the real function address if we need pointer
8236 equality. We load the GOT entry with the PLT entry. */
8237 plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
8238 bfd_put_NN (output_bfd, (plt->output_section->vma
8239 + plt->output_offset
8241 htab->root.sgot->contents
8242 + (h->got.offset & ~(bfd_vma) 1));
8246 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
8248 if (!h->def_regular)
8251 BFD_ASSERT ((h->got.offset & 1) != 0);
8252 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
8253 rela.r_addend = (h->root.u.def.value
8254 + h->root.u.def.section->output_section->vma
8255 + h->root.u.def.section->output_offset);
8260 BFD_ASSERT ((h->got.offset & 1) == 0);
8261 bfd_put_NN (output_bfd, (bfd_vma) 0,
8262 htab->root.sgot->contents + h->got.offset);
8263 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
8267 loc = htab->root.srelgot->contents;
8268 loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
8269 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
8274 Elf_Internal_Rela rela;
8277 /* This symbol needs a copy reloc. Set it up. */
8279 if (h->dynindx == -1
8280 || (h->root.type != bfd_link_hash_defined
8281 && h->root.type != bfd_link_hash_defweak)
8282 || htab->srelbss == NULL)
8285 rela.r_offset = (h->root.u.def.value
8286 + h->root.u.def.section->output_section->vma
8287 + h->root.u.def.section->output_offset);
8288 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
8290 loc = htab->srelbss->contents;
8291 loc += htab->srelbss->reloc_count++ * RELOC_SIZE (htab);
8292 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
8295 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
8296 be NULL for local symbols. */
8298 && (h == elf_hash_table (info)->hdynamic
8299 || h == elf_hash_table (info)->hgot))
8300 sym->st_shndx = SHN_ABS;
8305 /* Finish up local dynamic symbol handling. We set the contents of
8306 various dynamic sections here. */
8309 elfNN_aarch64_finish_local_dynamic_symbol (void **slot, void *inf)
8311 struct elf_link_hash_entry *h
8312 = (struct elf_link_hash_entry *) *slot;
8313 struct bfd_link_info *info
8314 = (struct bfd_link_info *) inf;
8316 return elfNN_aarch64_finish_dynamic_symbol (info->output_bfd,
8321 elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
8322 struct elf_aarch64_link_hash_table
8325 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
8326 small and large plts and at the minute just generates
8329 /* PLT0 of the small PLT looks like this in ELF64 -
8330 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
8331 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
8332 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
8334 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
8335 // GOTPLT entry for this.
8337 PLT0 will be slightly different in ELF32 due to different got entry
8340 bfd_vma plt_got_2nd_ent; /* Address of GOT[2]. */
8344 memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry,
8346 elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
8349 plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
8350 + htab->root.sgotplt->output_offset
8351 + GOT_ENTRY_SIZE * 2);
8353 plt_base = htab->root.splt->output_section->vma +
8354 htab->root.splt->output_offset;
8356 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8357 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8358 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
8359 htab->root.splt->contents + 4,
8360 PG (plt_got_2nd_ent) - PG (plt_base + 4));
8362 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
8363 htab->root.splt->contents + 8,
8364 PG_OFFSET (plt_got_2nd_ent));
8366 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
8367 htab->root.splt->contents + 12,
8368 PG_OFFSET (plt_got_2nd_ent));
8372 elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
8373 struct bfd_link_info *info)
8375 struct elf_aarch64_link_hash_table *htab;
8379 htab = elf_aarch64_hash_table (info);
8380 dynobj = htab->root.dynobj;
8381 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
8383 if (htab->root.dynamic_sections_created)
8385 ElfNN_External_Dyn *dyncon, *dynconend;
8387 if (sdyn == NULL || htab->root.sgot == NULL)
8390 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
8391 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
8392 for (; dyncon < dynconend; dyncon++)
8394 Elf_Internal_Dyn dyn;
8397 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
8405 s = htab->root.sgotplt;
8406 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
8410 dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
8414 s = htab->root.srelplt;
8415 dyn.d_un.d_val = s->size;
8419 /* The procedure linkage table relocs (DT_JMPREL) should
8420 not be included in the overall relocs (DT_RELA).
8421 Therefore, we override the DT_RELASZ entry here to
8422 make it not include the JMPREL relocs. Since the
8423 linker script arranges for .rela.plt to follow all
8424 other relocation sections, we don't have to worry
8425 about changing the DT_RELA entry. */
8426 if (htab->root.srelplt != NULL)
8428 s = htab->root.srelplt;
8429 dyn.d_un.d_val -= s->size;
8433 case DT_TLSDESC_PLT:
8434 s = htab->root.splt;
8435 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
8436 + htab->tlsdesc_plt;
8439 case DT_TLSDESC_GOT:
8440 s = htab->root.sgot;
8441 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
8442 + htab->dt_tlsdesc_got;
8446 bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
8451 /* Fill in the special first entry in the procedure linkage table. */
8452 if (htab->root.splt && htab->root.splt->size > 0)
8454 elfNN_aarch64_init_small_plt0_entry (output_bfd, htab);
8456 elf_section_data (htab->root.splt->output_section)->
8457 this_hdr.sh_entsize = htab->plt_entry_size;
8460 if (htab->tlsdesc_plt)
8462 bfd_put_NN (output_bfd, (bfd_vma) 0,
8463 htab->root.sgot->contents + htab->dt_tlsdesc_got);
8465 memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
8466 elfNN_aarch64_tlsdesc_small_plt_entry,
8467 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));
8470 bfd_vma adrp1_addr =
8471 htab->root.splt->output_section->vma
8472 + htab->root.splt->output_offset + htab->tlsdesc_plt + 4;
8474 bfd_vma adrp2_addr = adrp1_addr + 4;
8477 htab->root.sgot->output_section->vma
8478 + htab->root.sgot->output_offset;
8480 bfd_vma pltgot_addr =
8481 htab->root.sgotplt->output_section->vma
8482 + htab->root.sgotplt->output_offset;
8484 bfd_vma dt_tlsdesc_got = got_addr + htab->dt_tlsdesc_got;
8486 bfd_byte *plt_entry =
8487 htab->root.splt->contents + htab->tlsdesc_plt;
8489 /* adrp x2, DT_TLSDESC_GOT */
8490 elf_aarch64_update_plt_entry (output_bfd,
8491 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
8493 (PG (dt_tlsdesc_got)
8494 - PG (adrp1_addr)));
8497 elf_aarch64_update_plt_entry (output_bfd,
8498 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
8501 - PG (adrp2_addr)));
8503 /* ldr x2, [x2, #0] */
8504 elf_aarch64_update_plt_entry (output_bfd,
8505 BFD_RELOC_AARCH64_LDSTNN_LO12,
8507 PG_OFFSET (dt_tlsdesc_got));
8510 elf_aarch64_update_plt_entry (output_bfd,
8511 BFD_RELOC_AARCH64_ADD_LO12,
8513 PG_OFFSET (pltgot_addr));
8518 if (htab->root.sgotplt)
8520 if (bfd_is_abs_section (htab->root.sgotplt->output_section))
8522 (*_bfd_error_handler)
8523 (_("discarded output section: `%A'"), htab->root.sgotplt);
8527 /* Fill in the first three entries in the global offset table. */
8528 if (htab->root.sgotplt->size > 0)
8530 bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
8532 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
8533 bfd_put_NN (output_bfd,
8535 htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
8536 bfd_put_NN (output_bfd,
8538 htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
8541 if (htab->root.sgot)
8543 if (htab->root.sgot->size > 0)
8546 sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
8547 bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
8551 elf_section_data (htab->root.sgotplt->output_section)->
8552 this_hdr.sh_entsize = GOT_ENTRY_SIZE;
8555 if (htab->root.sgot && htab->root.sgot->size > 0)
8556 elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
8559 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
8560 htab_traverse (htab->loc_hash_table,
8561 elfNN_aarch64_finish_local_dynamic_symbol,
8567 /* Return address for Ith PLT stub in section PLT, for relocation REL
8568 or (bfd_vma) -1 if it should not be included. */
8571 elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
8572 const arelent *rel ATTRIBUTE_UNUSED)
8574 return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
8578 /* We use this so we can override certain functions
8579 (though currently we don't). */
8581 const struct elf_size_info elfNN_aarch64_size_info =
8583 sizeof (ElfNN_External_Ehdr),
8584 sizeof (ElfNN_External_Phdr),
8585 sizeof (ElfNN_External_Shdr),
8586 sizeof (ElfNN_External_Rel),
8587 sizeof (ElfNN_External_Rela),
8588 sizeof (ElfNN_External_Sym),
8589 sizeof (ElfNN_External_Dyn),
8590 sizeof (Elf_External_Note),
8591 4, /* Hash table entry size. */
8592 1, /* Internal relocs per external relocs. */
8593 ARCH_SIZE, /* Arch size. */
8594 LOG_FILE_ALIGN, /* Log_file_align. */
8595 ELFCLASSNN, EV_CURRENT,
8596 bfd_elfNN_write_out_phdrs,
8597 bfd_elfNN_write_shdrs_and_ehdr,
8598 bfd_elfNN_checksum_contents,
8599 bfd_elfNN_write_relocs,
8600 bfd_elfNN_swap_symbol_in,
8601 bfd_elfNN_swap_symbol_out,
8602 bfd_elfNN_slurp_reloc_table,
8603 bfd_elfNN_slurp_symbol_table,
8604 bfd_elfNN_swap_dyn_in,
8605 bfd_elfNN_swap_dyn_out,
8606 bfd_elfNN_swap_reloc_in,
8607 bfd_elfNN_swap_reloc_out,
8608 bfd_elfNN_swap_reloca_in,
8609 bfd_elfNN_swap_reloca_out
8612 #define ELF_ARCH bfd_arch_aarch64
8613 #define ELF_MACHINE_CODE EM_AARCH64
8614 #define ELF_MAXPAGESIZE 0x10000
8615 #define ELF_MINPAGESIZE 0x1000
8616 #define ELF_COMMONPAGESIZE 0x1000
8618 #define bfd_elfNN_close_and_cleanup \
8619 elfNN_aarch64_close_and_cleanup
8621 #define bfd_elfNN_bfd_free_cached_info \
8622 elfNN_aarch64_bfd_free_cached_info
8624 #define bfd_elfNN_bfd_is_target_special_symbol \
8625 elfNN_aarch64_is_target_special_symbol
8627 #define bfd_elfNN_bfd_link_hash_table_create \
8628 elfNN_aarch64_link_hash_table_create
8630 #define bfd_elfNN_bfd_merge_private_bfd_data \
8631 elfNN_aarch64_merge_private_bfd_data
8633 #define bfd_elfNN_bfd_print_private_bfd_data \
8634 elfNN_aarch64_print_private_bfd_data
8636 #define bfd_elfNN_bfd_reloc_type_lookup \
8637 elfNN_aarch64_reloc_type_lookup
8639 #define bfd_elfNN_bfd_reloc_name_lookup \
8640 elfNN_aarch64_reloc_name_lookup
8642 #define bfd_elfNN_bfd_set_private_flags \
8643 elfNN_aarch64_set_private_flags
8645 #define bfd_elfNN_find_inliner_info \
8646 elfNN_aarch64_find_inliner_info
8648 #define bfd_elfNN_find_nearest_line \
8649 elfNN_aarch64_find_nearest_line
8651 #define bfd_elfNN_mkobject \
8652 elfNN_aarch64_mkobject
8654 #define bfd_elfNN_new_section_hook \
8655 elfNN_aarch64_new_section_hook
8657 #define elf_backend_adjust_dynamic_symbol \
8658 elfNN_aarch64_adjust_dynamic_symbol
8660 #define elf_backend_always_size_sections \
8661 elfNN_aarch64_always_size_sections
8663 #define elf_backend_check_relocs \
8664 elfNN_aarch64_check_relocs
8666 #define elf_backend_copy_indirect_symbol \
8667 elfNN_aarch64_copy_indirect_symbol
8669 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
8670 to them in our hash. */
8671 #define elf_backend_create_dynamic_sections \
8672 elfNN_aarch64_create_dynamic_sections
8674 #define elf_backend_init_index_section \
8675 _bfd_elf_init_2_index_sections
8677 #define elf_backend_finish_dynamic_sections \
8678 elfNN_aarch64_finish_dynamic_sections
8680 #define elf_backend_finish_dynamic_symbol \
8681 elfNN_aarch64_finish_dynamic_symbol
8683 #define elf_backend_gc_sweep_hook \
8684 elfNN_aarch64_gc_sweep_hook
8686 #define elf_backend_object_p \
8687 elfNN_aarch64_object_p
8689 #define elf_backend_output_arch_local_syms \
8690 elfNN_aarch64_output_arch_local_syms
8692 #define elf_backend_plt_sym_val \
8693 elfNN_aarch64_plt_sym_val
8695 #define elf_backend_post_process_headers \
8696 elfNN_aarch64_post_process_headers
8698 #define elf_backend_relocate_section \
8699 elfNN_aarch64_relocate_section
8701 #define elf_backend_reloc_type_class \
8702 elfNN_aarch64_reloc_type_class
8704 #define elf_backend_section_from_shdr \
8705 elfNN_aarch64_section_from_shdr
8707 #define elf_backend_size_dynamic_sections \
8708 elfNN_aarch64_size_dynamic_sections
8710 #define elf_backend_size_info \
8711 elfNN_aarch64_size_info
8713 #define elf_backend_write_section \
8714 elfNN_aarch64_write_section
8716 #define elf_backend_can_refcount 1
8717 #define elf_backend_can_gc_sections 1
8718 #define elf_backend_plt_readonly 1
8719 #define elf_backend_want_got_plt 1
8720 #define elf_backend_want_plt_sym 0
8721 #define elf_backend_may_use_rel_p 0
8722 #define elf_backend_may_use_rela_p 1
8723 #define elf_backend_default_use_rela_p 1
8724 #define elf_backend_rela_normal 1
8725 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
8726 #define elf_backend_default_execstack 0
8727 #define elf_backend_extern_protected_data 1
8729 #undef elf_backend_obj_attrs_section
8730 #define elf_backend_obj_attrs_section ".ARM.attributes"
8732 #include "elfNN-target.h"