1 /* AArch64-specific support for NN-bit ELF.
2 Copyright 2009-2013 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 "elf/aarch64.h"
146 #include "elfxx-aarch64.h"
151 #define AARCH64_R(NAME) R_AARCH64_ ## NAME
152 #define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
153 #define HOWTO64(...) HOWTO (__VA_ARGS__)
154 #define HOWTO32(...) EMPTY_HOWTO (0)
155 #define LOG_FILE_ALIGN 3
159 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
160 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
161 #define HOWTO64(...) EMPTY_HOWTO (0)
162 #define HOWTO32(...) HOWTO (__VA_ARGS__)
163 #define LOG_FILE_ALIGN 2
166 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
167 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
168 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
169 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
170 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
171 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
186 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
188 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
189 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC)
202 #define ELIMINATE_COPY_RELOCS 0
204 /* Return size of a relocation entry. HTAB is the bfd's
205 elf_aarch64_link_hash_entry. */
206 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
208 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
209 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
210 #define PLT_ENTRY_SIZE (32)
211 #define PLT_SMALL_ENTRY_SIZE (16)
212 #define PLT_TLSDESC_ENTRY_SIZE (32)
214 /* Encoding of the nop instruction */
215 #define INSN_NOP 0xd503201f
217 #define aarch64_compute_jump_table_size(htab) \
218 (((htab)->root.srelplt == NULL) ? 0 \
219 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
221 /* The first entry in a procedure linkage table looks like this
222 if the distance between the PLTGOT and the PLT is < 4GB use
223 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
224 in x16 and needs to work out PLTGOT[1] by using an address of
225 [x16,#-GOT_ENTRY_SIZE]. */
226 static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
228 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
229 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
231 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
232 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
234 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
235 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
237 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
238 0x1f, 0x20, 0x03, 0xd5, /* nop */
239 0x1f, 0x20, 0x03, 0xd5, /* nop */
240 0x1f, 0x20, 0x03, 0xd5, /* nop */
243 /* Per function entry in a procedure linkage table looks like this
244 if the distance between the PLTGOT and the PLT is < 4GB use
245 these PLT entries. */
246 static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
248 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
250 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
251 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
253 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
254 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
256 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
259 static const bfd_byte
260 elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
262 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
263 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
264 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
266 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
267 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
269 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
270 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
272 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
273 0x1f, 0x20, 0x03, 0xd5, /* nop */
274 0x1f, 0x20, 0x03, 0xd5, /* nop */
277 #define elf_info_to_howto elfNN_aarch64_info_to_howto
278 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
280 #define AARCH64_ELF_ABI_VERSION 0
282 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
283 #define ALL_ONES (~ (bfd_vma) 0)
285 /* Indexed by the bfd interal reloc enumerators.
286 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
289 static reloc_howto_type elfNN_aarch64_howto_table[] =
293 /* Basic data relocations. */
296 HOWTO (R_AARCH64_NULL, /* type */
298 0, /* size (0 = byte, 1 = short, 2 = long) */
300 FALSE, /* pc_relative */
302 complain_overflow_dont, /* complain_on_overflow */
303 bfd_elf_generic_reloc, /* special_function */
304 "R_AARCH64_NULL", /* name */
305 FALSE, /* partial_inplace */
308 FALSE), /* pcrel_offset */
310 HOWTO (R_AARCH64_NONE, /* type */
312 0, /* size (0 = byte, 1 = short, 2 = long) */
314 FALSE, /* pc_relative */
316 complain_overflow_dont, /* complain_on_overflow */
317 bfd_elf_generic_reloc, /* special_function */
318 "R_AARCH64_NONE", /* name */
319 FALSE, /* partial_inplace */
322 FALSE), /* pcrel_offset */
326 HOWTO64 (AARCH64_R (ABS64), /* type */
328 4, /* size (4 = long long) */
330 FALSE, /* pc_relative */
332 complain_overflow_unsigned, /* complain_on_overflow */
333 bfd_elf_generic_reloc, /* special_function */
334 AARCH64_R_STR (ABS64), /* name */
335 FALSE, /* partial_inplace */
336 ALL_ONES, /* src_mask */
337 ALL_ONES, /* dst_mask */
338 FALSE), /* pcrel_offset */
341 HOWTO (AARCH64_R (ABS32), /* type */
343 2, /* size (0 = byte, 1 = short, 2 = long) */
345 FALSE, /* pc_relative */
347 complain_overflow_unsigned, /* complain_on_overflow */
348 bfd_elf_generic_reloc, /* special_function */
349 AARCH64_R_STR (ABS32), /* name */
350 FALSE, /* partial_inplace */
351 0xffffffff, /* src_mask */
352 0xffffffff, /* dst_mask */
353 FALSE), /* pcrel_offset */
356 HOWTO (AARCH64_R (ABS16), /* type */
358 1, /* size (0 = byte, 1 = short, 2 = long) */
360 FALSE, /* pc_relative */
362 complain_overflow_unsigned, /* complain_on_overflow */
363 bfd_elf_generic_reloc, /* special_function */
364 AARCH64_R_STR (ABS16), /* name */
365 FALSE, /* partial_inplace */
366 0xffff, /* src_mask */
367 0xffff, /* dst_mask */
368 FALSE), /* pcrel_offset */
370 /* .xword: (S+A-P) */
371 HOWTO64 (AARCH64_R (PREL64), /* type */
373 4, /* size (4 = long long) */
375 TRUE, /* pc_relative */
377 complain_overflow_signed, /* complain_on_overflow */
378 bfd_elf_generic_reloc, /* special_function */
379 AARCH64_R_STR (PREL64), /* name */
380 FALSE, /* partial_inplace */
381 ALL_ONES, /* src_mask */
382 ALL_ONES, /* dst_mask */
383 TRUE), /* pcrel_offset */
386 HOWTO (AARCH64_R (PREL32), /* type */
388 2, /* size (0 = byte, 1 = short, 2 = long) */
390 TRUE, /* pc_relative */
392 complain_overflow_signed, /* complain_on_overflow */
393 bfd_elf_generic_reloc, /* special_function */
394 AARCH64_R_STR (PREL32), /* name */
395 FALSE, /* partial_inplace */
396 0xffffffff, /* src_mask */
397 0xffffffff, /* dst_mask */
398 TRUE), /* pcrel_offset */
401 HOWTO (AARCH64_R (PREL16), /* type */
403 1, /* size (0 = byte, 1 = short, 2 = long) */
405 TRUE, /* pc_relative */
407 complain_overflow_signed, /* complain_on_overflow */
408 bfd_elf_generic_reloc, /* special_function */
409 AARCH64_R_STR (PREL16), /* name */
410 FALSE, /* partial_inplace */
411 0xffff, /* src_mask */
412 0xffff, /* dst_mask */
413 TRUE), /* pcrel_offset */
415 /* Group relocations to create a 16, 32, 48 or 64 bit
416 unsigned data or abs address inline. */
418 /* MOVZ: ((S+A) >> 0) & 0xffff */
419 HOWTO (AARCH64_R (MOVW_UABS_G0), /* type */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
423 FALSE, /* pc_relative */
425 complain_overflow_unsigned, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 AARCH64_R_STR (MOVW_UABS_G0), /* name */
428 FALSE, /* partial_inplace */
429 0xffff, /* src_mask */
430 0xffff, /* dst_mask */
431 FALSE), /* pcrel_offset */
433 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
434 HOWTO (AARCH64_R (MOVW_UABS_G0_NC), /* type */
436 2, /* size (0 = byte, 1 = short, 2 = long) */
438 FALSE, /* pc_relative */
440 complain_overflow_dont, /* complain_on_overflow */
441 bfd_elf_generic_reloc, /* special_function */
442 AARCH64_R_STR (MOVW_UABS_G0_NC), /* name */
443 FALSE, /* partial_inplace */
444 0xffff, /* src_mask */
445 0xffff, /* dst_mask */
446 FALSE), /* pcrel_offset */
448 /* MOVZ: ((S+A) >> 16) & 0xffff */
449 HOWTO (AARCH64_R (MOVW_UABS_G1), /* type */
451 2, /* size (0 = byte, 1 = short, 2 = long) */
453 FALSE, /* pc_relative */
455 complain_overflow_unsigned, /* complain_on_overflow */
456 bfd_elf_generic_reloc, /* special_function */
457 AARCH64_R_STR (MOVW_UABS_G1), /* name */
458 FALSE, /* partial_inplace */
459 0xffff, /* src_mask */
460 0xffff, /* dst_mask */
461 FALSE), /* pcrel_offset */
463 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
464 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC), /* type */
466 2, /* size (0 = byte, 1 = short, 2 = long) */
468 FALSE, /* pc_relative */
470 complain_overflow_dont, /* complain_on_overflow */
471 bfd_elf_generic_reloc, /* special_function */
472 AARCH64_R_STR (MOVW_UABS_G1_NC), /* name */
473 FALSE, /* partial_inplace */
474 0xffff, /* src_mask */
475 0xffff, /* dst_mask */
476 FALSE), /* pcrel_offset */
478 /* MOVZ: ((S+A) >> 32) & 0xffff */
479 HOWTO64 (AARCH64_R (MOVW_UABS_G2), /* type */
481 2, /* size (0 = byte, 1 = short, 2 = long) */
483 FALSE, /* pc_relative */
485 complain_overflow_unsigned, /* complain_on_overflow */
486 bfd_elf_generic_reloc, /* special_function */
487 AARCH64_R_STR (MOVW_UABS_G2), /* name */
488 FALSE, /* partial_inplace */
489 0xffff, /* src_mask */
490 0xffff, /* dst_mask */
491 FALSE), /* pcrel_offset */
493 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
494 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC), /* type */
496 2, /* size (0 = byte, 1 = short, 2 = long) */
498 FALSE, /* pc_relative */
500 complain_overflow_dont, /* complain_on_overflow */
501 bfd_elf_generic_reloc, /* special_function */
502 AARCH64_R_STR (MOVW_UABS_G2_NC), /* name */
503 FALSE, /* partial_inplace */
504 0xffff, /* src_mask */
505 0xffff, /* dst_mask */
506 FALSE), /* pcrel_offset */
508 /* MOVZ: ((S+A) >> 48) & 0xffff */
509 HOWTO64 (AARCH64_R (MOVW_UABS_G3), /* type */
511 2, /* size (0 = byte, 1 = short, 2 = long) */
513 FALSE, /* pc_relative */
515 complain_overflow_unsigned, /* complain_on_overflow */
516 bfd_elf_generic_reloc, /* special_function */
517 AARCH64_R_STR (MOVW_UABS_G3), /* name */
518 FALSE, /* partial_inplace */
519 0xffff, /* src_mask */
520 0xffff, /* dst_mask */
521 FALSE), /* pcrel_offset */
523 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
524 signed data or abs address inline. Will change instruction
525 to MOVN or MOVZ depending on sign of calculated value. */
527 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
528 HOWTO (AARCH64_R (MOVW_SABS_G0), /* type */
530 2, /* size (0 = byte, 1 = short, 2 = long) */
532 FALSE, /* pc_relative */
534 complain_overflow_signed, /* complain_on_overflow */
535 bfd_elf_generic_reloc, /* special_function */
536 AARCH64_R_STR (MOVW_SABS_G0), /* name */
537 FALSE, /* partial_inplace */
538 0xffff, /* src_mask */
539 0xffff, /* dst_mask */
540 FALSE), /* pcrel_offset */
542 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
543 HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
545 2, /* size (0 = byte, 1 = short, 2 = long) */
547 FALSE, /* pc_relative */
549 complain_overflow_signed, /* complain_on_overflow */
550 bfd_elf_generic_reloc, /* special_function */
551 AARCH64_R_STR (MOVW_SABS_G1), /* name */
552 FALSE, /* partial_inplace */
553 0xffff, /* src_mask */
554 0xffff, /* dst_mask */
555 FALSE), /* pcrel_offset */
557 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
558 HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
560 2, /* size (0 = byte, 1 = short, 2 = long) */
562 FALSE, /* pc_relative */
564 complain_overflow_signed, /* complain_on_overflow */
565 bfd_elf_generic_reloc, /* special_function */
566 AARCH64_R_STR (MOVW_SABS_G2), /* name */
567 FALSE, /* partial_inplace */
568 0xffff, /* src_mask */
569 0xffff, /* dst_mask */
570 FALSE), /* pcrel_offset */
572 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
573 addresses: PG(x) is (x & ~0xfff). */
575 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
576 HOWTO (AARCH64_R (LD_PREL_LO19), /* type */
578 2, /* size (0 = byte, 1 = short, 2 = long) */
580 TRUE, /* pc_relative */
582 complain_overflow_signed, /* complain_on_overflow */
583 bfd_elf_generic_reloc, /* special_function */
584 AARCH64_R_STR (LD_PREL_LO19), /* name */
585 FALSE, /* partial_inplace */
586 0x7ffff, /* src_mask */
587 0x7ffff, /* dst_mask */
588 TRUE), /* pcrel_offset */
590 /* ADR: (S+A-P) & 0x1fffff */
591 HOWTO (AARCH64_R (ADR_PREL_LO21), /* type */
593 2, /* size (0 = byte, 1 = short, 2 = long) */
595 TRUE, /* pc_relative */
597 complain_overflow_signed, /* complain_on_overflow */
598 bfd_elf_generic_reloc, /* special_function */
599 AARCH64_R_STR (ADR_PREL_LO21), /* name */
600 FALSE, /* partial_inplace */
601 0x1fffff, /* src_mask */
602 0x1fffff, /* dst_mask */
603 TRUE), /* pcrel_offset */
605 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
606 HOWTO (AARCH64_R (ADR_PREL_PG_HI21), /* type */
608 2, /* size (0 = byte, 1 = short, 2 = long) */
610 TRUE, /* pc_relative */
612 complain_overflow_signed, /* complain_on_overflow */
613 bfd_elf_generic_reloc, /* special_function */
614 AARCH64_R_STR (ADR_PREL_PG_HI21), /* name */
615 FALSE, /* partial_inplace */
616 0x1fffff, /* src_mask */
617 0x1fffff, /* dst_mask */
618 TRUE), /* pcrel_offset */
620 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
621 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC), /* type */
623 2, /* size (0 = byte, 1 = short, 2 = long) */
625 TRUE, /* pc_relative */
627 complain_overflow_dont, /* complain_on_overflow */
628 bfd_elf_generic_reloc, /* special_function */
629 AARCH64_R_STR (ADR_PREL_PG_HI21_NC), /* name */
630 FALSE, /* partial_inplace */
631 0x1fffff, /* src_mask */
632 0x1fffff, /* dst_mask */
633 TRUE), /* pcrel_offset */
635 /* ADD: (S+A) & 0xfff [no overflow check] */
636 HOWTO (AARCH64_R (ADD_ABS_LO12_NC), /* type */
638 2, /* size (0 = byte, 1 = short, 2 = long) */
640 FALSE, /* pc_relative */
642 complain_overflow_dont, /* complain_on_overflow */
643 bfd_elf_generic_reloc, /* special_function */
644 AARCH64_R_STR (ADD_ABS_LO12_NC), /* name */
645 FALSE, /* partial_inplace */
646 0x3ffc00, /* src_mask */
647 0x3ffc00, /* dst_mask */
648 FALSE), /* pcrel_offset */
650 /* LD/ST8: (S+A) & 0xfff */
651 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC), /* type */
653 2, /* size (0 = byte, 1 = short, 2 = long) */
655 FALSE, /* pc_relative */
657 complain_overflow_dont, /* complain_on_overflow */
658 bfd_elf_generic_reloc, /* special_function */
659 AARCH64_R_STR (LDST8_ABS_LO12_NC), /* name */
660 FALSE, /* partial_inplace */
661 0xfff, /* src_mask */
662 0xfff, /* dst_mask */
663 FALSE), /* pcrel_offset */
665 /* Relocations for control-flow instructions. */
667 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
668 HOWTO (AARCH64_R (TSTBR14), /* type */
670 2, /* size (0 = byte, 1 = short, 2 = long) */
672 TRUE, /* pc_relative */
674 complain_overflow_signed, /* complain_on_overflow */
675 bfd_elf_generic_reloc, /* special_function */
676 AARCH64_R_STR (TSTBR14), /* name */
677 FALSE, /* partial_inplace */
678 0x3fff, /* src_mask */
679 0x3fff, /* dst_mask */
680 TRUE), /* pcrel_offset */
682 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
683 HOWTO (AARCH64_R (CONDBR19), /* type */
685 2, /* size (0 = byte, 1 = short, 2 = long) */
687 TRUE, /* pc_relative */
689 complain_overflow_signed, /* complain_on_overflow */
690 bfd_elf_generic_reloc, /* special_function */
691 AARCH64_R_STR (CONDBR19), /* name */
692 FALSE, /* partial_inplace */
693 0x7ffff, /* src_mask */
694 0x7ffff, /* dst_mask */
695 TRUE), /* pcrel_offset */
697 /* B: ((S+A-P) >> 2) & 0x3ffffff */
698 HOWTO (AARCH64_R (JUMP26), /* type */
700 2, /* size (0 = byte, 1 = short, 2 = long) */
702 TRUE, /* pc_relative */
704 complain_overflow_signed, /* complain_on_overflow */
705 bfd_elf_generic_reloc, /* special_function */
706 AARCH64_R_STR (JUMP26), /* name */
707 FALSE, /* partial_inplace */
708 0x3ffffff, /* src_mask */
709 0x3ffffff, /* dst_mask */
710 TRUE), /* pcrel_offset */
712 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
713 HOWTO (AARCH64_R (CALL26), /* type */
715 2, /* size (0 = byte, 1 = short, 2 = long) */
717 TRUE, /* pc_relative */
719 complain_overflow_signed, /* complain_on_overflow */
720 bfd_elf_generic_reloc, /* special_function */
721 AARCH64_R_STR (CALL26), /* name */
722 FALSE, /* partial_inplace */
723 0x3ffffff, /* src_mask */
724 0x3ffffff, /* dst_mask */
725 TRUE), /* pcrel_offset */
727 /* LD/ST16: (S+A) & 0xffe */
728 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */
730 2, /* size (0 = byte, 1 = short, 2 = long) */
732 FALSE, /* pc_relative */
734 complain_overflow_dont, /* complain_on_overflow */
735 bfd_elf_generic_reloc, /* special_function */
736 AARCH64_R_STR (LDST16_ABS_LO12_NC), /* name */
737 FALSE, /* partial_inplace */
738 0xffe, /* src_mask */
739 0xffe, /* dst_mask */
740 FALSE), /* pcrel_offset */
742 /* LD/ST32: (S+A) & 0xffc */
743 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC), /* type */
745 2, /* size (0 = byte, 1 = short, 2 = long) */
747 FALSE, /* pc_relative */
749 complain_overflow_dont, /* complain_on_overflow */
750 bfd_elf_generic_reloc, /* special_function */
751 AARCH64_R_STR (LDST32_ABS_LO12_NC), /* name */
752 FALSE, /* partial_inplace */
753 0xffc, /* src_mask */
754 0xffc, /* dst_mask */
755 FALSE), /* pcrel_offset */
757 /* LD/ST64: (S+A) & 0xff8 */
758 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC), /* type */
760 2, /* size (0 = byte, 1 = short, 2 = long) */
762 FALSE, /* pc_relative */
764 complain_overflow_dont, /* complain_on_overflow */
765 bfd_elf_generic_reloc, /* special_function */
766 AARCH64_R_STR (LDST64_ABS_LO12_NC), /* name */
767 FALSE, /* partial_inplace */
768 0xff8, /* src_mask */
769 0xff8, /* dst_mask */
770 FALSE), /* pcrel_offset */
772 /* LD/ST128: (S+A) & 0xff0 */
773 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC), /* type */
775 2, /* size (0 = byte, 1 = short, 2 = long) */
777 FALSE, /* pc_relative */
779 complain_overflow_dont, /* complain_on_overflow */
780 bfd_elf_generic_reloc, /* special_function */
781 AARCH64_R_STR (LDST128_ABS_LO12_NC), /* name */
782 FALSE, /* partial_inplace */
783 0xff0, /* src_mask */
784 0xff0, /* dst_mask */
785 FALSE), /* pcrel_offset */
787 /* Set a load-literal immediate field to bits
788 0x1FFFFC of G(S)-P */
789 HOWTO (AARCH64_R (GOT_LD_PREL19), /* type */
791 2, /* size (0 = byte,1 = short,2 = long) */
793 TRUE, /* pc_relative */
795 complain_overflow_signed, /* complain_on_overflow */
796 bfd_elf_generic_reloc, /* special_function */
797 AARCH64_R_STR (GOT_LD_PREL19), /* name */
798 FALSE, /* partial_inplace */
799 0xffffe0, /* src_mask */
800 0xffffe0, /* dst_mask */
801 TRUE), /* pcrel_offset */
803 /* Get to the page for the GOT entry for the symbol
804 (G(S) - P) using an ADRP instruction. */
805 HOWTO (AARCH64_R (ADR_GOT_PAGE), /* type */
807 2, /* size (0 = byte, 1 = short, 2 = long) */
809 TRUE, /* pc_relative */
811 complain_overflow_dont, /* complain_on_overflow */
812 bfd_elf_generic_reloc, /* special_function */
813 AARCH64_R_STR (ADR_GOT_PAGE), /* name */
814 FALSE, /* partial_inplace */
815 0x1fffff, /* src_mask */
816 0x1fffff, /* dst_mask */
817 TRUE), /* pcrel_offset */
819 /* LD64: GOT offset G(S) & 0xff8 */
820 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC), /* type */
822 2, /* size (0 = byte, 1 = short, 2 = long) */
824 FALSE, /* pc_relative */
826 complain_overflow_dont, /* complain_on_overflow */
827 bfd_elf_generic_reloc, /* special_function */
828 AARCH64_R_STR (LD64_GOT_LO12_NC), /* name */
829 FALSE, /* partial_inplace */
830 0xff8, /* src_mask */
831 0xff8, /* dst_mask */
832 FALSE), /* pcrel_offset */
834 /* LD32: GOT offset G(S) & 0xffc */
835 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC), /* type */
837 2, /* size (0 = byte, 1 = short, 2 = long) */
839 FALSE, /* pc_relative */
841 complain_overflow_dont, /* complain_on_overflow */
842 bfd_elf_generic_reloc, /* special_function */
843 AARCH64_R_STR (LD32_GOT_LO12_NC), /* name */
844 FALSE, /* partial_inplace */
845 0xffc, /* src_mask */
846 0xffc, /* dst_mask */
847 FALSE), /* pcrel_offset */
849 /* Get to the page for the GOT entry for the symbol
850 (G(S) - P) using an ADRP instruction. */
851 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21), /* type */
853 2, /* size (0 = byte, 1 = short, 2 = long) */
855 TRUE, /* pc_relative */
857 complain_overflow_dont, /* complain_on_overflow */
858 bfd_elf_generic_reloc, /* special_function */
859 AARCH64_R_STR (TLSGD_ADR_PAGE21), /* name */
860 FALSE, /* partial_inplace */
861 0x1fffff, /* src_mask */
862 0x1fffff, /* dst_mask */
863 TRUE), /* pcrel_offset */
865 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
866 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC), /* type */
868 2, /* size (0 = byte, 1 = short, 2 = long) */
870 FALSE, /* pc_relative */
872 complain_overflow_dont, /* complain_on_overflow */
873 bfd_elf_generic_reloc, /* special_function */
874 AARCH64_R_STR (TLSGD_ADD_LO12_NC), /* name */
875 FALSE, /* partial_inplace */
876 0xfff, /* src_mask */
877 0xfff, /* dst_mask */
878 FALSE), /* pcrel_offset */
880 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
882 2, /* size (0 = byte, 1 = short, 2 = long) */
884 FALSE, /* pc_relative */
886 complain_overflow_dont, /* complain_on_overflow */
887 bfd_elf_generic_reloc, /* special_function */
888 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1), /* name */
889 FALSE, /* partial_inplace */
890 0xffff, /* src_mask */
891 0xffff, /* dst_mask */
892 FALSE), /* pcrel_offset */
894 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC), /* type */
896 2, /* size (0 = byte, 1 = short, 2 = long) */
898 FALSE, /* pc_relative */
900 complain_overflow_dont, /* complain_on_overflow */
901 bfd_elf_generic_reloc, /* special_function */
902 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC), /* name */
903 FALSE, /* partial_inplace */
904 0xffff, /* src_mask */
905 0xffff, /* dst_mask */
906 FALSE), /* pcrel_offset */
908 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21), /* type */
910 2, /* size (0 = byte, 1 = short, 2 = long) */
912 FALSE, /* pc_relative */
914 complain_overflow_dont, /* complain_on_overflow */
915 bfd_elf_generic_reloc, /* special_function */
916 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21), /* name */
917 FALSE, /* partial_inplace */
918 0x1fffff, /* src_mask */
919 0x1fffff, /* dst_mask */
920 FALSE), /* pcrel_offset */
922 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC), /* type */
924 2, /* size (0 = byte, 1 = short, 2 = long) */
926 FALSE, /* pc_relative */
928 complain_overflow_dont, /* complain_on_overflow */
929 bfd_elf_generic_reloc, /* special_function */
930 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC), /* name */
931 FALSE, /* partial_inplace */
932 0xff8, /* src_mask */
933 0xff8, /* dst_mask */
934 FALSE), /* pcrel_offset */
936 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC), /* type */
938 2, /* size (0 = byte, 1 = short, 2 = long) */
940 FALSE, /* pc_relative */
942 complain_overflow_dont, /* complain_on_overflow */
943 bfd_elf_generic_reloc, /* special_function */
944 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC), /* name */
945 FALSE, /* partial_inplace */
946 0xffc, /* src_mask */
947 0xffc, /* dst_mask */
948 FALSE), /* pcrel_offset */
950 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19), /* type */
952 2, /* size (0 = byte, 1 = short, 2 = long) */
954 FALSE, /* pc_relative */
956 complain_overflow_dont, /* complain_on_overflow */
957 bfd_elf_generic_reloc, /* special_function */
958 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19), /* name */
959 FALSE, /* partial_inplace */
960 0x1ffffc, /* src_mask */
961 0x1ffffc, /* dst_mask */
962 FALSE), /* pcrel_offset */
964 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
966 2, /* size (0 = byte, 1 = short, 2 = long) */
968 FALSE, /* pc_relative */
970 complain_overflow_dont, /* complain_on_overflow */
971 bfd_elf_generic_reloc, /* special_function */
972 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2), /* name */
973 FALSE, /* partial_inplace */
974 0xffff, /* src_mask */
975 0xffff, /* dst_mask */
976 FALSE), /* pcrel_offset */
978 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1), /* type */
980 2, /* size (0 = byte, 1 = short, 2 = long) */
982 FALSE, /* pc_relative */
984 complain_overflow_dont, /* complain_on_overflow */
985 bfd_elf_generic_reloc, /* special_function */
986 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1), /* name */
987 FALSE, /* partial_inplace */
988 0xffff, /* src_mask */
989 0xffff, /* dst_mask */
990 FALSE), /* pcrel_offset */
992 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC), /* type */
994 2, /* size (0 = byte, 1 = short, 2 = long) */
996 FALSE, /* pc_relative */
998 complain_overflow_dont, /* complain_on_overflow */
999 bfd_elf_generic_reloc, /* special_function */
1000 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC), /* name */
1001 FALSE, /* partial_inplace */
1002 0xffff, /* src_mask */
1003 0xffff, /* dst_mask */
1004 FALSE), /* pcrel_offset */
1006 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0), /* type */
1008 2, /* size (0 = byte, 1 = short, 2 = long) */
1010 FALSE, /* pc_relative */
1012 complain_overflow_dont, /* complain_on_overflow */
1013 bfd_elf_generic_reloc, /* special_function */
1014 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0), /* name */
1015 FALSE, /* partial_inplace */
1016 0xffff, /* src_mask */
1017 0xffff, /* dst_mask */
1018 FALSE), /* pcrel_offset */
1020 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC), /* type */
1022 2, /* size (0 = byte, 1 = short, 2 = long) */
1024 FALSE, /* pc_relative */
1026 complain_overflow_dont, /* complain_on_overflow */
1027 bfd_elf_generic_reloc, /* special_function */
1028 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC), /* name */
1029 FALSE, /* partial_inplace */
1030 0xffff, /* src_mask */
1031 0xffff, /* dst_mask */
1032 FALSE), /* pcrel_offset */
1034 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12), /* type */
1035 12, /* rightshift */
1036 2, /* size (0 = byte, 1 = short, 2 = long) */
1038 FALSE, /* pc_relative */
1040 complain_overflow_dont, /* complain_on_overflow */
1041 bfd_elf_generic_reloc, /* special_function */
1042 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12), /* name */
1043 FALSE, /* partial_inplace */
1044 0xfff, /* src_mask */
1045 0xfff, /* dst_mask */
1046 FALSE), /* pcrel_offset */
1048 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12), /* type */
1050 2, /* size (0 = byte, 1 = short, 2 = long) */
1052 FALSE, /* pc_relative */
1054 complain_overflow_dont, /* complain_on_overflow */
1055 bfd_elf_generic_reloc, /* special_function */
1056 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12), /* name */
1057 FALSE, /* partial_inplace */
1058 0xfff, /* src_mask */
1059 0xfff, /* dst_mask */
1060 FALSE), /* pcrel_offset */
1062 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC), /* type */
1064 2, /* size (0 = byte, 1 = short, 2 = long) */
1066 FALSE, /* pc_relative */
1068 complain_overflow_dont, /* complain_on_overflow */
1069 bfd_elf_generic_reloc, /* special_function */
1070 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC), /* name */
1071 FALSE, /* partial_inplace */
1072 0xfff, /* src_mask */
1073 0xfff, /* dst_mask */
1074 FALSE), /* pcrel_offset */
1076 HOWTO (AARCH64_R (TLSDESC_LD_PREL19), /* type */
1078 2, /* size (0 = byte, 1 = short, 2 = long) */
1080 TRUE, /* pc_relative */
1082 complain_overflow_dont, /* complain_on_overflow */
1083 bfd_elf_generic_reloc, /* special_function */
1084 AARCH64_R_STR (TLSDESC_LD_PREL19), /* name */
1085 FALSE, /* partial_inplace */
1086 0x1ffffc, /* src_mask */
1087 0x1ffffc, /* dst_mask */
1088 TRUE), /* pcrel_offset */
1090 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21), /* type */
1092 2, /* size (0 = byte, 1 = short, 2 = long) */
1094 TRUE, /* pc_relative */
1096 complain_overflow_dont, /* complain_on_overflow */
1097 bfd_elf_generic_reloc, /* special_function */
1098 AARCH64_R_STR (TLSDESC_ADR_PREL21), /* name */
1099 FALSE, /* partial_inplace */
1100 0x1fffff, /* src_mask */
1101 0x1fffff, /* dst_mask */
1102 TRUE), /* pcrel_offset */
1104 /* Get to the page for the GOT entry for the symbol
1105 (G(S) - P) using an ADRP instruction. */
1106 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21), /* type */
1107 12, /* rightshift */
1108 2, /* size (0 = byte, 1 = short, 2 = long) */
1110 TRUE, /* pc_relative */
1112 complain_overflow_dont, /* complain_on_overflow */
1113 bfd_elf_generic_reloc, /* special_function */
1114 AARCH64_R_STR (TLSDESC_ADR_PAGE21), /* name */
1115 FALSE, /* partial_inplace */
1116 0x1fffff, /* src_mask */
1117 0x1fffff, /* dst_mask */
1118 TRUE), /* pcrel_offset */
1120 /* LD64: GOT offset G(S) & 0xff8. */
1121 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC), /* type */
1123 2, /* size (0 = byte, 1 = short, 2 = long) */
1125 FALSE, /* pc_relative */
1127 complain_overflow_dont, /* complain_on_overflow */
1128 bfd_elf_generic_reloc, /* special_function */
1129 AARCH64_R_STR (TLSDESC_LD64_LO12_NC), /* name */
1130 FALSE, /* partial_inplace */
1131 0xff8, /* src_mask */
1132 0xff8, /* dst_mask */
1133 FALSE), /* pcrel_offset */
1135 /* LD32: GOT offset G(S) & 0xffc. */
1136 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC), /* type */
1138 2, /* size (0 = byte, 1 = short, 2 = long) */
1140 FALSE, /* pc_relative */
1142 complain_overflow_dont, /* complain_on_overflow */
1143 bfd_elf_generic_reloc, /* special_function */
1144 AARCH64_R_STR (TLSDESC_LD32_LO12_NC), /* name */
1145 FALSE, /* partial_inplace */
1146 0xffc, /* src_mask */
1147 0xffc, /* dst_mask */
1148 FALSE), /* pcrel_offset */
1150 /* ADD: GOT offset G(S) & 0xfff. */
1151 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC), /* type */
1153 2, /* size (0 = byte, 1 = short, 2 = long) */
1155 FALSE, /* pc_relative */
1157 complain_overflow_dont, /* complain_on_overflow */
1158 bfd_elf_generic_reloc, /* special_function */
1159 AARCH64_R_STR (TLSDESC_ADD_LO12_NC), /* name */
1160 FALSE, /* partial_inplace */
1161 0xfff, /* src_mask */
1162 0xfff, /* dst_mask */
1163 FALSE), /* pcrel_offset */
1165 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1), /* type */
1166 16, /* rightshift */
1167 2, /* size (0 = byte, 1 = short, 2 = long) */
1169 FALSE, /* pc_relative */
1171 complain_overflow_dont, /* complain_on_overflow */
1172 bfd_elf_generic_reloc, /* special_function */
1173 AARCH64_R_STR (TLSDESC_OFF_G1), /* name */
1174 FALSE, /* partial_inplace */
1175 0xffff, /* src_mask */
1176 0xffff, /* dst_mask */
1177 FALSE), /* pcrel_offset */
1179 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC), /* type */
1181 2, /* size (0 = byte, 1 = short, 2 = long) */
1183 FALSE, /* pc_relative */
1185 complain_overflow_dont, /* complain_on_overflow */
1186 bfd_elf_generic_reloc, /* special_function */
1187 AARCH64_R_STR (TLSDESC_OFF_G0_NC), /* name */
1188 FALSE, /* partial_inplace */
1189 0xffff, /* src_mask */
1190 0xffff, /* dst_mask */
1191 FALSE), /* pcrel_offset */
1193 HOWTO64 (AARCH64_R (TLSDESC_LDR), /* type */
1195 2, /* size (0 = byte, 1 = short, 2 = long) */
1197 FALSE, /* pc_relative */
1199 complain_overflow_dont, /* complain_on_overflow */
1200 bfd_elf_generic_reloc, /* special_function */
1201 AARCH64_R_STR (TLSDESC_LDR), /* name */
1202 FALSE, /* partial_inplace */
1205 FALSE), /* pcrel_offset */
1207 HOWTO64 (AARCH64_R (TLSDESC_ADD), /* type */
1209 2, /* size (0 = byte, 1 = short, 2 = long) */
1211 FALSE, /* pc_relative */
1213 complain_overflow_dont, /* complain_on_overflow */
1214 bfd_elf_generic_reloc, /* special_function */
1215 AARCH64_R_STR (TLSDESC_ADD), /* name */
1216 FALSE, /* partial_inplace */
1219 FALSE), /* pcrel_offset */
1221 HOWTO (AARCH64_R (TLSDESC_CALL), /* type */
1223 2, /* size (0 = byte, 1 = short, 2 = long) */
1225 FALSE, /* pc_relative */
1227 complain_overflow_dont, /* complain_on_overflow */
1228 bfd_elf_generic_reloc, /* special_function */
1229 AARCH64_R_STR (TLSDESC_CALL), /* name */
1230 FALSE, /* partial_inplace */
1233 FALSE), /* pcrel_offset */
1235 HOWTO (AARCH64_R (COPY), /* type */
1237 2, /* size (0 = byte, 1 = short, 2 = long) */
1239 FALSE, /* pc_relative */
1241 complain_overflow_bitfield, /* complain_on_overflow */
1242 bfd_elf_generic_reloc, /* special_function */
1243 AARCH64_R_STR (COPY), /* name */
1244 TRUE, /* partial_inplace */
1245 0xffffffff, /* src_mask */
1246 0xffffffff, /* dst_mask */
1247 FALSE), /* pcrel_offset */
1249 HOWTO (AARCH64_R (GLOB_DAT), /* type */
1251 2, /* size (0 = byte, 1 = short, 2 = long) */
1253 FALSE, /* pc_relative */
1255 complain_overflow_bitfield, /* complain_on_overflow */
1256 bfd_elf_generic_reloc, /* special_function */
1257 AARCH64_R_STR (GLOB_DAT), /* name */
1258 TRUE, /* partial_inplace */
1259 0xffffffff, /* src_mask */
1260 0xffffffff, /* dst_mask */
1261 FALSE), /* pcrel_offset */
1263 HOWTO (AARCH64_R (JUMP_SLOT), /* type */
1265 2, /* size (0 = byte, 1 = short, 2 = long) */
1267 FALSE, /* pc_relative */
1269 complain_overflow_bitfield, /* complain_on_overflow */
1270 bfd_elf_generic_reloc, /* special_function */
1271 AARCH64_R_STR (JUMP_SLOT), /* name */
1272 TRUE, /* partial_inplace */
1273 0xffffffff, /* src_mask */
1274 0xffffffff, /* dst_mask */
1275 FALSE), /* pcrel_offset */
1277 HOWTO (AARCH64_R (RELATIVE), /* type */
1279 2, /* size (0 = byte, 1 = short, 2 = long) */
1281 FALSE, /* pc_relative */
1283 complain_overflow_bitfield, /* complain_on_overflow */
1284 bfd_elf_generic_reloc, /* special_function */
1285 AARCH64_R_STR (RELATIVE), /* name */
1286 TRUE, /* partial_inplace */
1287 ALL_ONES, /* src_mask */
1288 ALL_ONES, /* dst_mask */
1289 FALSE), /* pcrel_offset */
1291 HOWTO (AARCH64_R (TLS_DTPMOD), /* type */
1293 2, /* size (0 = byte, 1 = short, 2 = long) */
1295 FALSE, /* pc_relative */
1297 complain_overflow_dont, /* complain_on_overflow */
1298 bfd_elf_generic_reloc, /* special_function */
1299 AARCH64_R_STR (TLS_DTPMOD), /* name */
1300 FALSE, /* partial_inplace */
1302 ALL_ONES, /* dst_mask */
1303 FALSE), /* pc_reloffset */
1305 HOWTO (AARCH64_R (TLS_DTPREL), /* type */
1307 2, /* size (0 = byte, 1 = short, 2 = long) */
1309 FALSE, /* pc_relative */
1311 complain_overflow_dont, /* complain_on_overflow */
1312 bfd_elf_generic_reloc, /* special_function */
1313 AARCH64_R_STR (TLS_DTPREL), /* name */
1314 FALSE, /* partial_inplace */
1316 ALL_ONES, /* dst_mask */
1317 FALSE), /* pcrel_offset */
1319 HOWTO (AARCH64_R (TLS_TPREL), /* type */
1321 2, /* size (0 = byte, 1 = short, 2 = long) */
1323 FALSE, /* pc_relative */
1325 complain_overflow_dont, /* complain_on_overflow */
1326 bfd_elf_generic_reloc, /* special_function */
1327 AARCH64_R_STR (TLS_TPREL), /* name */
1328 FALSE, /* partial_inplace */
1330 ALL_ONES, /* dst_mask */
1331 FALSE), /* pcrel_offset */
1333 HOWTO (AARCH64_R (TLSDESC), /* type */
1335 2, /* size (0 = byte, 1 = short, 2 = long) */
1337 FALSE, /* pc_relative */
1339 complain_overflow_dont, /* complain_on_overflow */
1340 bfd_elf_generic_reloc, /* special_function */
1341 AARCH64_R_STR (TLSDESC), /* name */
1342 FALSE, /* partial_inplace */
1344 ALL_ONES, /* dst_mask */
1345 FALSE), /* pcrel_offset */
1347 HOWTO (AARCH64_R (IRELATIVE), /* type */
1349 2, /* size (0 = byte, 1 = short, 2 = long) */
1351 FALSE, /* pc_relative */
1353 complain_overflow_bitfield, /* complain_on_overflow */
1354 bfd_elf_generic_reloc, /* special_function */
1355 AARCH64_R_STR (IRELATIVE), /* name */
1356 FALSE, /* partial_inplace */
1358 ALL_ONES, /* dst_mask */
1359 FALSE), /* pcrel_offset */
1364 static reloc_howto_type elfNN_aarch64_howto_none =
1365 HOWTO (R_AARCH64_NONE, /* type */
1367 0, /* size (0 = byte, 1 = short, 2 = long) */
1369 FALSE, /* pc_relative */
1371 complain_overflow_dont,/* complain_on_overflow */
1372 bfd_elf_generic_reloc, /* special_function */
1373 "R_AARCH64_NONE", /* name */
1374 FALSE, /* partial_inplace */
1377 FALSE); /* pcrel_offset */
1379 /* Given HOWTO, return the bfd internal relocation enumerator. */
1381 static bfd_reloc_code_real_type
1382 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type *howto)
1385 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table);
1386 const ptrdiff_t offset
1387 = howto - elfNN_aarch64_howto_table;
1389 if (offset > 0 && offset < size - 1)
1390 return BFD_RELOC_AARCH64_RELOC_START + offset;
1392 if (howto == &elfNN_aarch64_howto_none)
1393 return BFD_RELOC_AARCH64_NONE;
1395 return BFD_RELOC_AARCH64_RELOC_START;
1398 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1400 static bfd_reloc_code_real_type
1401 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type)
1403 static bfd_boolean initialized_p = FALSE;
1404 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1405 static unsigned int offsets[R_AARCH64_end];
1407 if (initialized_p == FALSE)
1411 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
1412 if (elfNN_aarch64_howto_table[i].type != 0)
1413 offsets[elfNN_aarch64_howto_table[i].type] = i;
1415 initialized_p = TRUE;
1418 if (r_type == R_AARCH64_NONE || r_type == R_AARCH64_NULL)
1419 return BFD_RELOC_AARCH64_NONE;
1421 return BFD_RELOC_AARCH64_RELOC_START + offsets[r_type];
1424 struct elf_aarch64_reloc_map
1426 bfd_reloc_code_real_type from;
1427 bfd_reloc_code_real_type to;
1430 /* Map bfd generic reloc to AArch64-specific reloc. */
1431 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map[] =
1433 {BFD_RELOC_NONE, BFD_RELOC_AARCH64_NONE},
1435 /* Basic data relocations. */
1436 {BFD_RELOC_CTOR, BFD_RELOC_AARCH64_NN},
1437 {BFD_RELOC_64, BFD_RELOC_AARCH64_64},
1438 {BFD_RELOC_32, BFD_RELOC_AARCH64_32},
1439 {BFD_RELOC_16, BFD_RELOC_AARCH64_16},
1440 {BFD_RELOC_64_PCREL, BFD_RELOC_AARCH64_64_PCREL},
1441 {BFD_RELOC_32_PCREL, BFD_RELOC_AARCH64_32_PCREL},
1442 {BFD_RELOC_16_PCREL, BFD_RELOC_AARCH64_16_PCREL},
1445 /* Given the bfd internal relocation enumerator in CODE, return the
1446 corresponding howto entry. */
1448 static reloc_howto_type *
1449 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
1453 /* Convert bfd generic reloc to AArch64-specific reloc. */
1454 if (code < BFD_RELOC_AARCH64_RELOC_START
1455 || code > BFD_RELOC_AARCH64_RELOC_END)
1456 for (i = 0; i < ARRAY_SIZE (elf_aarch64_reloc_map); i++)
1457 if (elf_aarch64_reloc_map[i].from == code)
1459 code = elf_aarch64_reloc_map[i].to;
1463 if (code > BFD_RELOC_AARCH64_RELOC_START
1464 && code < BFD_RELOC_AARCH64_RELOC_END)
1465 if (elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START].type)
1466 return &elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START];
1471 static reloc_howto_type *
1472 elfNN_aarch64_howto_from_type (unsigned int r_type)
1474 bfd_reloc_code_real_type val;
1475 reloc_howto_type *howto;
1480 bfd_set_error (bfd_error_bad_value);
1485 if (r_type == R_AARCH64_NONE)
1486 return &elfNN_aarch64_howto_none;
1488 val = elfNN_aarch64_bfd_reloc_from_type (r_type);
1489 howto = elfNN_aarch64_howto_from_bfd_reloc (val);
1494 bfd_set_error (bfd_error_bad_value);
1499 elfNN_aarch64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
1500 Elf_Internal_Rela *elf_reloc)
1502 unsigned int r_type;
1504 r_type = ELFNN_R_TYPE (elf_reloc->r_info);
1505 bfd_reloc->howto = elfNN_aarch64_howto_from_type (r_type);
1508 static reloc_howto_type *
1509 elfNN_aarch64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1510 bfd_reloc_code_real_type code)
1512 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (code);
1517 bfd_set_error (bfd_error_bad_value);
1521 static reloc_howto_type *
1522 elfNN_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1527 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
1528 if (elfNN_aarch64_howto_table[i].name != NULL
1529 && strcasecmp (elfNN_aarch64_howto_table[i].name, r_name) == 0)
1530 return &elfNN_aarch64_howto_table[i];
1535 #define TARGET_LITTLE_SYM bfd_elfNN_littleaarch64_vec
1536 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1537 #define TARGET_BIG_SYM bfd_elfNN_bigaarch64_vec
1538 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1540 /* The linker script knows the section names for placement.
1541 The entry_names are used to do simple name mangling on the stubs.
1542 Given a function name, and its type, the stub can be found. The
1543 name can be changed. The only requirement is the %s be present. */
1544 #define STUB_ENTRY_NAME "__%s_veneer"
1546 /* The name of the dynamic interpreter. This is put in the .interp
1548 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1550 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1551 (((1 << 25) - 1) << 2)
1552 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1555 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1556 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1559 aarch64_valid_for_adrp_p (bfd_vma value, bfd_vma place)
1561 bfd_signed_vma offset = (bfd_signed_vma) (PG (value) - PG (place)) >> 12;
1562 return offset <= AARCH64_MAX_ADRP_IMM && offset >= AARCH64_MIN_ADRP_IMM;
1566 aarch64_valid_branch_p (bfd_vma value, bfd_vma place)
1568 bfd_signed_vma offset = (bfd_signed_vma) (value - place);
1569 return (offset <= AARCH64_MAX_FWD_BRANCH_OFFSET
1570 && offset >= AARCH64_MAX_BWD_BRANCH_OFFSET);
1573 static const uint32_t aarch64_adrp_branch_stub [] =
1575 0x90000010, /* adrp ip0, X */
1576 /* R_AARCH64_ADR_HI21_PCREL(X) */
1577 0x91000210, /* add ip0, ip0, :lo12:X */
1578 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
1579 0xd61f0200, /* br ip0 */
1582 static const uint32_t aarch64_long_branch_stub[] =
1585 0x58000090, /* ldr ip0, 1f */
1587 0x18000090, /* ldr wip0, 1f */
1589 0x10000011, /* adr ip1, #0 */
1590 0x8b110210, /* add ip0, ip0, ip1 */
1591 0xd61f0200, /* br ip0 */
1592 0x00000000, /* 1: .xword or .word
1593 R_AARCH64_PRELNN(X) + 12
1598 /* Section name for stubs is the associated section name plus this
1600 #define STUB_SUFFIX ".stub"
1602 enum elf_aarch64_stub_type
1605 aarch64_stub_adrp_branch,
1606 aarch64_stub_long_branch,
1609 struct elf_aarch64_stub_hash_entry
1611 /* Base hash table entry structure. */
1612 struct bfd_hash_entry root;
1614 /* The stub section. */
1617 /* Offset within stub_sec of the beginning of this stub. */
1618 bfd_vma stub_offset;
1620 /* Given the symbol's value and its section we can determine its final
1621 value when building the stubs (so the stub knows where to jump). */
1622 bfd_vma target_value;
1623 asection *target_section;
1625 enum elf_aarch64_stub_type stub_type;
1627 /* The symbol table entry, if any, that this was derived from. */
1628 struct elf_aarch64_link_hash_entry *h;
1630 /* Destination symbol type */
1631 unsigned char st_type;
1633 /* Where this stub is being called from, or, in the case of combined
1634 stub sections, the first input section in the group. */
1637 /* The name for the local symbol at the start of this stub. The
1638 stub name in the hash table has to be unique; this does not, so
1639 it can be friendlier. */
1643 /* Used to build a map of a section. This is required for mixed-endian
1646 typedef struct elf_elf_section_map
1651 elf_aarch64_section_map;
1654 typedef struct _aarch64_elf_section_data
1656 struct bfd_elf_section_data elf;
1657 unsigned int mapcount;
1658 unsigned int mapsize;
1659 elf_aarch64_section_map *map;
1661 _aarch64_elf_section_data;
1663 #define elf_aarch64_section_data(sec) \
1664 ((_aarch64_elf_section_data *) elf_section_data (sec))
1666 /* The size of the thread control block. */
1669 struct elf_aarch64_local_symbol
1671 unsigned int got_type;
1672 bfd_signed_vma got_refcount;
1675 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
1676 offset is from the end of the jump table and reserved entries
1679 The magic value (bfd_vma) -1 indicates that an offset has not be
1681 bfd_vma tlsdesc_got_jump_table_offset;
1684 struct elf_aarch64_obj_tdata
1686 struct elf_obj_tdata root;
1688 /* local symbol descriptors */
1689 struct elf_aarch64_local_symbol *locals;
1691 /* Zero to warn when linking objects with incompatible enum sizes. */
1692 int no_enum_size_warning;
1694 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
1695 int no_wchar_size_warning;
1698 #define elf_aarch64_tdata(bfd) \
1699 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
1701 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
1703 #define is_aarch64_elf(bfd) \
1704 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
1705 && elf_tdata (bfd) != NULL \
1706 && elf_object_id (bfd) == AARCH64_ELF_DATA)
1709 elfNN_aarch64_mkobject (bfd *abfd)
1711 return bfd_elf_allocate_object (abfd, sizeof (struct elf_aarch64_obj_tdata),
1715 #define elf_aarch64_hash_entry(ent) \
1716 ((struct elf_aarch64_link_hash_entry *)(ent))
1718 #define GOT_UNKNOWN 0
1719 #define GOT_NORMAL 1
1720 #define GOT_TLS_GD 2
1721 #define GOT_TLS_IE 4
1722 #define GOT_TLSDESC_GD 8
1724 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
1726 /* AArch64 ELF linker hash entry. */
1727 struct elf_aarch64_link_hash_entry
1729 struct elf_link_hash_entry root;
1731 /* Track dynamic relocs copied for this symbol. */
1732 struct elf_dyn_relocs *dyn_relocs;
1734 /* Since PLT entries have variable size, we need to record the
1735 index into .got.plt instead of recomputing it from the PLT
1737 bfd_signed_vma plt_got_offset;
1739 /* Bit mask representing the type of GOT entry(s) if any required by
1741 unsigned int got_type;
1743 /* A pointer to the most recently used stub hash entry against this
1745 struct elf_aarch64_stub_hash_entry *stub_cache;
1747 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
1748 is from the end of the jump table and reserved entries within the PLTGOT.
1750 The magic value (bfd_vma) -1 indicates that an offset has not
1752 bfd_vma tlsdesc_got_jump_table_offset;
1756 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry *h,
1758 unsigned long r_symndx)
1761 return elf_aarch64_hash_entry (h)->got_type;
1763 if (! elf_aarch64_locals (abfd))
1766 return elf_aarch64_locals (abfd)[r_symndx].got_type;
1769 /* Get the AArch64 elf linker hash table from a link_info structure. */
1770 #define elf_aarch64_hash_table(info) \
1771 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
1773 #define aarch64_stub_hash_lookup(table, string, create, copy) \
1774 ((struct elf_aarch64_stub_hash_entry *) \
1775 bfd_hash_lookup ((table), (string), (create), (copy)))
1777 /* AArch64 ELF linker hash table. */
1778 struct elf_aarch64_link_hash_table
1780 /* The main hash table. */
1781 struct elf_link_hash_table root;
1783 /* Nonzero to force PIC branch veneers. */
1786 /* The number of bytes in the initial entry in the PLT. */
1787 bfd_size_type plt_header_size;
1789 /* The number of bytes in the subsequent PLT etries. */
1790 bfd_size_type plt_entry_size;
1792 /* Short-cuts to get to dynamic linker sections. */
1796 /* Small local sym cache. */
1797 struct sym_cache sym_cache;
1799 /* For convenience in allocate_dynrelocs. */
1802 /* The amount of space used by the reserved portion of the sgotplt
1803 section, plus whatever space is used by the jump slots. */
1804 bfd_vma sgotplt_jump_table_size;
1806 /* The stub hash table. */
1807 struct bfd_hash_table stub_hash_table;
1809 /* Linker stub bfd. */
1812 /* Linker call-backs. */
1813 asection *(*add_stub_section) (const char *, asection *);
1814 void (*layout_sections_again) (void);
1816 /* Array to keep track of which stub sections have been created, and
1817 information on stub grouping. */
1820 /* This is the section to which stubs in the group will be
1823 /* The stub section. */
1827 /* Assorted information used by elfNN_aarch64_size_stubs. */
1828 unsigned int bfd_count;
1830 asection **input_list;
1832 /* The offset into splt of the PLT entry for the TLS descriptor
1833 resolver. Special values are 0, if not necessary (or not found
1834 to be necessary yet), and -1 if needed but not determined
1836 bfd_vma tlsdesc_plt;
1838 /* The GOT offset for the lazy trampoline. Communicated to the
1839 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
1840 indicates an offset is not allocated. */
1841 bfd_vma dt_tlsdesc_got;
1844 /* Create an entry in an AArch64 ELF linker hash table. */
1846 static struct bfd_hash_entry *
1847 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
1848 struct bfd_hash_table *table,
1851 struct elf_aarch64_link_hash_entry *ret =
1852 (struct elf_aarch64_link_hash_entry *) entry;
1854 /* Allocate the structure if it has not already been allocated by a
1857 ret = bfd_hash_allocate (table,
1858 sizeof (struct elf_aarch64_link_hash_entry));
1860 return (struct bfd_hash_entry *) ret;
1862 /* Call the allocation method of the superclass. */
1863 ret = ((struct elf_aarch64_link_hash_entry *)
1864 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1868 ret->dyn_relocs = NULL;
1869 ret->got_type = GOT_UNKNOWN;
1870 ret->plt_got_offset = (bfd_vma) - 1;
1871 ret->stub_cache = NULL;
1872 ret->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
1875 return (struct bfd_hash_entry *) ret;
1878 /* Initialize an entry in the stub hash table. */
1880 static struct bfd_hash_entry *
1881 stub_hash_newfunc (struct bfd_hash_entry *entry,
1882 struct bfd_hash_table *table, const char *string)
1884 /* Allocate the structure if it has not already been allocated by a
1888 entry = bfd_hash_allocate (table,
1890 elf_aarch64_stub_hash_entry));
1895 /* Call the allocation method of the superclass. */
1896 entry = bfd_hash_newfunc (entry, table, string);
1899 struct elf_aarch64_stub_hash_entry *eh;
1901 /* Initialize the local fields. */
1902 eh = (struct elf_aarch64_stub_hash_entry *) entry;
1903 eh->stub_sec = NULL;
1904 eh->stub_offset = 0;
1905 eh->target_value = 0;
1906 eh->target_section = NULL;
1907 eh->stub_type = aarch64_stub_none;
1916 /* Copy the extra info we tack onto an elf_link_hash_entry. */
1919 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
1920 struct elf_link_hash_entry *dir,
1921 struct elf_link_hash_entry *ind)
1923 struct elf_aarch64_link_hash_entry *edir, *eind;
1925 edir = (struct elf_aarch64_link_hash_entry *) dir;
1926 eind = (struct elf_aarch64_link_hash_entry *) ind;
1928 if (eind->dyn_relocs != NULL)
1930 if (edir->dyn_relocs != NULL)
1932 struct elf_dyn_relocs **pp;
1933 struct elf_dyn_relocs *p;
1935 /* Add reloc counts against the indirect sym to the direct sym
1936 list. Merge any entries against the same section. */
1937 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
1939 struct elf_dyn_relocs *q;
1941 for (q = edir->dyn_relocs; q != NULL; q = q->next)
1942 if (q->sec == p->sec)
1944 q->pc_count += p->pc_count;
1945 q->count += p->count;
1952 *pp = edir->dyn_relocs;
1955 edir->dyn_relocs = eind->dyn_relocs;
1956 eind->dyn_relocs = NULL;
1959 if (ind->root.type == bfd_link_hash_indirect)
1961 /* Copy over PLT info. */
1962 if (dir->got.refcount <= 0)
1964 edir->got_type = eind->got_type;
1965 eind->got_type = GOT_UNKNOWN;
1969 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
1972 /* Create an AArch64 elf linker hash table. */
1974 static struct bfd_link_hash_table *
1975 elfNN_aarch64_link_hash_table_create (bfd *abfd)
1977 struct elf_aarch64_link_hash_table *ret;
1978 bfd_size_type amt = sizeof (struct elf_aarch64_link_hash_table);
1980 ret = bfd_zmalloc (amt);
1984 if (!_bfd_elf_link_hash_table_init
1985 (&ret->root, abfd, elfNN_aarch64_link_hash_newfunc,
1986 sizeof (struct elf_aarch64_link_hash_entry), AARCH64_ELF_DATA))
1992 ret->plt_header_size = PLT_ENTRY_SIZE;
1993 ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
1995 ret->dt_tlsdesc_got = (bfd_vma) - 1;
1997 if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
1998 sizeof (struct elf_aarch64_stub_hash_entry)))
2004 return &ret->root.root;
2007 /* Free the derived linker hash table. */
2010 elfNN_aarch64_hash_table_free (struct bfd_link_hash_table *hash)
2012 struct elf_aarch64_link_hash_table *ret
2013 = (struct elf_aarch64_link_hash_table *) hash;
2015 bfd_hash_table_free (&ret->stub_hash_table);
2016 _bfd_elf_link_hash_table_free (hash);
2020 aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
2021 bfd_vma offset, bfd_vma value)
2023 reloc_howto_type *howto;
2026 howto = elfNN_aarch64_howto_from_type (r_type);
2027 place = (input_section->output_section->vma + input_section->output_offset
2030 r_type = elfNN_aarch64_bfd_reloc_from_type (r_type);
2031 value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE);
2032 return _bfd_aarch64_elf_put_addend (input_bfd,
2033 input_section->contents + offset, r_type,
2037 static enum elf_aarch64_stub_type
2038 aarch64_select_branch_stub (bfd_vma value, bfd_vma place)
2040 if (aarch64_valid_for_adrp_p (value, place))
2041 return aarch64_stub_adrp_branch;
2042 return aarch64_stub_long_branch;
2045 /* Determine the type of stub needed, if any, for a call. */
2047 static enum elf_aarch64_stub_type
2048 aarch64_type_of_stub (struct bfd_link_info *info,
2049 asection *input_sec,
2050 const Elf_Internal_Rela *rel,
2051 unsigned char st_type,
2052 struct elf_aarch64_link_hash_entry *hash,
2053 bfd_vma destination)
2056 bfd_signed_vma branch_offset;
2057 unsigned int r_type;
2058 struct elf_aarch64_link_hash_table *globals;
2059 enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
2060 bfd_boolean via_plt_p;
2062 if (st_type != STT_FUNC)
2065 globals = elf_aarch64_hash_table (info);
2066 via_plt_p = (globals->root.splt != NULL && hash != NULL
2067 && hash->root.plt.offset != (bfd_vma) - 1);
2072 /* Determine where the call point is. */
2073 location = (input_sec->output_offset
2074 + input_sec->output_section->vma + rel->r_offset);
2076 branch_offset = (bfd_signed_vma) (destination - location);
2078 r_type = ELFNN_R_TYPE (rel->r_info);
2080 /* We don't want to redirect any old unconditional jump in this way,
2081 only one which is being used for a sibcall, where it is
2082 acceptable for the IP0 and IP1 registers to be clobbered. */
2083 if ((r_type == AARCH64_R (CALL26) || r_type == AARCH64_R (JUMP26))
2084 && (branch_offset > AARCH64_MAX_FWD_BRANCH_OFFSET
2085 || branch_offset < AARCH64_MAX_BWD_BRANCH_OFFSET))
2087 stub_type = aarch64_stub_long_branch;
2093 /* Build a name for an entry in the stub hash table. */
2096 elfNN_aarch64_stub_name (const asection *input_section,
2097 const asection *sym_sec,
2098 const struct elf_aarch64_link_hash_entry *hash,
2099 const Elf_Internal_Rela *rel)
2106 len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
2107 stub_name = bfd_malloc (len);
2108 if (stub_name != NULL)
2109 snprintf (stub_name, len, "%08x_%s+%" BFD_VMA_FMT "x",
2110 (unsigned int) input_section->id,
2111 hash->root.root.root.string,
2116 len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2117 stub_name = bfd_malloc (len);
2118 if (stub_name != NULL)
2119 snprintf (stub_name, len, "%08x_%x:%x+%" BFD_VMA_FMT "x",
2120 (unsigned int) input_section->id,
2121 (unsigned int) sym_sec->id,
2122 (unsigned int) ELFNN_R_SYM (rel->r_info),
2129 /* Look up an entry in the stub hash. Stub entries are cached because
2130 creating the stub name takes a bit of time. */
2132 static struct elf_aarch64_stub_hash_entry *
2133 elfNN_aarch64_get_stub_entry (const asection *input_section,
2134 const asection *sym_sec,
2135 struct elf_link_hash_entry *hash,
2136 const Elf_Internal_Rela *rel,
2137 struct elf_aarch64_link_hash_table *htab)
2139 struct elf_aarch64_stub_hash_entry *stub_entry;
2140 struct elf_aarch64_link_hash_entry *h =
2141 (struct elf_aarch64_link_hash_entry *) hash;
2142 const asection *id_sec;
2144 if ((input_section->flags & SEC_CODE) == 0)
2147 /* If this input section is part of a group of sections sharing one
2148 stub section, then use the id of the first section in the group.
2149 Stub names need to include a section id, as there may well be
2150 more than one stub used to reach say, printf, and we need to
2151 distinguish between them. */
2152 id_sec = htab->stub_group[input_section->id].link_sec;
2154 if (h != NULL && h->stub_cache != NULL
2155 && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
2157 stub_entry = h->stub_cache;
2163 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, h, rel);
2164 if (stub_name == NULL)
2167 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
2168 stub_name, FALSE, FALSE);
2170 h->stub_cache = stub_entry;
2178 /* Add a new stub entry to the stub hash. Not all fields of the new
2179 stub entry are initialised. */
2181 static struct elf_aarch64_stub_hash_entry *
2182 elfNN_aarch64_add_stub (const char *stub_name,
2184 struct elf_aarch64_link_hash_table *htab)
2188 struct elf_aarch64_stub_hash_entry *stub_entry;
2190 link_sec = htab->stub_group[section->id].link_sec;
2191 stub_sec = htab->stub_group[section->id].stub_sec;
2192 if (stub_sec == NULL)
2194 stub_sec = htab->stub_group[link_sec->id].stub_sec;
2195 if (stub_sec == NULL)
2201 namelen = strlen (link_sec->name);
2202 len = namelen + sizeof (STUB_SUFFIX);
2203 s_name = bfd_alloc (htab->stub_bfd, len);
2207 memcpy (s_name, link_sec->name, namelen);
2208 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
2209 stub_sec = (*htab->add_stub_section) (s_name, link_sec);
2210 if (stub_sec == NULL)
2212 htab->stub_group[link_sec->id].stub_sec = stub_sec;
2214 htab->stub_group[section->id].stub_sec = stub_sec;
2217 /* Enter this entry into the linker stub hash table. */
2218 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
2220 if (stub_entry == NULL)
2222 (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
2223 section->owner, stub_name);
2227 stub_entry->stub_sec = stub_sec;
2228 stub_entry->stub_offset = 0;
2229 stub_entry->id_sec = link_sec;
2235 aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
2236 void *in_arg ATTRIBUTE_UNUSED)
2238 struct elf_aarch64_stub_hash_entry *stub_entry;
2243 unsigned int template_size;
2244 const uint32_t *template;
2247 /* Massage our args to the form they really have. */
2248 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
2250 stub_sec = stub_entry->stub_sec;
2252 /* Make a note of the offset within the stubs for this entry. */
2253 stub_entry->stub_offset = stub_sec->size;
2254 loc = stub_sec->contents + stub_entry->stub_offset;
2256 stub_bfd = stub_sec->owner;
2258 /* This is the address of the stub destination. */
2259 sym_value = (stub_entry->target_value
2260 + stub_entry->target_section->output_offset
2261 + stub_entry->target_section->output_section->vma);
2263 if (stub_entry->stub_type == aarch64_stub_long_branch)
2265 bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
2266 + stub_sec->output_offset);
2268 /* See if we can relax the stub. */
2269 if (aarch64_valid_for_adrp_p (sym_value, place))
2270 stub_entry->stub_type = aarch64_select_branch_stub (sym_value, place);
2273 switch (stub_entry->stub_type)
2275 case aarch64_stub_adrp_branch:
2276 template = aarch64_adrp_branch_stub;
2277 template_size = sizeof (aarch64_adrp_branch_stub);
2279 case aarch64_stub_long_branch:
2280 template = aarch64_long_branch_stub;
2281 template_size = sizeof (aarch64_long_branch_stub);
2288 for (i = 0; i < (template_size / sizeof template[0]); i++)
2290 bfd_putl32 (template[i], loc);
2294 template_size = (template_size + 7) & ~7;
2295 stub_sec->size += template_size;
2297 switch (stub_entry->stub_type)
2299 case aarch64_stub_adrp_branch:
2300 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
2301 stub_entry->stub_offset, sym_value))
2302 /* The stub would not have been relaxed if the offset was out
2306 _bfd_final_link_relocate
2307 (elfNN_aarch64_howto_from_type (AARCH64_R (ADD_ABS_LO12_NC)),
2311 stub_entry->stub_offset + 4,
2316 case aarch64_stub_long_branch:
2317 /* We want the value relative to the address 12 bytes back from the
2319 _bfd_final_link_relocate (elfNN_aarch64_howto_from_type
2320 (AARCH64_R (PRELNN)), stub_bfd, stub_sec,
2322 stub_entry->stub_offset + 16,
2332 /* As above, but don't actually build the stub. Just bump offset so
2333 we know stub section sizes. */
2336 aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
2337 void *in_arg ATTRIBUTE_UNUSED)
2339 struct elf_aarch64_stub_hash_entry *stub_entry;
2342 /* Massage our args to the form they really have. */
2343 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
2345 switch (stub_entry->stub_type)
2347 case aarch64_stub_adrp_branch:
2348 size = sizeof (aarch64_adrp_branch_stub);
2350 case aarch64_stub_long_branch:
2351 size = sizeof (aarch64_long_branch_stub);
2359 size = (size + 7) & ~7;
2360 stub_entry->stub_sec->size += size;
2364 /* External entry points for sizing and building linker stubs. */
2366 /* Set up various things so that we can make a list of input sections
2367 for each output section included in the link. Returns -1 on error,
2368 0 when no stubs will be needed, and 1 on success. */
2371 elfNN_aarch64_setup_section_lists (bfd *output_bfd,
2372 struct bfd_link_info *info)
2375 unsigned int bfd_count;
2376 int top_id, top_index;
2378 asection **input_list, **list;
2380 struct elf_aarch64_link_hash_table *htab =
2381 elf_aarch64_hash_table (info);
2383 if (!is_elf_hash_table (htab))
2386 /* Count the number of input BFDs and find the top input section id. */
2387 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
2388 input_bfd != NULL; input_bfd = input_bfd->link_next)
2391 for (section = input_bfd->sections;
2392 section != NULL; section = section->next)
2394 if (top_id < section->id)
2395 top_id = section->id;
2398 htab->bfd_count = bfd_count;
2400 amt = sizeof (struct map_stub) * (top_id + 1);
2401 htab->stub_group = bfd_zmalloc (amt);
2402 if (htab->stub_group == NULL)
2405 /* We can't use output_bfd->section_count here to find the top output
2406 section index as some sections may have been removed, and
2407 _bfd_strip_section_from_output doesn't renumber the indices. */
2408 for (section = output_bfd->sections, top_index = 0;
2409 section != NULL; section = section->next)
2411 if (top_index < section->index)
2412 top_index = section->index;
2415 htab->top_index = top_index;
2416 amt = sizeof (asection *) * (top_index + 1);
2417 input_list = bfd_malloc (amt);
2418 htab->input_list = input_list;
2419 if (input_list == NULL)
2422 /* For sections we aren't interested in, mark their entries with a
2423 value we can check later. */
2424 list = input_list + top_index;
2426 *list = bfd_abs_section_ptr;
2427 while (list-- != input_list);
2429 for (section = output_bfd->sections;
2430 section != NULL; section = section->next)
2432 if ((section->flags & SEC_CODE) != 0)
2433 input_list[section->index] = NULL;
2439 /* Used by elfNN_aarch64_next_input_section and group_sections. */
2440 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
2442 /* The linker repeatedly calls this function for each input section,
2443 in the order that input sections are linked into output sections.
2444 Build lists of input sections to determine groupings between which
2445 we may insert linker stubs. */
2448 elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec)
2450 struct elf_aarch64_link_hash_table *htab =
2451 elf_aarch64_hash_table (info);
2453 if (isec->output_section->index <= htab->top_index)
2455 asection **list = htab->input_list + isec->output_section->index;
2457 if (*list != bfd_abs_section_ptr)
2459 /* Steal the link_sec pointer for our list. */
2460 /* This happens to make the list in reverse order,
2461 which is what we want. */
2462 PREV_SEC (isec) = *list;
2468 /* See whether we can group stub sections together. Grouping stub
2469 sections may result in fewer stubs. More importantly, we need to
2470 put all .init* and .fini* stubs at the beginning of the .init or
2471 .fini output sections respectively, because glibc splits the
2472 _init and _fini functions into multiple parts. Putting a stub in
2473 the middle of a function is not a good idea. */
2476 group_sections (struct elf_aarch64_link_hash_table *htab,
2477 bfd_size_type stub_group_size,
2478 bfd_boolean stubs_always_before_branch)
2480 asection **list = htab->input_list + htab->top_index;
2484 asection *tail = *list;
2486 if (tail == bfd_abs_section_ptr)
2489 while (tail != NULL)
2493 bfd_size_type total;
2497 while ((prev = PREV_SEC (curr)) != NULL
2498 && ((total += curr->output_offset - prev->output_offset)
2502 /* OK, the size from the start of CURR to the end is less
2503 than stub_group_size and thus can be handled by one stub
2504 section. (Or the tail section is itself larger than
2505 stub_group_size, in which case we may be toast.)
2506 We should really be keeping track of the total size of
2507 stubs added here, as stubs contribute to the final output
2511 prev = PREV_SEC (tail);
2512 /* Set up this stub group. */
2513 htab->stub_group[tail->id].link_sec = curr;
2515 while (tail != curr && (tail = prev) != NULL);
2517 /* But wait, there's more! Input sections up to stub_group_size
2518 bytes before the stub section can be handled by it too. */
2519 if (!stubs_always_before_branch)
2523 && ((total += tail->output_offset - prev->output_offset)
2527 prev = PREV_SEC (tail);
2528 htab->stub_group[tail->id].link_sec = curr;
2534 while (list-- != htab->input_list);
2536 free (htab->input_list);
2541 /* Determine and set the size of the stub section for a final link.
2543 The basic idea here is to examine all the relocations looking for
2544 PC-relative calls to a target that is unreachable with a "bl"
2548 elfNN_aarch64_size_stubs (bfd *output_bfd,
2550 struct bfd_link_info *info,
2551 bfd_signed_vma group_size,
2552 asection * (*add_stub_section) (const char *,
2554 void (*layout_sections_again) (void))
2556 bfd_size_type stub_group_size;
2557 bfd_boolean stubs_always_before_branch;
2558 bfd_boolean stub_changed = 0;
2559 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
2561 /* Propagate mach to stub bfd, because it may not have been
2562 finalized when we created stub_bfd. */
2563 bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
2564 bfd_get_mach (output_bfd));
2566 /* Stash our params away. */
2567 htab->stub_bfd = stub_bfd;
2568 htab->add_stub_section = add_stub_section;
2569 htab->layout_sections_again = layout_sections_again;
2570 stubs_always_before_branch = group_size < 0;
2572 stub_group_size = -group_size;
2574 stub_group_size = group_size;
2576 if (stub_group_size == 1)
2578 /* Default values. */
2579 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
2580 stub_group_size = 127 * 1024 * 1024;
2583 group_sections (htab, stub_group_size, stubs_always_before_branch);
2588 unsigned int bfd_indx;
2591 for (input_bfd = info->input_bfds, bfd_indx = 0;
2592 input_bfd != NULL; input_bfd = input_bfd->link_next, bfd_indx++)
2594 Elf_Internal_Shdr *symtab_hdr;
2596 Elf_Internal_Sym *local_syms = NULL;
2598 /* We'll need the symbol table in a second. */
2599 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2600 if (symtab_hdr->sh_info == 0)
2603 /* Walk over each section attached to the input bfd. */
2604 for (section = input_bfd->sections;
2605 section != NULL; section = section->next)
2607 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
2609 /* If there aren't any relocs, then there's nothing more
2611 if ((section->flags & SEC_RELOC) == 0
2612 || section->reloc_count == 0
2613 || (section->flags & SEC_CODE) == 0)
2616 /* If this section is a link-once section that will be
2617 discarded, then don't create any stubs. */
2618 if (section->output_section == NULL
2619 || section->output_section->owner != output_bfd)
2622 /* Get the relocs. */
2624 = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
2625 NULL, info->keep_memory);
2626 if (internal_relocs == NULL)
2627 goto error_ret_free_local;
2629 /* Now examine each relocation. */
2630 irela = internal_relocs;
2631 irelaend = irela + section->reloc_count;
2632 for (; irela < irelaend; irela++)
2634 unsigned int r_type, r_indx;
2635 enum elf_aarch64_stub_type stub_type;
2636 struct elf_aarch64_stub_hash_entry *stub_entry;
2639 bfd_vma destination;
2640 struct elf_aarch64_link_hash_entry *hash;
2641 const char *sym_name;
2643 const asection *id_sec;
2644 unsigned char st_type;
2647 r_type = ELFNN_R_TYPE (irela->r_info);
2648 r_indx = ELFNN_R_SYM (irela->r_info);
2650 if (r_type >= (unsigned int) R_AARCH64_end)
2652 bfd_set_error (bfd_error_bad_value);
2653 error_ret_free_internal:
2654 if (elf_section_data (section)->relocs == NULL)
2655 free (internal_relocs);
2656 goto error_ret_free_local;
2659 /* Only look for stubs on unconditional branch and
2660 branch and link instructions. */
2661 if (r_type != (unsigned int) AARCH64_R (CALL26)
2662 && r_type != (unsigned int) AARCH64_R (JUMP26))
2665 /* Now determine the call target, its name, value,
2672 if (r_indx < symtab_hdr->sh_info)
2674 /* It's a local symbol. */
2675 Elf_Internal_Sym *sym;
2676 Elf_Internal_Shdr *hdr;
2678 if (local_syms == NULL)
2681 = (Elf_Internal_Sym *) symtab_hdr->contents;
2682 if (local_syms == NULL)
2684 = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
2685 symtab_hdr->sh_info, 0,
2687 if (local_syms == NULL)
2688 goto error_ret_free_internal;
2691 sym = local_syms + r_indx;
2692 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
2693 sym_sec = hdr->bfd_section;
2695 /* This is an undefined symbol. It can never
2699 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
2700 sym_value = sym->st_value;
2701 destination = (sym_value + irela->r_addend
2702 + sym_sec->output_offset
2703 + sym_sec->output_section->vma);
2704 st_type = ELF_ST_TYPE (sym->st_info);
2706 = bfd_elf_string_from_elf_section (input_bfd,
2707 symtab_hdr->sh_link,
2714 e_indx = r_indx - symtab_hdr->sh_info;
2715 hash = ((struct elf_aarch64_link_hash_entry *)
2716 elf_sym_hashes (input_bfd)[e_indx]);
2718 while (hash->root.root.type == bfd_link_hash_indirect
2719 || hash->root.root.type == bfd_link_hash_warning)
2720 hash = ((struct elf_aarch64_link_hash_entry *)
2721 hash->root.root.u.i.link);
2723 if (hash->root.root.type == bfd_link_hash_defined
2724 || hash->root.root.type == bfd_link_hash_defweak)
2726 struct elf_aarch64_link_hash_table *globals =
2727 elf_aarch64_hash_table (info);
2728 sym_sec = hash->root.root.u.def.section;
2729 sym_value = hash->root.root.u.def.value;
2730 /* For a destination in a shared library,
2731 use the PLT stub as target address to
2732 decide whether a branch stub is
2734 if (globals->root.splt != NULL && hash != NULL
2735 && hash->root.plt.offset != (bfd_vma) - 1)
2737 sym_sec = globals->root.splt;
2738 sym_value = hash->root.plt.offset;
2739 if (sym_sec->output_section != NULL)
2740 destination = (sym_value
2741 + sym_sec->output_offset
2743 sym_sec->output_section->vma);
2745 else if (sym_sec->output_section != NULL)
2746 destination = (sym_value + irela->r_addend
2747 + sym_sec->output_offset
2748 + sym_sec->output_section->vma);
2750 else if (hash->root.root.type == bfd_link_hash_undefined
2751 || (hash->root.root.type
2752 == bfd_link_hash_undefweak))
2754 /* For a shared library, use the PLT stub as
2755 target address to decide whether a long
2756 branch stub is needed.
2757 For absolute code, they cannot be handled. */
2758 struct elf_aarch64_link_hash_table *globals =
2759 elf_aarch64_hash_table (info);
2761 if (globals->root.splt != NULL && hash != NULL
2762 && hash->root.plt.offset != (bfd_vma) - 1)
2764 sym_sec = globals->root.splt;
2765 sym_value = hash->root.plt.offset;
2766 if (sym_sec->output_section != NULL)
2767 destination = (sym_value
2768 + sym_sec->output_offset
2770 sym_sec->output_section->vma);
2777 bfd_set_error (bfd_error_bad_value);
2778 goto error_ret_free_internal;
2780 st_type = ELF_ST_TYPE (hash->root.type);
2781 sym_name = hash->root.root.root.string;
2784 /* Determine what (if any) linker stub is needed. */
2785 stub_type = aarch64_type_of_stub
2786 (info, section, irela, st_type, hash, destination);
2787 if (stub_type == aarch64_stub_none)
2790 /* Support for grouping stub sections. */
2791 id_sec = htab->stub_group[section->id].link_sec;
2793 /* Get the name of this stub. */
2794 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash,
2797 goto error_ret_free_internal;
2800 aarch64_stub_hash_lookup (&htab->stub_hash_table,
2801 stub_name, FALSE, FALSE);
2802 if (stub_entry != NULL)
2804 /* The proper stub has already been created. */
2809 stub_entry = elfNN_aarch64_add_stub (stub_name, section,
2811 if (stub_entry == NULL)
2814 goto error_ret_free_internal;
2817 stub_entry->target_value = sym_value;
2818 stub_entry->target_section = sym_sec;
2819 stub_entry->stub_type = stub_type;
2820 stub_entry->h = hash;
2821 stub_entry->st_type = st_type;
2823 if (sym_name == NULL)
2824 sym_name = "unnamed";
2825 len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
2826 stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
2827 if (stub_entry->output_name == NULL)
2830 goto error_ret_free_internal;
2833 snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
2836 stub_changed = TRUE;
2839 /* We're done with the internal relocs, free them. */
2840 if (elf_section_data (section)->relocs == NULL)
2841 free (internal_relocs);
2848 /* OK, we've added some stubs. Find out the new size of the
2850 for (stub_sec = htab->stub_bfd->sections;
2851 stub_sec != NULL; stub_sec = stub_sec->next)
2854 bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
2856 /* Ask the linker to do its stuff. */
2857 (*htab->layout_sections_again) ();
2858 stub_changed = FALSE;
2863 error_ret_free_local:
2867 /* Build all the stubs associated with the current output file. The
2868 stubs are kept in a hash table attached to the main linker hash
2869 table. We also set up the .plt entries for statically linked PIC
2870 functions here. This function is called via aarch64_elf_finish in the
2874 elfNN_aarch64_build_stubs (struct bfd_link_info *info)
2877 struct bfd_hash_table *table;
2878 struct elf_aarch64_link_hash_table *htab;
2880 htab = elf_aarch64_hash_table (info);
2882 for (stub_sec = htab->stub_bfd->sections;
2883 stub_sec != NULL; stub_sec = stub_sec->next)
2887 /* Ignore non-stub sections. */
2888 if (!strstr (stub_sec->name, STUB_SUFFIX))
2891 /* Allocate memory to hold the linker stubs. */
2892 size = stub_sec->size;
2893 stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
2894 if (stub_sec->contents == NULL && size != 0)
2899 /* Build the stubs as directed by the stub hash table. */
2900 table = &htab->stub_hash_table;
2901 bfd_hash_traverse (table, aarch64_build_one_stub, info);
2907 /* Add an entry to the code/data map for section SEC. */
2910 elfNN_aarch64_section_map_add (asection *sec, char type, bfd_vma vma)
2912 struct _aarch64_elf_section_data *sec_data =
2913 elf_aarch64_section_data (sec);
2914 unsigned int newidx;
2916 if (sec_data->map == NULL)
2918 sec_data->map = bfd_malloc (sizeof (elf_aarch64_section_map));
2919 sec_data->mapcount = 0;
2920 sec_data->mapsize = 1;
2923 newidx = sec_data->mapcount++;
2925 if (sec_data->mapcount > sec_data->mapsize)
2927 sec_data->mapsize *= 2;
2928 sec_data->map = bfd_realloc_or_free
2929 (sec_data->map, sec_data->mapsize * sizeof (elf_aarch64_section_map));
2934 sec_data->map[newidx].vma = vma;
2935 sec_data->map[newidx].type = type;
2940 /* Initialise maps of insn/data for input BFDs. */
2942 bfd_elfNN_aarch64_init_maps (bfd *abfd)
2944 Elf_Internal_Sym *isymbuf;
2945 Elf_Internal_Shdr *hdr;
2946 unsigned int i, localsyms;
2948 /* Make sure that we are dealing with an AArch64 elf binary. */
2949 if (!is_aarch64_elf (abfd))
2952 if ((abfd->flags & DYNAMIC) != 0)
2955 hdr = &elf_symtab_hdr (abfd);
2956 localsyms = hdr->sh_info;
2958 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
2959 should contain the number of local symbols, which should come before any
2960 global symbols. Mapping symbols are always local. */
2961 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL);
2963 /* No internal symbols read? Skip this BFD. */
2964 if (isymbuf == NULL)
2967 for (i = 0; i < localsyms; i++)
2969 Elf_Internal_Sym *isym = &isymbuf[i];
2970 asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2973 if (sec != NULL && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
2975 name = bfd_elf_string_from_elf_section (abfd,
2979 if (bfd_is_aarch64_special_symbol_name
2980 (name, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP))
2981 elfNN_aarch64_section_map_add (sec, name[1], isym->st_value);
2986 /* Set option values needed during linking. */
2988 bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
2989 struct bfd_link_info *link_info,
2991 int no_wchar_warn, int pic_veneer)
2993 struct elf_aarch64_link_hash_table *globals;
2995 globals = elf_aarch64_hash_table (link_info);
2996 globals->pic_veneer = pic_veneer;
2998 BFD_ASSERT (is_aarch64_elf (output_bfd));
2999 elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
3000 elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
3004 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
3005 struct elf_aarch64_link_hash_table
3006 *globals, struct bfd_link_info *info,
3007 bfd_vma value, bfd *output_bfd,
3008 bfd_boolean *unresolved_reloc_p)
3010 bfd_vma off = (bfd_vma) - 1;
3011 asection *basegot = globals->root.sgot;
3012 bfd_boolean dyn = globals->root.dynamic_sections_created;
3016 BFD_ASSERT (basegot != NULL);
3017 off = h->got.offset;
3018 BFD_ASSERT (off != (bfd_vma) - 1);
3019 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
3021 && SYMBOL_REFERENCES_LOCAL (info, h))
3022 || (ELF_ST_VISIBILITY (h->other)
3023 && h->root.type == bfd_link_hash_undefweak))
3025 /* This is actually a static link, or it is a -Bsymbolic link
3026 and the symbol is defined locally. We must initialize this
3027 entry in the global offset table. Since the offset must
3028 always be a multiple of 8 (4 in the case of ILP32), we use
3029 the least significant bit to record whether we have
3030 initialized it already.
3031 When doing a dynamic link, we create a .rel(a).got relocation
3032 entry to initialize the value. This is done in the
3033 finish_dynamic_symbol routine. */
3038 bfd_put_NN (output_bfd, value, basegot->contents + off);
3043 *unresolved_reloc_p = FALSE;
3045 off = off + basegot->output_section->vma + basegot->output_offset;
3051 /* Change R_TYPE to a more efficient access model where possible,
3052 return the new reloc type. */
3054 static bfd_reloc_code_real_type
3055 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
3056 struct elf_link_hash_entry *h)
3058 bfd_boolean is_local = h == NULL;
3062 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3063 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3065 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
3066 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
3068 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3069 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
3071 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
3072 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
3074 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3075 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
3077 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
3078 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
3080 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3081 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3082 /* Instructions with these relocations will become NOPs. */
3083 return BFD_RELOC_AARCH64_NONE;
3093 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
3097 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
3098 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
3099 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
3100 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
3103 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3104 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3107 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3108 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3109 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3110 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
3111 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
3112 return GOT_TLSDESC_GD;
3114 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3115 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
3116 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
3119 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
3120 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
3121 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
3122 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
3123 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
3124 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
3125 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
3126 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
3136 aarch64_can_relax_tls (bfd *input_bfd,
3137 struct bfd_link_info *info,
3138 bfd_reloc_code_real_type r_type,
3139 struct elf_link_hash_entry *h,
3140 unsigned long r_symndx)
3142 unsigned int symbol_got_type;
3143 unsigned int reloc_got_type;
3145 if (! IS_AARCH64_TLS_RELOC (r_type))
3148 symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
3149 reloc_got_type = aarch64_reloc_got_type (r_type);
3151 if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
3157 if (h && h->root.type == bfd_link_hash_undefweak)
3163 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
3166 static bfd_reloc_code_real_type
3167 aarch64_tls_transition (bfd *input_bfd,
3168 struct bfd_link_info *info,
3169 unsigned int r_type,
3170 struct elf_link_hash_entry *h,
3171 unsigned long r_symndx)
3173 bfd_reloc_code_real_type bfd_r_type
3174 = elfNN_aarch64_bfd_reloc_from_type (r_type);
3176 if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
3179 return aarch64_tls_transition_without_check (bfd_r_type, h);
3182 /* Return the base VMA address which should be subtracted from real addresses
3183 when resolving R_AARCH64_TLS_DTPREL relocation. */
3186 dtpoff_base (struct bfd_link_info *info)
3188 /* If tls_sec is NULL, we should have signalled an error already. */
3189 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3190 return elf_hash_table (info)->tls_sec->vma;
3193 /* Return the base VMA address which should be subtracted from real addresses
3194 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
3197 tpoff_base (struct bfd_link_info *info)
3199 struct elf_link_hash_table *htab = elf_hash_table (info);
3201 /* If tls_sec is NULL, we should have signalled an error already. */
3202 if (htab->tls_sec == NULL)
3205 bfd_vma base = align_power ((bfd_vma) TCB_SIZE,
3206 htab->tls_sec->alignment_power);
3207 return htab->tls_sec->vma - base;
3211 symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
3212 unsigned long r_symndx)
3214 /* Calculate the address of the GOT entry for symbol
3215 referred to in h. */
3217 return &h->got.offset;
3221 struct elf_aarch64_local_symbol *l;
3223 l = elf_aarch64_locals (input_bfd);
3224 return &l[r_symndx].got_offset;
3229 symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
3230 unsigned long r_symndx)
3233 p = symbol_got_offset_ref (input_bfd, h, r_symndx);
3238 symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
3239 unsigned long r_symndx)
3242 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
3247 symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
3248 unsigned long r_symndx)
3251 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
3257 symbol_tlsdesc_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
3258 unsigned long r_symndx)
3260 /* Calculate the address of the GOT entry for symbol
3261 referred to in h. */
3264 struct elf_aarch64_link_hash_entry *eh;
3265 eh = (struct elf_aarch64_link_hash_entry *) h;
3266 return &eh->tlsdesc_got_jump_table_offset;
3271 struct elf_aarch64_local_symbol *l;
3273 l = elf_aarch64_locals (input_bfd);
3274 return &l[r_symndx].tlsdesc_got_jump_table_offset;
3279 symbol_tlsdesc_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
3280 unsigned long r_symndx)
3283 p = symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
3288 symbol_tlsdesc_got_offset_mark_p (bfd *input_bfd,
3289 struct elf_link_hash_entry *h,
3290 unsigned long r_symndx)
3293 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
3298 symbol_tlsdesc_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
3299 unsigned long r_symndx)
3302 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
3307 /* Perform a relocation as part of a final link. */
3308 static bfd_reloc_status_type
3309 elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
3312 asection *input_section,
3314 Elf_Internal_Rela *rel,
3316 struct bfd_link_info *info,
3318 struct elf_link_hash_entry *h,
3319 bfd_boolean *unresolved_reloc_p,
3320 bfd_boolean save_addend,
3321 bfd_vma *saved_addend)
3323 unsigned int r_type = howto->type;
3324 bfd_reloc_code_real_type bfd_r_type
3325 = elfNN_aarch64_bfd_reloc_from_howto (howto);
3326 bfd_reloc_code_real_type new_bfd_r_type;
3327 unsigned long r_symndx;
3328 bfd_byte *hit_data = contents + rel->r_offset;
3330 bfd_signed_vma signed_addend;
3331 struct elf_aarch64_link_hash_table *globals;
3332 bfd_boolean weak_undef_p;
3334 globals = elf_aarch64_hash_table (info);
3336 BFD_ASSERT (is_aarch64_elf (input_bfd));
3338 r_symndx = ELFNN_R_SYM (rel->r_info);
3340 /* It is possible to have linker relaxations on some TLS access
3341 models. Update our information here. */
3342 new_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, h, r_symndx);
3343 if (new_bfd_r_type != bfd_r_type)
3345 bfd_r_type = new_bfd_r_type;
3346 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
3347 BFD_ASSERT (howto != NULL);
3348 r_type = howto->type;
3351 place = input_section->output_section->vma
3352 + input_section->output_offset + rel->r_offset;
3354 /* Get addend, accumulating the addend for consecutive relocs
3355 which refer to the same offset. */
3356 signed_addend = saved_addend ? *saved_addend : 0;
3357 signed_addend += rel->r_addend;
3359 weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
3360 : bfd_is_und_section (sym_sec));
3364 case BFD_RELOC_AARCH64_NONE:
3365 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3366 *unresolved_reloc_p = FALSE;
3367 return bfd_reloc_ok;
3369 case BFD_RELOC_AARCH64_NN:
3371 /* When generating a shared object or relocatable executable, these
3372 relocations are copied into the output file to be resolved at
3374 if (((info->shared == TRUE) || globals->root.is_relocatable_executable)
3375 && (input_section->flags & SEC_ALLOC)
3377 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3378 || h->root.type != bfd_link_hash_undefweak))
3380 Elf_Internal_Rela outrel;
3382 bfd_boolean skip, relocate;
3385 *unresolved_reloc_p = FALSE;
3387 sreloc = _bfd_elf_get_dynamic_reloc_section (input_bfd,
3390 return bfd_reloc_notsupported;
3395 outrel.r_addend = signed_addend;
3397 _bfd_elf_section_offset (output_bfd, info, input_section,
3399 if (outrel.r_offset == (bfd_vma) - 1)
3401 else if (outrel.r_offset == (bfd_vma) - 2)
3407 outrel.r_offset += (input_section->output_section->vma
3408 + input_section->output_offset);
3411 memset (&outrel, 0, sizeof outrel);
3414 && (!info->shared || !info->symbolic || !h->def_regular))
3415 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
3420 /* On SVR4-ish systems, the dynamic loader cannot
3421 relocate the text and data segments independently,
3422 so the symbol does not matter. */
3424 outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
3425 outrel.r_addend += value;
3428 loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (htab);
3429 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
3431 if (sreloc->reloc_count * RELOC_SIZE (htab) > sreloc->size)
3433 /* Sanity to check that we have previously allocated
3434 sufficient space in the relocation section for the
3435 number of relocations we actually want to emit. */
3439 /* If this reloc is against an external symbol, we do not want to
3440 fiddle with the addend. Otherwise, we need to include the symbol
3441 value so that it becomes an addend for the dynamic reloc. */
3443 return bfd_reloc_ok;
3445 return _bfd_final_link_relocate (howto, input_bfd, input_section,
3446 contents, rel->r_offset, value,
3450 value += signed_addend;
3453 case BFD_RELOC_AARCH64_JUMP26:
3454 case BFD_RELOC_AARCH64_CALL26:
3456 asection *splt = globals->root.splt;
3457 bfd_boolean via_plt_p =
3458 splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
3460 /* A call to an undefined weak symbol is converted to a jump to
3461 the next instruction unless a PLT entry will be created.
3462 The jump to the next instruction is optimized as a NOP.
3463 Do the same for local undefined symbols. */
3464 if (weak_undef_p && ! via_plt_p)
3466 bfd_putl32 (INSN_NOP, hit_data);
3467 return bfd_reloc_ok;
3470 /* If the call goes through a PLT entry, make sure to
3471 check distance to the right destination address. */
3474 value = (splt->output_section->vma
3475 + splt->output_offset + h->plt.offset);
3476 *unresolved_reloc_p = FALSE;
3479 /* If the target symbol is global and marked as a function the
3480 relocation applies a function call or a tail call. In this
3481 situation we can veneer out of range branches. The veneers
3482 use IP0 and IP1 hence cannot be used arbitrary out of range
3483 branches that occur within the body of a function. */
3484 if (h && h->type == STT_FUNC)
3486 /* Check if a stub has to be inserted because the destination
3488 if (! aarch64_valid_branch_p (value, place))
3490 /* The target is out of reach, so redirect the branch to
3491 the local stub for this function. */
3492 struct elf_aarch64_stub_hash_entry *stub_entry;
3493 stub_entry = elfNN_aarch64_get_stub_entry (input_section,
3496 if (stub_entry != NULL)
3497 value = (stub_entry->stub_offset
3498 + stub_entry->stub_sec->output_offset
3499 + stub_entry->stub_sec->output_section->vma);
3503 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3504 signed_addend, weak_undef_p);
3507 case BFD_RELOC_AARCH64_16:
3509 case BFD_RELOC_AARCH64_32:
3511 case BFD_RELOC_AARCH64_ADD_LO12:
3512 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
3513 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
3514 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
3515 case BFD_RELOC_AARCH64_BRANCH19:
3516 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
3517 case BFD_RELOC_AARCH64_LDST8_LO12:
3518 case BFD_RELOC_AARCH64_LDST16_LO12:
3519 case BFD_RELOC_AARCH64_LDST32_LO12:
3520 case BFD_RELOC_AARCH64_LDST64_LO12:
3521 case BFD_RELOC_AARCH64_LDST128_LO12:
3522 case BFD_RELOC_AARCH64_MOVW_G0_S:
3523 case BFD_RELOC_AARCH64_MOVW_G1_S:
3524 case BFD_RELOC_AARCH64_MOVW_G2_S:
3525 case BFD_RELOC_AARCH64_MOVW_G0:
3526 case BFD_RELOC_AARCH64_MOVW_G0_NC:
3527 case BFD_RELOC_AARCH64_MOVW_G1:
3528 case BFD_RELOC_AARCH64_MOVW_G1_NC:
3529 case BFD_RELOC_AARCH64_MOVW_G2:
3530 case BFD_RELOC_AARCH64_MOVW_G2_NC:
3531 case BFD_RELOC_AARCH64_MOVW_G3:
3532 case BFD_RELOC_AARCH64_16_PCREL:
3533 case BFD_RELOC_AARCH64_32_PCREL:
3534 case BFD_RELOC_AARCH64_64_PCREL:
3535 case BFD_RELOC_AARCH64_TSTBR14:
3536 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3537 signed_addend, weak_undef_p);
3540 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
3541 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
3542 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
3543 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
3544 if (globals->root.sgot == NULL)
3545 BFD_ASSERT (h != NULL);
3549 value = aarch64_calculate_got_entry_vma (h, globals, info, value,
3551 unresolved_reloc_p);
3552 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3557 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3558 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3559 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3560 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
3561 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
3562 if (globals->root.sgot == NULL)
3563 return bfd_reloc_notsupported;
3565 value = (symbol_got_offset (input_bfd, h, r_symndx)
3566 + globals->root.sgot->output_section->vma
3567 + globals->root.sgot->output_section->output_offset);
3569 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3571 *unresolved_reloc_p = FALSE;
3574 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
3575 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
3576 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
3577 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
3578 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
3579 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
3580 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
3581 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
3582 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3583 signed_addend - tpoff_base (info),
3585 *unresolved_reloc_p = FALSE;
3588 case BFD_RELOC_AARCH64_TLSDESC_ADD:
3589 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3590 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3591 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
3592 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
3593 case BFD_RELOC_AARCH64_TLSDESC_LDR:
3594 if (globals->root.sgot == NULL)
3595 return bfd_reloc_notsupported;
3597 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
3598 + globals->root.sgotplt->output_section->vma
3599 + globals->root.sgotplt->output_section->output_offset
3600 + globals->sgotplt_jump_table_size);
3602 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3604 *unresolved_reloc_p = FALSE;
3608 return bfd_reloc_notsupported;
3612 *saved_addend = value;
3614 /* Only apply the final relocation in a sequence. */
3616 return bfd_reloc_continue;
3618 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
3622 /* Handle TLS relaxations. Relaxing is possible for symbols that use
3623 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
3626 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
3627 is to then call final_link_relocate. Return other values in the
3630 static bfd_reloc_status_type
3631 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
3632 bfd *input_bfd, bfd_byte *contents,
3633 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h)
3635 bfd_boolean is_local = h == NULL;
3636 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
3639 BFD_ASSERT (globals && input_bfd && contents && rel);
3641 switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
3643 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3644 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3647 /* GD->LE relaxation:
3648 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
3650 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
3652 bfd_putl32 (0xd2a00000, contents + rel->r_offset);
3653 return bfd_reloc_continue;
3657 /* GD->IE relaxation:
3658 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
3660 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
3662 insn = bfd_getl32 (contents + rel->r_offset);
3663 return bfd_reloc_continue;
3666 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
3669 /* GD->LE relaxation:
3670 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
3672 bfd_putl32 (0xf2800000, contents + rel->r_offset);
3673 return bfd_reloc_continue;
3677 /* GD->IE relaxation:
3678 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
3680 insn = bfd_getl32 (contents + rel->r_offset);
3682 bfd_putl32 (insn, contents + rel->r_offset);
3683 return bfd_reloc_continue;
3686 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3689 /* GD->LE relaxation
3690 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
3691 bl __tls_get_addr => mrs x1, tpidr_el0
3692 nop => add x0, x1, x0
3695 /* First kill the tls_get_addr reloc on the bl instruction. */
3696 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
3697 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
3699 bfd_putl32 (0xf2800000, contents + rel->r_offset);
3700 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
3701 bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
3702 return bfd_reloc_continue;
3706 /* GD->IE relaxation
3707 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
3708 BL __tls_get_addr => mrs x1, tpidr_el0
3710 NOP => add x0, x1, x0
3713 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
3715 /* Remove the relocation on the BL instruction. */
3716 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
3718 bfd_putl32 (0xf9400000, contents + rel->r_offset);
3720 /* We choose to fixup the BL and NOP instructions using the
3721 offset from the second relocation to allow flexibility in
3722 scheduling instructions between the ADD and BL. */
3723 bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
3724 bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
3725 return bfd_reloc_continue;
3728 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3729 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3730 /* GD->IE/LE relaxation:
3731 add x0, x0, #:tlsdesc_lo12:var => nop
3734 bfd_putl32 (INSN_NOP, contents + rel->r_offset);
3735 return bfd_reloc_ok;
3737 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3738 /* IE->LE relaxation:
3739 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
3743 insn = bfd_getl32 (contents + rel->r_offset);
3744 bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
3746 return bfd_reloc_continue;
3748 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
3749 /* IE->LE relaxation:
3750 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
3754 insn = bfd_getl32 (contents + rel->r_offset);
3755 bfd_putl32 (0xf2800000 | (insn & 0x1f), contents + rel->r_offset);
3757 return bfd_reloc_continue;
3760 return bfd_reloc_continue;
3763 return bfd_reloc_ok;
3766 /* Relocate an AArch64 ELF section. */
3769 elfNN_aarch64_relocate_section (bfd *output_bfd,
3770 struct bfd_link_info *info,
3772 asection *input_section,
3774 Elf_Internal_Rela *relocs,
3775 Elf_Internal_Sym *local_syms,
3776 asection **local_sections)
3778 Elf_Internal_Shdr *symtab_hdr;
3779 struct elf_link_hash_entry **sym_hashes;
3780 Elf_Internal_Rela *rel;
3781 Elf_Internal_Rela *relend;
3783 struct elf_aarch64_link_hash_table *globals;
3784 bfd_boolean save_addend = FALSE;
3787 globals = elf_aarch64_hash_table (info);
3789 symtab_hdr = &elf_symtab_hdr (input_bfd);
3790 sym_hashes = elf_sym_hashes (input_bfd);
3793 relend = relocs + input_section->reloc_count;
3794 for (; rel < relend; rel++)
3796 unsigned int r_type;
3797 bfd_reloc_code_real_type bfd_r_type;
3798 bfd_reloc_code_real_type relaxed_bfd_r_type;
3799 reloc_howto_type *howto;
3800 unsigned long r_symndx;
3801 Elf_Internal_Sym *sym;
3803 struct elf_link_hash_entry *h;
3805 bfd_reloc_status_type r;
3808 bfd_boolean unresolved_reloc = FALSE;
3809 char *error_message = NULL;
3811 r_symndx = ELFNN_R_SYM (rel->r_info);
3812 r_type = ELFNN_R_TYPE (rel->r_info);
3814 bfd_reloc.howto = elfNN_aarch64_howto_from_type (r_type);
3815 howto = bfd_reloc.howto;
3819 (*_bfd_error_handler)
3820 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
3821 input_bfd, input_section, r_type);
3824 bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
3830 if (r_symndx < symtab_hdr->sh_info)
3832 sym = local_syms + r_symndx;
3833 sym_type = ELFNN_ST_TYPE (sym->st_info);
3834 sec = local_sections[r_symndx];
3836 /* An object file might have a reference to a local
3837 undefined symbol. This is a daft object file, but we
3838 should at least do something about it. */
3839 if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
3840 && bfd_is_und_section (sec)
3841 && ELF_ST_BIND (sym->st_info) != STB_WEAK)
3843 if (!info->callbacks->undefined_symbol
3844 (info, bfd_elf_string_from_elf_section
3845 (input_bfd, symtab_hdr->sh_link, sym->st_name),
3846 input_bfd, input_section, rel->r_offset, TRUE))
3850 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
3856 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3857 r_symndx, symtab_hdr, sym_hashes,
3859 unresolved_reloc, warned);
3864 if (sec != NULL && discarded_section (sec))
3865 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
3866 rel, 1, relend, howto, 0, contents);
3868 if (info->relocatable)
3870 /* This is a relocatable link. We don't have to change
3871 anything, unless the reloc is against a section symbol,
3872 in which case we have to adjust according to where the
3873 section symbol winds up in the output section. */
3874 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3875 rel->r_addend += sec->output_offset;
3880 name = h->root.root.string;
3883 name = (bfd_elf_string_from_elf_section
3884 (input_bfd, symtab_hdr->sh_link, sym->st_name));
3885 if (name == NULL || *name == '\0')
3886 name = bfd_section_name (input_bfd, sec);
3890 && r_type != R_AARCH64_NONE
3891 && r_type != R_AARCH64_NULL
3893 || h->root.type == bfd_link_hash_defined
3894 || h->root.type == bfd_link_hash_defweak)
3895 && IS_AARCH64_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
3897 (*_bfd_error_handler)
3898 ((sym_type == STT_TLS
3899 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
3900 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
3902 input_section, (long) rel->r_offset, howto->name, name);
3905 /* We relax only if we can see that there can be a valid transition
3906 from a reloc type to another.
3907 We call elfNN_aarch64_final_link_relocate unless we're completely
3908 done, i.e., the relaxation produced the final output we want. */
3910 relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
3912 if (relaxed_bfd_r_type != bfd_r_type)
3914 bfd_r_type = relaxed_bfd_r_type;
3915 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
3916 BFD_ASSERT (howto != NULL);
3917 r_type = howto->type;
3918 r = elfNN_aarch64_tls_relax (globals, input_bfd, contents, rel, h);
3919 unresolved_reloc = 0;
3922 r = bfd_reloc_continue;
3924 /* There may be multiple consecutive relocations for the
3925 same offset. In that case we are supposed to treat the
3926 output of each relocation as the addend for the next. */
3927 if (rel + 1 < relend
3928 && rel->r_offset == rel[1].r_offset
3929 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NONE
3930 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NULL)
3933 save_addend = FALSE;
3935 if (r == bfd_reloc_continue)
3936 r = elfNN_aarch64_final_link_relocate (howto, input_bfd, output_bfd,
3937 input_section, contents, rel,
3938 relocation, info, sec,
3939 h, &unresolved_reloc,
3940 save_addend, &addend);
3942 switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
3944 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3945 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3946 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
3948 bfd_boolean need_relocs = FALSE;
3953 off = symbol_got_offset (input_bfd, h, r_symndx);
3954 indx = h && h->dynindx != -1 ? h->dynindx : 0;
3957 (info->shared || indx != 0) &&
3959 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3960 || h->root.type != bfd_link_hash_undefweak);
3962 BFD_ASSERT (globals->root.srelgot != NULL);
3966 Elf_Internal_Rela rela;
3967 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPMOD));
3969 rela.r_offset = globals->root.sgot->output_section->vma +
3970 globals->root.sgot->output_offset + off;
3973 loc = globals->root.srelgot->contents;
3974 loc += globals->root.srelgot->reloc_count++
3975 * RELOC_SIZE (htab);
3976 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
3980 bfd_put_NN (output_bfd,
3981 relocation - dtpoff_base (info),
3982 globals->root.sgot->contents + off
3987 /* This TLS symbol is global. We emit a
3988 relocation to fixup the tls offset at load
3991 ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPREL));
3994 (globals->root.sgot->output_section->vma
3995 + globals->root.sgot->output_offset + off
3998 loc = globals->root.srelgot->contents;
3999 loc += globals->root.srelgot->reloc_count++
4000 * RELOC_SIZE (globals);
4001 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4002 bfd_put_NN (output_bfd, (bfd_vma) 0,
4003 globals->root.sgot->contents + off
4009 bfd_put_NN (output_bfd, (bfd_vma) 1,
4010 globals->root.sgot->contents + off);
4011 bfd_put_NN (output_bfd,
4012 relocation - dtpoff_base (info),
4013 globals->root.sgot->contents + off
4017 symbol_got_offset_mark (input_bfd, h, r_symndx);
4021 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4022 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
4023 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
4025 bfd_boolean need_relocs = FALSE;
4030 off = symbol_got_offset (input_bfd, h, r_symndx);
4032 indx = h && h->dynindx != -1 ? h->dynindx : 0;
4035 (info->shared || indx != 0) &&
4037 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4038 || h->root.type != bfd_link_hash_undefweak);
4040 BFD_ASSERT (globals->root.srelgot != NULL);
4044 Elf_Internal_Rela rela;
4047 rela.r_addend = relocation - dtpoff_base (info);
4051 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_TPREL));
4052 rela.r_offset = globals->root.sgot->output_section->vma +
4053 globals->root.sgot->output_offset + off;
4055 loc = globals->root.srelgot->contents;
4056 loc += globals->root.srelgot->reloc_count++
4057 * RELOC_SIZE (htab);
4059 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4061 bfd_put_NN (output_bfd, rela.r_addend,
4062 globals->root.sgot->contents + off);
4065 bfd_put_NN (output_bfd, relocation - tpoff_base (info),
4066 globals->root.sgot->contents + off);
4068 symbol_got_offset_mark (input_bfd, h, r_symndx);
4072 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
4073 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
4074 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
4075 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
4076 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
4077 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
4078 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
4079 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
4082 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4083 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4084 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
4085 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
4087 bfd_boolean need_relocs = FALSE;
4088 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
4089 bfd_vma off = symbol_tlsdesc_got_offset (input_bfd, h, r_symndx);
4091 need_relocs = (h == NULL
4092 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4093 || h->root.type != bfd_link_hash_undefweak);
4095 BFD_ASSERT (globals->root.srelgot != NULL);
4096 BFD_ASSERT (globals->root.sgot != NULL);
4101 Elf_Internal_Rela rela;
4102 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
4105 rela.r_offset = (globals->root.sgotplt->output_section->vma
4106 + globals->root.sgotplt->output_offset
4107 + off + globals->sgotplt_jump_table_size);
4110 rela.r_addend = relocation - dtpoff_base (info);
4112 /* Allocate the next available slot in the PLT reloc
4113 section to hold our R_AARCH64_TLSDESC, the next
4114 available slot is determined from reloc_count,
4115 which we step. But note, reloc_count was
4116 artifically moved down while allocating slots for
4117 real PLT relocs such that all of the PLT relocs
4118 will fit above the initial reloc_count and the
4119 extra stuff will fit below. */
4120 loc = globals->root.srelplt->contents;
4121 loc += globals->root.srelplt->reloc_count++
4122 * RELOC_SIZE (globals);
4124 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4126 bfd_put_NN (output_bfd, (bfd_vma) 0,
4127 globals->root.sgotplt->contents + off +
4128 globals->sgotplt_jump_table_size);
4129 bfd_put_NN (output_bfd, (bfd_vma) 0,
4130 globals->root.sgotplt->contents + off +
4131 globals->sgotplt_jump_table_size +
4135 symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
4146 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
4147 because such sections are not SEC_ALLOC and thus ld.so will
4148 not process them. */
4149 if (unresolved_reloc
4150 && !((input_section->flags & SEC_DEBUGGING) != 0
4152 && _bfd_elf_section_offset (output_bfd, info, input_section,
4153 +rel->r_offset) != (bfd_vma) - 1)
4155 (*_bfd_error_handler)
4157 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
4158 input_bfd, input_section, (long) rel->r_offset, howto->name,
4159 h->root.root.string);
4163 if (r != bfd_reloc_ok && r != bfd_reloc_continue)
4167 case bfd_reloc_overflow:
4168 /* If the overflowing reloc was to an undefined symbol,
4169 we have already printed one error message and there
4170 is no point complaining again. */
4172 h->root.type != bfd_link_hash_undefined)
4173 && (!((*info->callbacks->reloc_overflow)
4174 (info, (h ? &h->root : NULL), name, howto->name,
4175 (bfd_vma) 0, input_bfd, input_section,
4180 case bfd_reloc_undefined:
4181 if (!((*info->callbacks->undefined_symbol)
4182 (info, name, input_bfd, input_section,
4183 rel->r_offset, TRUE)))
4187 case bfd_reloc_outofrange:
4188 error_message = _("out of range");
4191 case bfd_reloc_notsupported:
4192 error_message = _("unsupported relocation");
4195 case bfd_reloc_dangerous:
4196 /* error_message should already be set. */
4200 error_message = _("unknown error");
4204 BFD_ASSERT (error_message != NULL);
4205 if (!((*info->callbacks->reloc_dangerous)
4206 (info, error_message, input_bfd, input_section,
4217 /* Set the right machine number. */
4220 elfNN_aarch64_object_p (bfd *abfd)
4223 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64_ilp32);
4225 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64);
4230 /* Function to keep AArch64 specific flags in the ELF header. */
4233 elfNN_aarch64_set_private_flags (bfd *abfd, flagword flags)
4235 if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
4240 elf_elfheader (abfd)->e_flags = flags;
4241 elf_flags_init (abfd) = TRUE;
4247 /* Copy backend specific data from one object module to another. */
4250 elfNN_aarch64_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
4254 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
4257 in_flags = elf_elfheader (ibfd)->e_flags;
4259 elf_elfheader (obfd)->e_flags = in_flags;
4260 elf_flags_init (obfd) = TRUE;
4262 /* Also copy the EI_OSABI field. */
4263 elf_elfheader (obfd)->e_ident[EI_OSABI] =
4264 elf_elfheader (ibfd)->e_ident[EI_OSABI];
4266 /* Copy object attributes. */
4267 _bfd_elf_copy_obj_attributes (ibfd, obfd);
4272 /* Merge backend specific data from an object file to the output
4273 object file when linking. */
4276 elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
4280 bfd_boolean flags_compatible = TRUE;
4283 /* Check if we have the same endianess. */
4284 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
4287 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
4290 /* The input BFD must have had its flags initialised. */
4291 /* The following seems bogus to me -- The flags are initialized in
4292 the assembler but I don't think an elf_flags_init field is
4293 written into the object. */
4294 /* BFD_ASSERT (elf_flags_init (ibfd)); */
4296 in_flags = elf_elfheader (ibfd)->e_flags;
4297 out_flags = elf_elfheader (obfd)->e_flags;
4299 if (!elf_flags_init (obfd))
4301 /* If the input is the default architecture and had the default
4302 flags then do not bother setting the flags for the output
4303 architecture, instead allow future merges to do this. If no
4304 future merges ever set these flags then they will retain their
4305 uninitialised values, which surprise surprise, correspond
4306 to the default values. */
4307 if (bfd_get_arch_info (ibfd)->the_default
4308 && elf_elfheader (ibfd)->e_flags == 0)
4311 elf_flags_init (obfd) = TRUE;
4312 elf_elfheader (obfd)->e_flags = in_flags;
4314 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4315 && bfd_get_arch_info (obfd)->the_default)
4316 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4317 bfd_get_mach (ibfd));
4322 /* Identical flags must be compatible. */
4323 if (in_flags == out_flags)
4326 /* Check to see if the input BFD actually contains any sections. If
4327 not, its flags may not have been initialised either, but it
4328 cannot actually cause any incompatiblity. Do not short-circuit
4329 dynamic objects; their section list may be emptied by
4330 elf_link_add_object_symbols.
4332 Also check to see if there are no code sections in the input.
4333 In this case there is no need to check for code specific flags.
4334 XXX - do we need to worry about floating-point format compatability
4335 in data sections ? */
4336 if (!(ibfd->flags & DYNAMIC))
4338 bfd_boolean null_input_bfd = TRUE;
4339 bfd_boolean only_data_sections = TRUE;
4341 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
4343 if ((bfd_get_section_flags (ibfd, sec)
4344 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
4345 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
4346 only_data_sections = FALSE;
4348 null_input_bfd = FALSE;
4352 if (null_input_bfd || only_data_sections)
4356 return flags_compatible;
4359 /* Display the flags field. */
4362 elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
4364 FILE *file = (FILE *) ptr;
4365 unsigned long flags;
4367 BFD_ASSERT (abfd != NULL && ptr != NULL);
4369 /* Print normal ELF private data. */
4370 _bfd_elf_print_private_bfd_data (abfd, ptr);
4372 flags = elf_elfheader (abfd)->e_flags;
4373 /* Ignore init flag - it may not be set, despite the flags field
4374 containing valid data. */
4376 /* xgettext:c-format */
4377 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
4380 fprintf (file, _("<Unrecognised flag bits set>"));
4387 /* Update the got entry reference counts for the section being removed. */
4390 elfNN_aarch64_gc_sweep_hook (bfd *abfd,
4391 struct bfd_link_info *info,
4393 const Elf_Internal_Rela * relocs)
4395 struct elf_aarch64_link_hash_table *htab;
4396 Elf_Internal_Shdr *symtab_hdr;
4397 struct elf_link_hash_entry **sym_hashes;
4398 struct elf_aarch64_local_symbol *locals;
4399 const Elf_Internal_Rela *rel, *relend;
4401 if (info->relocatable)
4404 htab = elf_aarch64_hash_table (info);
4409 elf_section_data (sec)->local_dynrel = NULL;
4411 symtab_hdr = &elf_symtab_hdr (abfd);
4412 sym_hashes = elf_sym_hashes (abfd);
4414 locals = elf_aarch64_locals (abfd);
4416 relend = relocs + sec->reloc_count;
4417 for (rel = relocs; rel < relend; rel++)
4419 unsigned long r_symndx;
4420 unsigned int r_type;
4421 struct elf_link_hash_entry *h = NULL;
4423 r_symndx = ELFNN_R_SYM (rel->r_info);
4425 if (r_symndx >= symtab_hdr->sh_info)
4427 struct elf_aarch64_link_hash_entry *eh;
4428 struct elf_dyn_relocs **pp;
4429 struct elf_dyn_relocs *p;
4431 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4432 while (h->root.type == bfd_link_hash_indirect
4433 || h->root.type == bfd_link_hash_warning)
4434 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4435 eh = (struct elf_aarch64_link_hash_entry *) h;
4437 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
4441 /* Everything must go for SEC. */
4449 Elf_Internal_Sym *isym;
4451 /* A local symbol. */
4452 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
4458 r_type = ELFNN_R_TYPE (rel->r_info);
4459 switch (aarch64_tls_transition (abfd,info, r_type, h ,r_symndx))
4461 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4462 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
4463 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
4464 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
4465 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4466 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4467 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
4468 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
4469 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
4470 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
4471 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4472 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
4473 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
4474 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
4475 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
4476 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
4477 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
4478 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
4479 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
4480 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
4481 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
4484 if (h->got.refcount > 0)
4485 h->got.refcount -= 1;
4487 else if (locals != NULL)
4489 if (locals[r_symndx].got_refcount > 0)
4490 locals[r_symndx].got_refcount -= 1;
4494 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
4495 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
4496 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
4497 if (h != NULL && info->executable)
4499 if (h->plt.refcount > 0)
4500 h->plt.refcount -= 1;
4504 case BFD_RELOC_AARCH64_CALL26:
4505 case BFD_RELOC_AARCH64_JUMP26:
4506 /* If this is a local symbol then we resolve it
4507 directly without creating a PLT entry. */
4511 if (h->plt.refcount > 0)
4512 h->plt.refcount -= 1;
4515 case BFD_RELOC_AARCH64_NN:
4516 if (h != NULL && info->executable)
4518 if (h->plt.refcount > 0)
4519 h->plt.refcount -= 1;
4531 /* Adjust a symbol defined by a dynamic object and referenced by a
4532 regular object. The current definition is in some section of the
4533 dynamic object, but we're not including those sections. We have to
4534 change the definition to something the rest of the link can
4538 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
4539 struct elf_link_hash_entry *h)
4541 struct elf_aarch64_link_hash_table *htab;
4544 /* If this is a function, put it in the procedure linkage table. We
4545 will fill in the contents of the procedure linkage table later,
4546 when we know the address of the .got section. */
4547 if (h->type == STT_FUNC || h->needs_plt)
4549 if (h->plt.refcount <= 0
4550 || SYMBOL_CALLS_LOCAL (info, h)
4551 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4552 && h->root.type == bfd_link_hash_undefweak))
4554 /* This case can occur if we saw a CALL26 reloc in
4555 an input file, but the symbol wasn't referred to
4556 by a dynamic object or all references were
4557 garbage collected. In which case we can end up
4559 h->plt.offset = (bfd_vma) - 1;
4566 /* It's possible that we incorrectly decided a .plt reloc was
4567 needed for an R_X86_64_PC32 reloc to a non-function sym in
4568 check_relocs. We can't decide accurately between function and
4569 non-function syms in check-relocs; Objects loaded later in
4570 the link may change h->type. So fix it now. */
4571 h->plt.offset = (bfd_vma) - 1;
4574 /* If this is a weak symbol, and there is a real definition, the
4575 processor independent code will have arranged for us to see the
4576 real definition first, and we can just use the same value. */
4577 if (h->u.weakdef != NULL)
4579 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
4580 || h->u.weakdef->root.type == bfd_link_hash_defweak);
4581 h->root.u.def.section = h->u.weakdef->root.u.def.section;
4582 h->root.u.def.value = h->u.weakdef->root.u.def.value;
4583 if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
4584 h->non_got_ref = h->u.weakdef->non_got_ref;
4588 /* If we are creating a shared library, we must presume that the
4589 only references to the symbol are via the global offset table.
4590 For such cases we need not do anything here; the relocations will
4591 be handled correctly by relocate_section. */
4595 /* If there are no references to this symbol that do not use the
4596 GOT, we don't need to generate a copy reloc. */
4597 if (!h->non_got_ref)
4600 /* If -z nocopyreloc was given, we won't generate them either. */
4601 if (info->nocopyreloc)
4607 /* We must allocate the symbol in our .dynbss section, which will
4608 become part of the .bss section of the executable. There will be
4609 an entry for this symbol in the .dynsym section. The dynamic
4610 object will contain position independent code, so all references
4611 from the dynamic object to this symbol will go through the global
4612 offset table. The dynamic linker will use the .dynsym entry to
4613 determine the address it must put in the global offset table, so
4614 both the dynamic object and the regular object will refer to the
4615 same memory location for the variable. */
4617 htab = elf_aarch64_hash_table (info);
4619 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
4620 to copy the initial value out of the dynamic object and into the
4621 runtime process image. */
4622 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
4624 htab->srelbss->size += RELOC_SIZE (htab);
4630 return _bfd_elf_adjust_dynamic_copy (h, s);
4635 elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
4637 struct elf_aarch64_local_symbol *locals;
4638 locals = elf_aarch64_locals (abfd);
4641 locals = (struct elf_aarch64_local_symbol *)
4642 bfd_zalloc (abfd, number * sizeof (struct elf_aarch64_local_symbol));
4645 elf_aarch64_locals (abfd) = locals;
4650 /* Create the .got section to hold the global offset table. */
4653 aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
4655 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
4658 struct elf_link_hash_entry *h;
4659 struct elf_link_hash_table *htab = elf_hash_table (info);
4661 /* This function may be called more than once. */
4662 s = bfd_get_linker_section (abfd, ".got");
4666 flags = bed->dynamic_sec_flags;
4668 s = bfd_make_section_anyway_with_flags (abfd,
4669 (bed->rela_plts_and_copies_p
4670 ? ".rela.got" : ".rel.got"),
4671 (bed->dynamic_sec_flags
4674 || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
4678 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
4680 || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
4683 htab->sgot->size += GOT_ENTRY_SIZE;
4685 if (bed->want_got_sym)
4687 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
4688 (or .got.plt) section. We don't do this in the linker script
4689 because we don't want to define the symbol if we are not creating
4690 a global offset table. */
4691 h = _bfd_elf_define_linkage_sym (abfd, info, s,
4692 "_GLOBAL_OFFSET_TABLE_");
4693 elf_hash_table (info)->hgot = h;
4698 if (bed->want_got_plt)
4700 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
4702 || !bfd_set_section_alignment (abfd, s,
4703 bed->s->log_file_align))
4708 /* The first bit of the global offset table is the header. */
4709 s->size += bed->got_header_size;
4714 /* Look through the relocs for a section during the first phase. */
4717 elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
4718 asection *sec, const Elf_Internal_Rela *relocs)
4720 Elf_Internal_Shdr *symtab_hdr;
4721 struct elf_link_hash_entry **sym_hashes;
4722 const Elf_Internal_Rela *rel;
4723 const Elf_Internal_Rela *rel_end;
4726 struct elf_aarch64_link_hash_table *htab;
4728 if (info->relocatable)
4731 BFD_ASSERT (is_aarch64_elf (abfd));
4733 htab = elf_aarch64_hash_table (info);
4736 symtab_hdr = &elf_symtab_hdr (abfd);
4737 sym_hashes = elf_sym_hashes (abfd);
4739 rel_end = relocs + sec->reloc_count;
4740 for (rel = relocs; rel < rel_end; rel++)
4742 struct elf_link_hash_entry *h;
4743 unsigned long r_symndx;
4744 unsigned int r_type;
4745 bfd_reloc_code_real_type bfd_r_type;
4747 r_symndx = ELFNN_R_SYM (rel->r_info);
4748 r_type = ELFNN_R_TYPE (rel->r_info);
4750 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
4752 (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
4757 if (r_symndx < symtab_hdr->sh_info)
4761 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4762 while (h->root.type == bfd_link_hash_indirect
4763 || h->root.type == bfd_link_hash_warning)
4764 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4766 /* PR15323, ref flags aren't set for references in the same
4768 h->root.non_ir_ref = 1;
4771 /* Could be done earlier, if h were already available. */
4772 bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
4776 case BFD_RELOC_AARCH64_NN:
4778 /* We don't need to handle relocs into sections not going into
4779 the "real" output. */
4780 if ((sec->flags & SEC_ALLOC) == 0)
4788 h->plt.refcount += 1;
4789 h->pointer_equality_needed = 1;
4792 /* No need to do anything if we're not creating a shared
4798 struct elf_dyn_relocs *p;
4799 struct elf_dyn_relocs **head;
4801 /* We must copy these reloc types into the output file.
4802 Create a reloc section in dynobj and make room for
4806 if (htab->root.dynobj == NULL)
4807 htab->root.dynobj = abfd;
4809 sreloc = _bfd_elf_make_dynamic_reloc_section
4810 (sec, htab->root.dynobj, 3, abfd, /*rela? */ TRUE);
4816 /* If this is a global symbol, we count the number of
4817 relocations we need for this symbol. */
4820 struct elf_aarch64_link_hash_entry *eh;
4821 eh = (struct elf_aarch64_link_hash_entry *) h;
4822 head = &eh->dyn_relocs;
4826 /* Track dynamic relocs needed for local syms too.
4827 We really need local syms available to do this
4832 Elf_Internal_Sym *isym;
4834 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
4839 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
4843 /* Beware of type punned pointers vs strict aliasing
4845 vpp = &(elf_section_data (s)->local_dynrel);
4846 head = (struct elf_dyn_relocs **) vpp;
4850 if (p == NULL || p->sec != sec)
4852 bfd_size_type amt = sizeof *p;
4853 p = ((struct elf_dyn_relocs *)
4854 bfd_zalloc (htab->root.dynobj, amt));
4867 /* RR: We probably want to keep a consistency check that
4868 there are no dangling GOT_PAGE relocs. */
4869 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4870 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
4871 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
4872 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
4873 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4874 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4875 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
4876 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
4877 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
4878 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
4879 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4880 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
4881 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
4882 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
4883 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
4884 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
4885 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
4886 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
4887 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
4888 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
4889 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
4892 unsigned old_got_type;
4894 got_type = aarch64_reloc_got_type (bfd_r_type);
4898 h->got.refcount += 1;
4899 old_got_type = elf_aarch64_hash_entry (h)->got_type;
4903 struct elf_aarch64_local_symbol *locals;
4905 if (!elfNN_aarch64_allocate_local_symbols
4906 (abfd, symtab_hdr->sh_info))
4909 locals = elf_aarch64_locals (abfd);
4910 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
4911 locals[r_symndx].got_refcount += 1;
4912 old_got_type = locals[r_symndx].got_type;
4915 /* If a variable is accessed with both general dynamic TLS
4916 methods, two slots may be created. */
4917 if (GOT_TLS_GD_ANY_P (old_got_type) && GOT_TLS_GD_ANY_P (got_type))
4918 got_type |= old_got_type;
4920 /* We will already have issued an error message if there
4921 is a TLS/non-TLS mismatch, based on the symbol type.
4922 So just combine any TLS types needed. */
4923 if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
4924 && got_type != GOT_NORMAL)
4925 got_type |= old_got_type;
4927 /* If the symbol is accessed by both IE and GD methods, we
4928 are able to relax. Turn off the GD flag, without
4929 messing up with any other kind of TLS types that may be
4931 if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
4932 got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
4934 if (old_got_type != got_type)
4937 elf_aarch64_hash_entry (h)->got_type = got_type;
4940 struct elf_aarch64_local_symbol *locals;
4941 locals = elf_aarch64_locals (abfd);
4942 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
4943 locals[r_symndx].got_type = got_type;
4947 if (htab->root.dynobj == NULL)
4948 htab->root.dynobj = abfd;
4949 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
4954 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
4955 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
4956 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
4957 if (h != NULL && info->executable)
4959 /* If this reloc is in a read-only section, we might
4960 need a copy reloc. We can't check reliably at this
4961 stage whether the section is read-only, as input
4962 sections have not yet been mapped to output sections.
4963 Tentatively set the flag for now, and correct in
4964 adjust_dynamic_symbol. */
4966 h->plt.refcount += 1;
4967 h->pointer_equality_needed = 1;
4969 /* FIXME:: RR need to handle these in shared libraries
4970 and essentially bomb out as these being non-PIC
4971 relocations in shared libraries. */
4974 case BFD_RELOC_AARCH64_CALL26:
4975 case BFD_RELOC_AARCH64_JUMP26:
4976 /* If this is a local symbol then we resolve it
4977 directly without creating a PLT entry. */
4982 h->plt.refcount += 1;
4993 /* Treat mapping symbols as special target symbols. */
4996 elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED,
4999 return bfd_is_aarch64_special_symbol_name (sym->name,
5000 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
5003 /* This is a copy of elf_find_function () from elf.c except that
5004 AArch64 mapping symbols are ignored when looking for function names. */
5007 aarch64_elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
5011 const char **filename_ptr,
5012 const char **functionname_ptr)
5014 const char *filename = NULL;
5015 asymbol *func = NULL;
5016 bfd_vma low_func = 0;
5019 for (p = symbols; *p != NULL; p++)
5023 q = (elf_symbol_type *) * p;
5025 switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
5030 filename = bfd_asymbol_name (&q->symbol);
5034 /* Skip mapping symbols. */
5035 if ((q->symbol.flags & BSF_LOCAL)
5036 && (bfd_is_aarch64_special_symbol_name
5037 (q->symbol.name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)))
5040 if (bfd_get_section (&q->symbol) == section
5041 && q->symbol.value >= low_func && q->symbol.value <= offset)
5043 func = (asymbol *) q;
5044 low_func = q->symbol.value;
5054 *filename_ptr = filename;
5055 if (functionname_ptr)
5056 *functionname_ptr = bfd_asymbol_name (func);
5062 /* Find the nearest line to a particular section and offset, for error
5063 reporting. This code is a duplicate of the code in elf.c, except
5064 that it uses aarch64_elf_find_function. */
5067 elfNN_aarch64_find_nearest_line (bfd *abfd,
5071 const char **filename_ptr,
5072 const char **functionname_ptr,
5073 unsigned int *line_ptr)
5075 bfd_boolean found = FALSE;
5077 /* We skip _bfd_dwarf1_find_nearest_line since no known AArch64
5078 toolchain uses it. */
5080 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
5081 section, symbols, offset,
5082 filename_ptr, functionname_ptr,
5084 &elf_tdata (abfd)->dwarf2_find_line_info))
5086 if (!*functionname_ptr)
5087 aarch64_elf_find_function (abfd, section, symbols, offset,
5088 *filename_ptr ? NULL : filename_ptr,
5094 if (!_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
5095 &found, filename_ptr,
5096 functionname_ptr, line_ptr,
5097 &elf_tdata (abfd)->line_info))
5100 if (found && (*functionname_ptr || *line_ptr))
5103 if (symbols == NULL)
5106 if (!aarch64_elf_find_function (abfd, section, symbols, offset,
5107 filename_ptr, functionname_ptr))
5115 elfNN_aarch64_find_inliner_info (bfd *abfd,
5116 const char **filename_ptr,
5117 const char **functionname_ptr,
5118 unsigned int *line_ptr)
5121 found = _bfd_dwarf2_find_inliner_info
5122 (abfd, filename_ptr,
5123 functionname_ptr, line_ptr, &elf_tdata (abfd)->dwarf2_find_line_info);
5129 elfNN_aarch64_post_process_headers (bfd *abfd,
5130 struct bfd_link_info *link_info
5133 Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
5135 i_ehdrp = elf_elfheader (abfd);
5136 i_ehdrp->e_ident[EI_OSABI] = 0;
5137 i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
5140 static enum elf_reloc_type_class
5141 elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
5142 const asection *rel_sec ATTRIBUTE_UNUSED,
5143 const Elf_Internal_Rela *rela)
5145 switch ((int) ELFNN_R_TYPE (rela->r_info))
5147 case AARCH64_R (RELATIVE):
5148 return reloc_class_relative;
5149 case AARCH64_R (JUMP_SLOT):
5150 return reloc_class_plt;
5151 case AARCH64_R (COPY):
5152 return reloc_class_copy;
5154 return reloc_class_normal;
5158 /* Set the right machine number for an AArch64 ELF file. */
5161 elfNN_aarch64_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
5163 if (hdr->sh_type == SHT_NOTE)
5164 *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
5169 /* Handle an AArch64 specific section when reading an object file. This is
5170 called when bfd_section_from_shdr finds a section with an unknown
5174 elfNN_aarch64_section_from_shdr (bfd *abfd,
5175 Elf_Internal_Shdr *hdr,
5176 const char *name, int shindex)
5178 /* There ought to be a place to keep ELF backend specific flags, but
5179 at the moment there isn't one. We just keep track of the
5180 sections by their name, instead. Fortunately, the ABI gives
5181 names for all the AArch64 specific sections, so we will probably get
5183 switch (hdr->sh_type)
5185 case SHT_AARCH64_ATTRIBUTES:
5192 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5198 /* A structure used to record a list of sections, independently
5199 of the next and prev fields in the asection structure. */
5200 typedef struct section_list
5203 struct section_list *next;
5204 struct section_list *prev;
5208 /* Unfortunately we need to keep a list of sections for which
5209 an _aarch64_elf_section_data structure has been allocated. This
5210 is because it is possible for functions like elfNN_aarch64_write_section
5211 to be called on a section which has had an elf_data_structure
5212 allocated for it (and so the used_by_bfd field is valid) but
5213 for which the AArch64 extended version of this structure - the
5214 _aarch64_elf_section_data structure - has not been allocated. */
5215 static section_list *sections_with_aarch64_elf_section_data = NULL;
5218 record_section_with_aarch64_elf_section_data (asection *sec)
5220 struct section_list *entry;
5222 entry = bfd_malloc (sizeof (*entry));
5226 entry->next = sections_with_aarch64_elf_section_data;
5228 if (entry->next != NULL)
5229 entry->next->prev = entry;
5230 sections_with_aarch64_elf_section_data = entry;
5233 static struct section_list *
5234 find_aarch64_elf_section_entry (asection *sec)
5236 struct section_list *entry;
5237 static struct section_list *last_entry = NULL;
5239 /* This is a short cut for the typical case where the sections are added
5240 to the sections_with_aarch64_elf_section_data list in forward order and
5241 then looked up here in backwards order. This makes a real difference
5242 to the ld-srec/sec64k.exp linker test. */
5243 entry = sections_with_aarch64_elf_section_data;
5244 if (last_entry != NULL)
5246 if (last_entry->sec == sec)
5248 else if (last_entry->next != NULL && last_entry->next->sec == sec)
5249 entry = last_entry->next;
5252 for (; entry; entry = entry->next)
5253 if (entry->sec == sec)
5257 /* Record the entry prior to this one - it is the entry we are
5258 most likely to want to locate next time. Also this way if we
5259 have been called from
5260 unrecord_section_with_aarch64_elf_section_data () we will not
5261 be caching a pointer that is about to be freed. */
5262 last_entry = entry->prev;
5268 unrecord_section_with_aarch64_elf_section_data (asection *sec)
5270 struct section_list *entry;
5272 entry = find_aarch64_elf_section_entry (sec);
5276 if (entry->prev != NULL)
5277 entry->prev->next = entry->next;
5278 if (entry->next != NULL)
5279 entry->next->prev = entry->prev;
5280 if (entry == sections_with_aarch64_elf_section_data)
5281 sections_with_aarch64_elf_section_data = entry->next;
5290 struct bfd_link_info *info;
5293 int (*func) (void *, const char *, Elf_Internal_Sym *,
5294 asection *, struct elf_link_hash_entry *);
5295 } output_arch_syminfo;
5297 enum map_symbol_type
5304 /* Output a single mapping symbol. */
5307 elfNN_aarch64_output_map_sym (output_arch_syminfo *osi,
5308 enum map_symbol_type type, bfd_vma offset)
5310 static const char *names[2] = { "$x", "$d" };
5311 Elf_Internal_Sym sym;
5313 sym.st_value = (osi->sec->output_section->vma
5314 + osi->sec->output_offset + offset);
5317 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
5318 sym.st_shndx = osi->sec_shndx;
5319 return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
5324 /* Output mapping symbols for PLT entries associated with H. */
5327 elfNN_aarch64_output_plt_map (struct elf_link_hash_entry *h, void *inf)
5329 output_arch_syminfo *osi = (output_arch_syminfo *) inf;
5332 if (h->root.type == bfd_link_hash_indirect)
5335 if (h->root.type == bfd_link_hash_warning)
5336 /* When warning symbols are created, they **replace** the "real"
5337 entry in the hash table, thus we never get to see the real
5338 symbol in a hash traversal. So look at it now. */
5339 h = (struct elf_link_hash_entry *) h->root.u.i.link;
5341 if (h->plt.offset == (bfd_vma) - 1)
5344 addr = h->plt.offset;
5347 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
5354 /* Output a single local symbol for a generated stub. */
5357 elfNN_aarch64_output_stub_sym (output_arch_syminfo *osi, const char *name,
5358 bfd_vma offset, bfd_vma size)
5360 Elf_Internal_Sym sym;
5362 sym.st_value = (osi->sec->output_section->vma
5363 + osi->sec->output_offset + offset);
5366 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
5367 sym.st_shndx = osi->sec_shndx;
5368 return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
5372 aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
5374 struct elf_aarch64_stub_hash_entry *stub_entry;
5378 output_arch_syminfo *osi;
5380 /* Massage our args to the form they really have. */
5381 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
5382 osi = (output_arch_syminfo *) in_arg;
5384 stub_sec = stub_entry->stub_sec;
5386 /* Ensure this stub is attached to the current section being
5388 if (stub_sec != osi->sec)
5391 addr = (bfd_vma) stub_entry->stub_offset;
5393 stub_name = stub_entry->output_name;
5395 switch (stub_entry->stub_type)
5397 case aarch64_stub_adrp_branch:
5398 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
5399 sizeof (aarch64_adrp_branch_stub)))
5401 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
5404 case aarch64_stub_long_branch:
5405 if (!elfNN_aarch64_output_stub_sym
5406 (osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
5408 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
5410 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_DATA, addr + 16))
5420 /* Output mapping symbols for linker generated sections. */
5423 elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
5424 struct bfd_link_info *info,
5426 int (*func) (void *, const char *,
5429 struct elf_link_hash_entry
5432 output_arch_syminfo osi;
5433 struct elf_aarch64_link_hash_table *htab;
5435 htab = elf_aarch64_hash_table (info);
5441 /* Long calls stubs. */
5442 if (htab->stub_bfd && htab->stub_bfd->sections)
5446 for (stub_sec = htab->stub_bfd->sections;
5447 stub_sec != NULL; stub_sec = stub_sec->next)
5449 /* Ignore non-stub sections. */
5450 if (!strstr (stub_sec->name, STUB_SUFFIX))
5455 osi.sec_shndx = _bfd_elf_section_from_bfd_section
5456 (output_bfd, osi.sec->output_section);
5458 bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
5463 /* Finally, output mapping symbols for the PLT. */
5464 if (!htab->root.splt || htab->root.splt->size == 0)
5467 /* For now live without mapping symbols for the plt. */
5468 osi.sec_shndx = _bfd_elf_section_from_bfd_section
5469 (output_bfd, htab->root.splt->output_section);
5470 osi.sec = htab->root.splt;
5472 elf_link_hash_traverse (&htab->root, elfNN_aarch64_output_plt_map,
5479 /* Allocate target specific section data. */
5482 elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec)
5484 if (!sec->used_by_bfd)
5486 _aarch64_elf_section_data *sdata;
5487 bfd_size_type amt = sizeof (*sdata);
5489 sdata = bfd_zalloc (abfd, amt);
5492 sec->used_by_bfd = sdata;
5495 record_section_with_aarch64_elf_section_data (sec);
5497 return _bfd_elf_new_section_hook (abfd, sec);
5502 unrecord_section_via_map_over_sections (bfd *abfd ATTRIBUTE_UNUSED,
5504 void *ignore ATTRIBUTE_UNUSED)
5506 unrecord_section_with_aarch64_elf_section_data (sec);
5510 elfNN_aarch64_close_and_cleanup (bfd *abfd)
5513 bfd_map_over_sections (abfd,
5514 unrecord_section_via_map_over_sections, NULL);
5516 return _bfd_elf_close_and_cleanup (abfd);
5520 elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
5523 bfd_map_over_sections (abfd,
5524 unrecord_section_via_map_over_sections, NULL);
5526 return _bfd_free_cached_info (abfd);
5530 elfNN_aarch64_is_function_type (unsigned int type)
5532 return type == STT_FUNC;
5535 /* Create dynamic sections. This is different from the ARM backend in that
5536 the got, plt, gotplt and their relocation sections are all created in the
5537 standard part of the bfd elf backend. */
5540 elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
5541 struct bfd_link_info *info)
5543 struct elf_aarch64_link_hash_table *htab;
5545 /* We need to create .got section. */
5546 if (!aarch64_elf_create_got_section (dynobj, info))
5549 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
5552 htab = elf_aarch64_hash_table (info);
5553 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
5555 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
5557 if (!htab->sdynbss || (!info->shared && !htab->srelbss))
5564 /* Allocate space in .plt, .got and associated reloc sections for
5568 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
5570 struct bfd_link_info *info;
5571 struct elf_aarch64_link_hash_table *htab;
5572 struct elf_aarch64_link_hash_entry *eh;
5573 struct elf_dyn_relocs *p;
5575 /* An example of a bfd_link_hash_indirect symbol is versioned
5576 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
5577 -> __gxx_personality_v0(bfd_link_hash_defined)
5579 There is no need to process bfd_link_hash_indirect symbols here
5580 because we will also be presented with the concrete instance of
5581 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
5582 called to copy all relevant data from the generic to the concrete
5585 if (h->root.type == bfd_link_hash_indirect)
5588 if (h->root.type == bfd_link_hash_warning)
5589 h = (struct elf_link_hash_entry *) h->root.u.i.link;
5591 info = (struct bfd_link_info *) inf;
5592 htab = elf_aarch64_hash_table (info);
5594 if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
5596 /* Make sure this symbol is output as a dynamic symbol.
5597 Undefined weak syms won't yet be marked as dynamic. */
5598 if (h->dynindx == -1 && !h->forced_local)
5600 if (!bfd_elf_link_record_dynamic_symbol (info, h))
5604 if (info->shared || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
5606 asection *s = htab->root.splt;
5608 /* If this is the first .plt entry, make room for the special
5611 s->size += htab->plt_header_size;
5613 h->plt.offset = s->size;
5615 /* If this symbol is not defined in a regular file, and we are
5616 not generating a shared library, then set the symbol to this
5617 location in the .plt. This is required to make function
5618 pointers compare as equal between the normal executable and
5619 the shared library. */
5620 if (!info->shared && !h->def_regular)
5622 h->root.u.def.section = s;
5623 h->root.u.def.value = h->plt.offset;
5626 /* Make room for this entry. For now we only create the
5627 small model PLT entries. We later need to find a way
5628 of relaxing into these from the large model PLT entries. */
5629 s->size += PLT_SMALL_ENTRY_SIZE;
5631 /* We also need to make an entry in the .got.plt section, which
5632 will be placed in the .got section by the linker script. */
5633 htab->root.sgotplt->size += GOT_ENTRY_SIZE;
5635 /* We also need to make an entry in the .rela.plt section. */
5636 htab->root.srelplt->size += RELOC_SIZE (htab);
5638 /* We need to ensure that all GOT entries that serve the PLT
5639 are consecutive with the special GOT slots [0] [1] and
5640 [2]. Any addtional relocations, such as
5641 R_AARCH64_TLSDESC, must be placed after the PLT related
5642 entries. We abuse the reloc_count such that during
5643 sizing we adjust reloc_count to indicate the number of
5644 PLT related reserved entries. In subsequent phases when
5645 filling in the contents of the reloc entries, PLT related
5646 entries are placed by computing their PLT index (0
5647 .. reloc_count). While other none PLT relocs are placed
5648 at the slot indicated by reloc_count and reloc_count is
5651 htab->root.srelplt->reloc_count++;
5655 h->plt.offset = (bfd_vma) - 1;
5661 h->plt.offset = (bfd_vma) - 1;
5665 eh = (struct elf_aarch64_link_hash_entry *) h;
5666 eh->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
5668 if (h->got.refcount > 0)
5671 unsigned got_type = elf_aarch64_hash_entry (h)->got_type;
5673 h->got.offset = (bfd_vma) - 1;
5675 dyn = htab->root.dynamic_sections_created;
5677 /* Make sure this symbol is output as a dynamic symbol.
5678 Undefined weak syms won't yet be marked as dynamic. */
5679 if (dyn && h->dynindx == -1 && !h->forced_local)
5681 if (!bfd_elf_link_record_dynamic_symbol (info, h))
5685 if (got_type == GOT_UNKNOWN)
5688 else if (got_type == GOT_NORMAL)
5690 h->got.offset = htab->root.sgot->size;
5691 htab->root.sgot->size += GOT_ENTRY_SIZE;
5692 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5693 || h->root.type != bfd_link_hash_undefweak)
5695 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
5697 htab->root.srelgot->size += RELOC_SIZE (htab);
5703 if (got_type & GOT_TLSDESC_GD)
5705 eh->tlsdesc_got_jump_table_offset =
5706 (htab->root.sgotplt->size
5707 - aarch64_compute_jump_table_size (htab));
5708 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
5709 h->got.offset = (bfd_vma) - 2;
5712 if (got_type & GOT_TLS_GD)
5714 h->got.offset = htab->root.sgot->size;
5715 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
5718 if (got_type & GOT_TLS_IE)
5720 h->got.offset = htab->root.sgot->size;
5721 htab->root.sgot->size += GOT_ENTRY_SIZE;
5724 indx = h && h->dynindx != -1 ? h->dynindx : 0;
5725 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5726 || h->root.type != bfd_link_hash_undefweak)
5729 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
5731 if (got_type & GOT_TLSDESC_GD)
5733 htab->root.srelplt->size += RELOC_SIZE (htab);
5734 /* Note reloc_count not incremented here! We have
5735 already adjusted reloc_count for this relocation
5738 /* TLSDESC PLT is now needed, but not yet determined. */
5739 htab->tlsdesc_plt = (bfd_vma) - 1;
5742 if (got_type & GOT_TLS_GD)
5743 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
5745 if (got_type & GOT_TLS_IE)
5746 htab->root.srelgot->size += RELOC_SIZE (htab);
5752 h->got.offset = (bfd_vma) - 1;
5755 if (eh->dyn_relocs == NULL)
5758 /* In the shared -Bsymbolic case, discard space allocated for
5759 dynamic pc-relative relocs against symbols which turn out to be
5760 defined in regular objects. For the normal shared case, discard
5761 space for pc-relative relocs that have become local due to symbol
5762 visibility changes. */
5766 /* Relocs that use pc_count are those that appear on a call
5767 insn, or certain REL relocs that can generated via assembly.
5768 We want calls to protected symbols to resolve directly to the
5769 function rather than going via the plt. If people want
5770 function pointer comparisons to work as expected then they
5771 should avoid writing weird assembly. */
5772 if (SYMBOL_CALLS_LOCAL (info, h))
5774 struct elf_dyn_relocs **pp;
5776 for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
5778 p->count -= p->pc_count;
5787 /* Also discard relocs on undefined weak syms with non-default
5789 if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
5791 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
5792 eh->dyn_relocs = NULL;
5794 /* Make sure undefined weak symbols are output as a dynamic
5796 else if (h->dynindx == -1
5798 && !bfd_elf_link_record_dynamic_symbol (info, h))
5803 else if (ELIMINATE_COPY_RELOCS)
5805 /* For the non-shared case, discard space for relocs against
5806 symbols which turn out to need copy relocs or are not
5812 || (htab->root.dynamic_sections_created
5813 && (h->root.type == bfd_link_hash_undefweak
5814 || h->root.type == bfd_link_hash_undefined))))
5816 /* Make sure this symbol is output as a dynamic symbol.
5817 Undefined weak syms won't yet be marked as dynamic. */
5818 if (h->dynindx == -1
5820 && !bfd_elf_link_record_dynamic_symbol (info, h))
5823 /* If that succeeded, we know we'll be keeping all the
5825 if (h->dynindx != -1)
5829 eh->dyn_relocs = NULL;
5834 /* Finally, allocate space. */
5835 for (p = eh->dyn_relocs; p != NULL; p = p->next)
5839 sreloc = elf_section_data (p->sec)->sreloc;
5841 BFD_ASSERT (sreloc != NULL);
5843 sreloc->size += p->count * RELOC_SIZE (htab);
5850 /* This is the most important function of all . Innocuosly named
5853 elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
5854 struct bfd_link_info *info)
5856 struct elf_aarch64_link_hash_table *htab;
5862 htab = elf_aarch64_hash_table ((info));
5863 dynobj = htab->root.dynobj;
5865 BFD_ASSERT (dynobj != NULL);
5867 if (htab->root.dynamic_sections_created)
5869 if (info->executable)
5871 s = bfd_get_linker_section (dynobj, ".interp");
5874 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
5875 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
5879 /* Set up .got offsets for local syms, and space for local dynamic
5881 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
5883 struct elf_aarch64_local_symbol *locals = NULL;
5884 Elf_Internal_Shdr *symtab_hdr;
5888 if (!is_aarch64_elf (ibfd))
5891 for (s = ibfd->sections; s != NULL; s = s->next)
5893 struct elf_dyn_relocs *p;
5895 for (p = (struct elf_dyn_relocs *)
5896 (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
5898 if (!bfd_is_abs_section (p->sec)
5899 && bfd_is_abs_section (p->sec->output_section))
5901 /* Input section has been discarded, either because
5902 it is a copy of a linkonce section or due to
5903 linker script /DISCARD/, so we'll be discarding
5906 else if (p->count != 0)
5908 srel = elf_section_data (p->sec)->sreloc;
5909 srel->size += p->count * RELOC_SIZE (htab);
5910 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
5911 info->flags |= DF_TEXTREL;
5916 locals = elf_aarch64_locals (ibfd);
5920 symtab_hdr = &elf_symtab_hdr (ibfd);
5921 srel = htab->root.srelgot;
5922 for (i = 0; i < symtab_hdr->sh_info; i++)
5924 locals[i].got_offset = (bfd_vma) - 1;
5925 locals[i].tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
5926 if (locals[i].got_refcount > 0)
5928 unsigned got_type = locals[i].got_type;
5929 if (got_type & GOT_TLSDESC_GD)
5931 locals[i].tlsdesc_got_jump_table_offset =
5932 (htab->root.sgotplt->size
5933 - aarch64_compute_jump_table_size (htab));
5934 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
5935 locals[i].got_offset = (bfd_vma) - 2;
5938 if (got_type & GOT_TLS_GD)
5940 locals[i].got_offset = htab->root.sgot->size;
5941 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
5944 if (got_type & GOT_TLS_IE)
5946 locals[i].got_offset = htab->root.sgot->size;
5947 htab->root.sgot->size += GOT_ENTRY_SIZE;
5950 if (got_type == GOT_UNKNOWN)
5954 if (got_type == GOT_NORMAL)
5960 if (got_type & GOT_TLSDESC_GD)
5962 htab->root.srelplt->size += RELOC_SIZE (htab);
5963 /* Note RELOC_COUNT not incremented here! */
5964 htab->tlsdesc_plt = (bfd_vma) - 1;
5967 if (got_type & GOT_TLS_GD)
5968 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
5970 if (got_type & GOT_TLS_IE)
5971 htab->root.srelgot->size += RELOC_SIZE (htab);
5976 locals[i].got_refcount = (bfd_vma) - 1;
5982 /* Allocate global sym .plt and .got entries, and space for global
5983 sym dynamic relocs. */
5984 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
5988 /* For every jump slot reserved in the sgotplt, reloc_count is
5989 incremented. However, when we reserve space for TLS descriptors,
5990 it's not incremented, so in order to compute the space reserved
5991 for them, it suffices to multiply the reloc count by the jump
5994 if (htab->root.srelplt)
5995 htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab);
5997 if (htab->tlsdesc_plt)
5999 if (htab->root.splt->size == 0)
6000 htab->root.splt->size += PLT_ENTRY_SIZE;
6002 htab->tlsdesc_plt = htab->root.splt->size;
6003 htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
6005 /* If we're not using lazy TLS relocations, don't generate the
6006 GOT entry required. */
6007 if (!(info->flags & DF_BIND_NOW))
6009 htab->dt_tlsdesc_got = htab->root.sgot->size;
6010 htab->root.sgot->size += GOT_ENTRY_SIZE;
6014 /* We now have determined the sizes of the various dynamic sections.
6015 Allocate memory for them. */
6017 for (s = dynobj->sections; s != NULL; s = s->next)
6019 if ((s->flags & SEC_LINKER_CREATED) == 0)
6022 if (s == htab->root.splt
6023 || s == htab->root.sgot
6024 || s == htab->root.sgotplt
6025 || s == htab->root.iplt
6026 || s == htab->root.igotplt || s == htab->sdynbss)
6028 /* Strip this section if we don't need it; see the
6031 else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
6033 if (s->size != 0 && s != htab->root.srelplt)
6036 /* We use the reloc_count field as a counter if we need
6037 to copy relocs into the output file. */
6038 if (s != htab->root.srelplt)
6043 /* It's not one of our sections, so don't allocate space. */
6049 /* If we don't need this section, strip it from the
6050 output file. This is mostly to handle .rela.bss and
6051 .rela.plt. We must create both sections in
6052 create_dynamic_sections, because they must be created
6053 before the linker maps input sections to output
6054 sections. The linker does that before
6055 adjust_dynamic_symbol is called, and it is that
6056 function which decides whether anything needs to go
6057 into these sections. */
6059 s->flags |= SEC_EXCLUDE;
6063 if ((s->flags & SEC_HAS_CONTENTS) == 0)
6066 /* Allocate memory for the section contents. We use bfd_zalloc
6067 here in case unused entries are not reclaimed before the
6068 section's contents are written out. This should not happen,
6069 but this way if it does, we get a R_AARCH64_NONE reloc instead
6071 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
6072 if (s->contents == NULL)
6076 if (htab->root.dynamic_sections_created)
6078 /* Add some entries to the .dynamic section. We fill in the
6079 values later, in elfNN_aarch64_finish_dynamic_sections, but we
6080 must add the entries now so that we get the correct size for
6081 the .dynamic section. The DT_DEBUG entry is filled in by the
6082 dynamic linker and used by the debugger. */
6083 #define add_dynamic_entry(TAG, VAL) \
6084 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
6086 if (info->executable)
6088 if (!add_dynamic_entry (DT_DEBUG, 0))
6092 if (htab->root.splt->size != 0)
6094 if (!add_dynamic_entry (DT_PLTGOT, 0)
6095 || !add_dynamic_entry (DT_PLTRELSZ, 0)
6096 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
6097 || !add_dynamic_entry (DT_JMPREL, 0))
6100 if (htab->tlsdesc_plt
6101 && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
6102 || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
6108 if (!add_dynamic_entry (DT_RELA, 0)
6109 || !add_dynamic_entry (DT_RELASZ, 0)
6110 || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
6113 /* If any dynamic relocs apply to a read-only section,
6114 then we need a DT_TEXTREL entry. */
6115 if ((info->flags & DF_TEXTREL) != 0)
6117 if (!add_dynamic_entry (DT_TEXTREL, 0))
6122 #undef add_dynamic_entry
6128 elf_aarch64_update_plt_entry (bfd *output_bfd,
6129 bfd_reloc_code_real_type r_type,
6130 bfd_byte *plt_entry, bfd_vma value)
6132 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
6134 _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
6138 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
6139 struct elf_aarch64_link_hash_table
6140 *htab, bfd *output_bfd)
6142 bfd_byte *plt_entry;
6145 bfd_vma gotplt_entry_address;
6146 bfd_vma plt_entry_address;
6147 Elf_Internal_Rela rela;
6150 plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
6152 /* Offset in the GOT is PLT index plus got GOT headers(3)
6153 times GOT_ENTRY_SIZE. */
6154 got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
6155 plt_entry = htab->root.splt->contents + h->plt.offset;
6156 plt_entry_address = htab->root.splt->output_section->vma
6157 + htab->root.splt->output_section->output_offset + h->plt.offset;
6158 gotplt_entry_address = htab->root.sgotplt->output_section->vma +
6159 htab->root.sgotplt->output_offset + got_offset;
6161 /* Copy in the boiler-plate for the PLTn entry. */
6162 memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
6164 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
6165 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
6166 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
6168 PG (gotplt_entry_address) -
6169 PG (plt_entry_address));
6171 /* Fill in the lo12 bits for the load from the pltgot. */
6172 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
6174 PG_OFFSET (gotplt_entry_address));
6176 /* Fill in the the lo12 bits for the add from the pltgot entry. */
6177 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
6179 PG_OFFSET (gotplt_entry_address));
6181 /* All the GOTPLT Entries are essentially initialized to PLT0. */
6182 bfd_put_NN (output_bfd,
6183 (htab->root.splt->output_section->vma
6184 + htab->root.splt->output_offset),
6185 htab->root.sgotplt->contents + got_offset);
6187 /* Fill in the entry in the .rela.plt section. */
6188 rela.r_offset = gotplt_entry_address;
6189 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
6192 /* Compute the relocation entry to used based on PLT index and do
6193 not adjust reloc_count. The reloc_count has already been adjusted
6194 to account for this entry. */
6195 loc = htab->root.srelplt->contents + plt_index * RELOC_SIZE (htab);
6196 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6199 /* Size sections even though they're not dynamic. We use it to setup
6200 _TLS_MODULE_BASE_, if needed. */
6203 elfNN_aarch64_always_size_sections (bfd *output_bfd,
6204 struct bfd_link_info *info)
6208 if (info->relocatable)
6211 tls_sec = elf_hash_table (info)->tls_sec;
6215 struct elf_link_hash_entry *tlsbase;
6217 tlsbase = elf_link_hash_lookup (elf_hash_table (info),
6218 "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
6222 struct bfd_link_hash_entry *h = NULL;
6223 const struct elf_backend_data *bed =
6224 get_elf_backend_data (output_bfd);
6226 if (!(_bfd_generic_link_add_one_symbol
6227 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
6228 tls_sec, 0, NULL, FALSE, bed->collect, &h)))
6231 tlsbase->type = STT_TLS;
6232 tlsbase = (struct elf_link_hash_entry *) h;
6233 tlsbase->def_regular = 1;
6234 tlsbase->other = STV_HIDDEN;
6235 (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
6242 /* Finish up dynamic symbol handling. We set the contents of various
6243 dynamic sections here. */
6245 elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
6246 struct bfd_link_info *info,
6247 struct elf_link_hash_entry *h,
6248 Elf_Internal_Sym *sym)
6250 struct elf_aarch64_link_hash_table *htab;
6251 htab = elf_aarch64_hash_table (info);
6253 if (h->plt.offset != (bfd_vma) - 1)
6255 /* This symbol has an entry in the procedure linkage table. Set
6258 if (h->dynindx == -1
6259 || htab->root.splt == NULL
6260 || htab->root.sgotplt == NULL || htab->root.srelplt == NULL)
6263 elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd);
6264 if (!h->def_regular)
6266 /* Mark the symbol as undefined, rather than as defined in
6267 the .plt section. Leave the value alone. This is a clue
6268 for the dynamic linker, to make function pointer
6269 comparisons work between an application and shared
6271 sym->st_shndx = SHN_UNDEF;
6275 if (h->got.offset != (bfd_vma) - 1
6276 && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL)
6278 Elf_Internal_Rela rela;
6281 /* This symbol has an entry in the global offset table. Set it
6283 if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
6286 rela.r_offset = (htab->root.sgot->output_section->vma
6287 + htab->root.sgot->output_offset
6288 + (h->got.offset & ~(bfd_vma) 1));
6290 if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
6292 if (!h->def_regular)
6295 BFD_ASSERT ((h->got.offset & 1) != 0);
6296 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
6297 rela.r_addend = (h->root.u.def.value
6298 + h->root.u.def.section->output_section->vma
6299 + h->root.u.def.section->output_offset);
6303 BFD_ASSERT ((h->got.offset & 1) == 0);
6304 bfd_put_NN (output_bfd, (bfd_vma) 0,
6305 htab->root.sgot->contents + h->got.offset);
6306 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
6310 loc = htab->root.srelgot->contents;
6311 loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
6312 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6317 Elf_Internal_Rela rela;
6320 /* This symbol needs a copy reloc. Set it up. */
6322 if (h->dynindx == -1
6323 || (h->root.type != bfd_link_hash_defined
6324 && h->root.type != bfd_link_hash_defweak)
6325 || htab->srelbss == NULL)
6328 rela.r_offset = (h->root.u.def.value
6329 + h->root.u.def.section->output_section->vma
6330 + h->root.u.def.section->output_offset);
6331 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
6333 loc = htab->srelbss->contents;
6334 loc += htab->srelbss->reloc_count++ * RELOC_SIZE (htab);
6335 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6338 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
6339 be NULL for local symbols. */
6341 && (h == elf_hash_table (info)->hdynamic
6342 || h == elf_hash_table (info)->hgot))
6343 sym->st_shndx = SHN_ABS;
6349 elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
6350 struct elf_aarch64_link_hash_table
6353 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
6354 small and large plts and at the minute just generates
6357 /* PLT0 of the small PLT looks like this in ELF64 -
6358 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
6359 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
6360 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
6362 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
6363 // GOTPLT entry for this.
6365 PLT0 will be slightly different in ELF32 due to different got entry
6368 bfd_vma plt_got_2nd_ent; /* Address of GOT[2]. */
6372 memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry,
6374 elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
6377 plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
6378 + htab->root.sgotplt->output_offset
6379 + GOT_ENTRY_SIZE * 2);
6381 plt_base = htab->root.splt->output_section->vma +
6382 htab->root.splt->output_section->output_offset;
6384 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
6385 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
6386 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
6387 htab->root.splt->contents + 4,
6388 PG (plt_got_2nd_ent) - PG (plt_base + 4));
6390 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
6391 htab->root.splt->contents + 8,
6392 PG_OFFSET (plt_got_2nd_ent));
6394 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
6395 htab->root.splt->contents + 12,
6396 PG_OFFSET (plt_got_2nd_ent));
6400 elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
6401 struct bfd_link_info *info)
6403 struct elf_aarch64_link_hash_table *htab;
6407 htab = elf_aarch64_hash_table (info);
6408 dynobj = htab->root.dynobj;
6409 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
6411 if (htab->root.dynamic_sections_created)
6413 ElfNN_External_Dyn *dyncon, *dynconend;
6415 if (sdyn == NULL || htab->root.sgot == NULL)
6418 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
6419 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
6420 for (; dyncon < dynconend; dyncon++)
6422 Elf_Internal_Dyn dyn;
6425 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
6433 s = htab->root.sgotplt;
6434 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
6438 dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
6442 s = htab->root.srelplt->output_section;
6443 dyn.d_un.d_val = s->size;
6447 /* The procedure linkage table relocs (DT_JMPREL) should
6448 not be included in the overall relocs (DT_RELA).
6449 Therefore, we override the DT_RELASZ entry here to
6450 make it not include the JMPREL relocs. Since the
6451 linker script arranges for .rela.plt to follow all
6452 other relocation sections, we don't have to worry
6453 about changing the DT_RELA entry. */
6454 if (htab->root.srelplt != NULL)
6456 s = htab->root.srelplt->output_section;
6457 dyn.d_un.d_val -= s->size;
6461 case DT_TLSDESC_PLT:
6462 s = htab->root.splt;
6463 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
6464 + htab->tlsdesc_plt;
6467 case DT_TLSDESC_GOT:
6468 s = htab->root.sgot;
6469 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
6470 + htab->dt_tlsdesc_got;
6474 bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
6479 /* Fill in the special first entry in the procedure linkage table. */
6480 if (htab->root.splt && htab->root.splt->size > 0)
6482 elfNN_aarch64_init_small_plt0_entry (output_bfd, htab);
6484 elf_section_data (htab->root.splt->output_section)->
6485 this_hdr.sh_entsize = htab->plt_entry_size;
6488 if (htab->tlsdesc_plt)
6490 bfd_put_NN (output_bfd, (bfd_vma) 0,
6491 htab->root.sgot->contents + htab->dt_tlsdesc_got);
6493 memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
6494 elfNN_aarch64_tlsdesc_small_plt_entry,
6495 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));
6498 bfd_vma adrp1_addr =
6499 htab->root.splt->output_section->vma
6500 + htab->root.splt->output_offset + htab->tlsdesc_plt + 4;
6502 bfd_vma adrp2_addr = adrp1_addr + 4;
6505 htab->root.sgot->output_section->vma
6506 + htab->root.sgot->output_offset;
6508 bfd_vma pltgot_addr =
6509 htab->root.sgotplt->output_section->vma
6510 + htab->root.sgotplt->output_offset;
6512 bfd_vma dt_tlsdesc_got = got_addr + htab->dt_tlsdesc_got;
6514 bfd_byte *plt_entry =
6515 htab->root.splt->contents + htab->tlsdesc_plt;
6517 /* adrp x2, DT_TLSDESC_GOT */
6518 elf_aarch64_update_plt_entry (output_bfd,
6519 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
6521 (PG (dt_tlsdesc_got)
6522 - PG (adrp1_addr)));
6525 elf_aarch64_update_plt_entry (output_bfd,
6526 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
6529 - PG (adrp2_addr)));
6531 /* ldr x2, [x2, #0] */
6532 elf_aarch64_update_plt_entry (output_bfd,
6533 BFD_RELOC_AARCH64_LDSTNN_LO12,
6535 PG_OFFSET (dt_tlsdesc_got));
6538 elf_aarch64_update_plt_entry (output_bfd,
6539 BFD_RELOC_AARCH64_ADD_LO12,
6541 PG_OFFSET (pltgot_addr));
6546 if (htab->root.sgotplt)
6548 if (bfd_is_abs_section (htab->root.sgotplt->output_section))
6550 (*_bfd_error_handler)
6551 (_("discarded output section: `%A'"), htab->root.sgotplt);
6555 /* Fill in the first three entries in the global offset table. */
6556 if (htab->root.sgotplt->size > 0)
6558 bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
6560 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
6561 bfd_put_NN (output_bfd,
6563 htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
6564 bfd_put_NN (output_bfd,
6566 htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
6569 if (htab->root.sgot)
6571 if (htab->root.sgot->size > 0)
6574 sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
6575 bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
6579 elf_section_data (htab->root.sgotplt->output_section)->
6580 this_hdr.sh_entsize = GOT_ENTRY_SIZE;
6583 if (htab->root.sgot && htab->root.sgot->size > 0)
6584 elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
6590 /* Return address for Ith PLT stub in section PLT, for relocation REL
6591 or (bfd_vma) -1 if it should not be included. */
6594 elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
6595 const arelent *rel ATTRIBUTE_UNUSED)
6597 return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
6601 /* We use this so we can override certain functions
6602 (though currently we don't). */
6604 const struct elf_size_info elfNN_aarch64_size_info =
6606 sizeof (ElfNN_External_Ehdr),
6607 sizeof (ElfNN_External_Phdr),
6608 sizeof (ElfNN_External_Shdr),
6609 sizeof (ElfNN_External_Rel),
6610 sizeof (ElfNN_External_Rela),
6611 sizeof (ElfNN_External_Sym),
6612 sizeof (ElfNN_External_Dyn),
6613 sizeof (Elf_External_Note),
6614 4, /* Hash table entry size. */
6615 1, /* Internal relocs per external relocs. */
6616 ARCH_SIZE, /* Arch size. */
6617 LOG_FILE_ALIGN, /* Log_file_align. */
6618 ELFCLASSNN, EV_CURRENT,
6619 bfd_elfNN_write_out_phdrs,
6620 bfd_elfNN_write_shdrs_and_ehdr,
6621 bfd_elfNN_checksum_contents,
6622 bfd_elfNN_write_relocs,
6623 bfd_elfNN_swap_symbol_in,
6624 bfd_elfNN_swap_symbol_out,
6625 bfd_elfNN_slurp_reloc_table,
6626 bfd_elfNN_slurp_symbol_table,
6627 bfd_elfNN_swap_dyn_in,
6628 bfd_elfNN_swap_dyn_out,
6629 bfd_elfNN_swap_reloc_in,
6630 bfd_elfNN_swap_reloc_out,
6631 bfd_elfNN_swap_reloca_in,
6632 bfd_elfNN_swap_reloca_out
6635 #define ELF_ARCH bfd_arch_aarch64
6636 #define ELF_MACHINE_CODE EM_AARCH64
6637 #define ELF_MAXPAGESIZE 0x10000
6638 #define ELF_MINPAGESIZE 0x1000
6639 #define ELF_COMMONPAGESIZE 0x1000
6641 #define bfd_elfNN_close_and_cleanup \
6642 elfNN_aarch64_close_and_cleanup
6644 #define bfd_elfNN_bfd_copy_private_bfd_data \
6645 elfNN_aarch64_copy_private_bfd_data
6647 #define bfd_elfNN_bfd_free_cached_info \
6648 elfNN_aarch64_bfd_free_cached_info
6650 #define bfd_elfNN_bfd_is_target_special_symbol \
6651 elfNN_aarch64_is_target_special_symbol
6653 #define bfd_elfNN_bfd_link_hash_table_create \
6654 elfNN_aarch64_link_hash_table_create
6656 #define bfd_elfNN_bfd_link_hash_table_free \
6657 elfNN_aarch64_hash_table_free
6659 #define bfd_elfNN_bfd_merge_private_bfd_data \
6660 elfNN_aarch64_merge_private_bfd_data
6662 #define bfd_elfNN_bfd_print_private_bfd_data \
6663 elfNN_aarch64_print_private_bfd_data
6665 #define bfd_elfNN_bfd_reloc_type_lookup \
6666 elfNN_aarch64_reloc_type_lookup
6668 #define bfd_elfNN_bfd_reloc_name_lookup \
6669 elfNN_aarch64_reloc_name_lookup
6671 #define bfd_elfNN_bfd_set_private_flags \
6672 elfNN_aarch64_set_private_flags
6674 #define bfd_elfNN_find_inliner_info \
6675 elfNN_aarch64_find_inliner_info
6677 #define bfd_elfNN_find_nearest_line \
6678 elfNN_aarch64_find_nearest_line
6680 #define bfd_elfNN_mkobject \
6681 elfNN_aarch64_mkobject
6683 #define bfd_elfNN_new_section_hook \
6684 elfNN_aarch64_new_section_hook
6686 #define elf_backend_adjust_dynamic_symbol \
6687 elfNN_aarch64_adjust_dynamic_symbol
6689 #define elf_backend_always_size_sections \
6690 elfNN_aarch64_always_size_sections
6692 #define elf_backend_check_relocs \
6693 elfNN_aarch64_check_relocs
6695 #define elf_backend_copy_indirect_symbol \
6696 elfNN_aarch64_copy_indirect_symbol
6698 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
6699 to them in our hash. */
6700 #define elf_backend_create_dynamic_sections \
6701 elfNN_aarch64_create_dynamic_sections
6703 #define elf_backend_init_index_section \
6704 _bfd_elf_init_2_index_sections
6706 #define elf_backend_is_function_type \
6707 elfNN_aarch64_is_function_type
6709 #define elf_backend_finish_dynamic_sections \
6710 elfNN_aarch64_finish_dynamic_sections
6712 #define elf_backend_finish_dynamic_symbol \
6713 elfNN_aarch64_finish_dynamic_symbol
6715 #define elf_backend_gc_sweep_hook \
6716 elfNN_aarch64_gc_sweep_hook
6718 #define elf_backend_object_p \
6719 elfNN_aarch64_object_p
6721 #define elf_backend_output_arch_local_syms \
6722 elfNN_aarch64_output_arch_local_syms
6724 #define elf_backend_plt_sym_val \
6725 elfNN_aarch64_plt_sym_val
6727 #define elf_backend_post_process_headers \
6728 elfNN_aarch64_post_process_headers
6730 #define elf_backend_relocate_section \
6731 elfNN_aarch64_relocate_section
6733 #define elf_backend_reloc_type_class \
6734 elfNN_aarch64_reloc_type_class
6736 #define elf_backend_section_flags \
6737 elfNN_aarch64_section_flags
6739 #define elf_backend_section_from_shdr \
6740 elfNN_aarch64_section_from_shdr
6742 #define elf_backend_size_dynamic_sections \
6743 elfNN_aarch64_size_dynamic_sections
6745 #define elf_backend_size_info \
6746 elfNN_aarch64_size_info
6748 #define elf_backend_can_refcount 1
6749 #define elf_backend_can_gc_sections 1
6750 #define elf_backend_plt_readonly 1
6751 #define elf_backend_want_got_plt 1
6752 #define elf_backend_want_plt_sym 0
6753 #define elf_backend_may_use_rel_p 0
6754 #define elf_backend_may_use_rela_p 1
6755 #define elf_backend_default_use_rela_p 1
6756 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
6757 #define elf_backend_default_execstack 0
6759 #undef elf_backend_obj_attrs_section
6760 #define elf_backend_obj_attrs_section ".ARM.attributes"
6762 #include "elfNN-target.h"