1 /* AArch64-specific support for NN-bit ELF.
2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* Notes on implementation:
23 Thread Local Store (TLS)
27 The implementation currently supports both traditional TLS and TLS
28 descriptors, but only general dynamic (GD).
30 For traditional TLS the assembler will present us with code
31 fragments of the form:
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
40 For TLS descriptors the assembler will present us with code
41 fragments of the form:
43 adrp x0, :tlsdesc:foo R_AARCH64_TLSDESC_ADR_PAGE21(foo)
44 ldr x1, [x0, #:tlsdesc_lo12:foo] R_AARCH64_TLSDESC_LD64_LO12(foo)
45 add x0, x0, #:tlsdesc_lo12:foo R_AARCH64_TLSDESC_ADD_LO12(foo)
47 blr x1 R_AARCH64_TLSDESC_CALL(foo)
49 The relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} against foo
50 indicate that foo is thread local and should be accessed via the
51 traditional TLS mechanims.
53 The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
54 against foo indicate that 'foo' is thread local and should be accessed
55 via a TLS descriptor mechanism.
57 The precise instruction sequence is only relevant from the
58 perspective of linker relaxation which is currently not implemented.
60 The static linker must detect that 'foo' is a TLS object and
61 allocate a double GOT entry. The GOT entry must be created for both
62 global and local TLS symbols. Note that this is different to none
63 TLS local objects which do not need a GOT entry.
65 In the traditional TLS mechanism, the double GOT entry is used to
66 provide the tls_index structure, containing module and offset
67 entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
68 on the module entry. The loader will subsequently fixup this
69 relocation with the module identity.
71 For global traditional TLS symbols the static linker places an
72 R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
73 will subsequently fixup the offset. For local TLS symbols the static
74 linker fixes up offset.
76 In the TLS descriptor mechanism the double GOT entry is used to
77 provide the descriptor. The static linker places the relocation
78 R_AARCH64_TLSDESC on the first GOT slot. The loader will
79 subsequently fix this up.
83 The handling of TLS symbols is implemented across a number of
84 different backend functions. The following is a top level view of
85 what processing is performed where.
87 The TLS implementation maintains state information for each TLS
88 symbol. The state information for local and global symbols is kept
89 in different places. Global symbols use generic BFD structures while
90 local symbols use backend specific structures that are allocated and
91 maintained entirely by the backend.
95 elfNN_aarch64_check_relocs()
97 This function is invoked for each relocation.
99 The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
100 R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
101 spotted. One time creation of local symbol data structures are
102 created when the first local symbol is seen.
104 The reference count for a symbol is incremented. The GOT type for
105 each symbol is marked as general dynamic.
107 elfNN_aarch64_allocate_dynrelocs ()
109 For each global with positive reference count we allocate a double
110 GOT slot. For a traditional TLS symbol we allocate space for two
111 relocation entries on the GOT, for a TLS descriptor symbol we
112 allocate space for one relocation on the slot. Record the GOT offset
115 elfNN_aarch64_size_dynamic_sections ()
117 Iterate all input BFDS, look for in the local symbol data structure
118 constructed earlier for local TLS symbols and allocate them double
119 GOT slots along with space for a single GOT relocation. Update the
120 local symbol structure to record the GOT offset allocated.
122 elfNN_aarch64_relocate_section ()
124 Calls elfNN_aarch64_final_link_relocate ()
126 Emit the relevant TLS relocations against the GOT for each TLS
127 symbol. For local TLS symbols emit the GOT offset directly. The GOT
128 relocations are emitted once the first time a TLS symbol is
129 encountered. The implementation uses the LSB of the GOT offset to
130 flag that the relevant GOT relocations for a symbol have been
131 emitted. All of the TLS code that uses the GOT offset needs to take
132 care to mask out this flag bit before using the offset.
134 elfNN_aarch64_final_link_relocate ()
136 Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
140 #include "libiberty.h"
142 #include "bfd_stdint.h"
145 #include "objalloc.h"
146 #include "elf/aarch64.h"
147 #include "elfxx-aarch64.h"
152 #define AARCH64_R(NAME) R_AARCH64_ ## NAME
153 #define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
154 #define HOWTO64(...) HOWTO (__VA_ARGS__)
155 #define HOWTO32(...) EMPTY_HOWTO (0)
156 #define LOG_FILE_ALIGN 3
160 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
161 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
162 #define HOWTO64(...) EMPTY_HOWTO (0)
163 #define HOWTO32(...) HOWTO (__VA_ARGS__)
164 #define LOG_FILE_ALIGN 2
167 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
168 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
169 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
170 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
171 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
191 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
193 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
194 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
207 #define ELIMINATE_COPY_RELOCS 0
209 /* Return size of a relocation entry. HTAB is the bfd's
210 elf_aarch64_link_hash_entry. */
211 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
213 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
214 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
215 #define PLT_ENTRY_SIZE (32)
216 #define PLT_SMALL_ENTRY_SIZE (16)
217 #define PLT_TLSDESC_ENTRY_SIZE (32)
219 /* Encoding of the nop instruction */
220 #define INSN_NOP 0xd503201f
222 #define aarch64_compute_jump_table_size(htab) \
223 (((htab)->root.srelplt == NULL) ? 0 \
224 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
226 /* The first entry in a procedure linkage table looks like this
227 if the distance between the PLTGOT and the PLT is < 4GB use
228 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
229 in x16 and needs to work out PLTGOT[1] by using an address of
230 [x16,#-GOT_ENTRY_SIZE]. */
231 static const bfd_byte elfNN_aarch64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
233 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
234 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
236 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
237 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
239 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
240 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
242 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
243 0x1f, 0x20, 0x03, 0xd5, /* nop */
244 0x1f, 0x20, 0x03, 0xd5, /* nop */
245 0x1f, 0x20, 0x03, 0xd5, /* nop */
248 /* Per function entry in a procedure linkage table looks like this
249 if the distance between the PLTGOT and the PLT is < 4GB use
250 these PLT entries. */
251 static const bfd_byte elfNN_aarch64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
253 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
255 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
256 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
258 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
259 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
261 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
264 static const bfd_byte
265 elfNN_aarch64_tlsdesc_small_plt_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
267 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
268 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
269 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
271 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
272 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
274 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
275 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
277 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
278 0x1f, 0x20, 0x03, 0xd5, /* nop */
279 0x1f, 0x20, 0x03, 0xd5, /* nop */
282 #define elf_info_to_howto elfNN_aarch64_info_to_howto
283 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
285 #define AARCH64_ELF_ABI_VERSION 0
287 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
288 #define ALL_ONES (~ (bfd_vma) 0)
290 /* Indexed by the bfd interal reloc enumerators.
291 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
294 static reloc_howto_type elfNN_aarch64_howto_table
[] =
298 /* Basic data relocations. */
301 HOWTO (R_AARCH64_NULL
, /* type */
303 3, /* size (0 = byte, 1 = short, 2 = long) */
305 FALSE
, /* pc_relative */
307 complain_overflow_dont
, /* complain_on_overflow */
308 bfd_elf_generic_reloc
, /* special_function */
309 "R_AARCH64_NULL", /* name */
310 FALSE
, /* partial_inplace */
313 FALSE
), /* pcrel_offset */
315 HOWTO (R_AARCH64_NONE
, /* type */
317 3, /* size (0 = byte, 1 = short, 2 = long) */
319 FALSE
, /* pc_relative */
321 complain_overflow_dont
, /* complain_on_overflow */
322 bfd_elf_generic_reloc
, /* special_function */
323 "R_AARCH64_NONE", /* name */
324 FALSE
, /* partial_inplace */
327 FALSE
), /* pcrel_offset */
331 HOWTO64 (AARCH64_R (ABS64
), /* type */
333 4, /* size (4 = long long) */
335 FALSE
, /* pc_relative */
337 complain_overflow_unsigned
, /* complain_on_overflow */
338 bfd_elf_generic_reloc
, /* special_function */
339 AARCH64_R_STR (ABS64
), /* name */
340 FALSE
, /* partial_inplace */
341 ALL_ONES
, /* src_mask */
342 ALL_ONES
, /* dst_mask */
343 FALSE
), /* pcrel_offset */
346 HOWTO (AARCH64_R (ABS32
), /* type */
348 2, /* size (0 = byte, 1 = short, 2 = long) */
350 FALSE
, /* pc_relative */
352 complain_overflow_unsigned
, /* complain_on_overflow */
353 bfd_elf_generic_reloc
, /* special_function */
354 AARCH64_R_STR (ABS32
), /* name */
355 FALSE
, /* partial_inplace */
356 0xffffffff, /* src_mask */
357 0xffffffff, /* dst_mask */
358 FALSE
), /* pcrel_offset */
361 HOWTO (AARCH64_R (ABS16
), /* type */
363 1, /* size (0 = byte, 1 = short, 2 = long) */
365 FALSE
, /* pc_relative */
367 complain_overflow_unsigned
, /* complain_on_overflow */
368 bfd_elf_generic_reloc
, /* special_function */
369 AARCH64_R_STR (ABS16
), /* name */
370 FALSE
, /* partial_inplace */
371 0xffff, /* src_mask */
372 0xffff, /* dst_mask */
373 FALSE
), /* pcrel_offset */
375 /* .xword: (S+A-P) */
376 HOWTO64 (AARCH64_R (PREL64
), /* type */
378 4, /* size (4 = long long) */
380 TRUE
, /* pc_relative */
382 complain_overflow_signed
, /* complain_on_overflow */
383 bfd_elf_generic_reloc
, /* special_function */
384 AARCH64_R_STR (PREL64
), /* name */
385 FALSE
, /* partial_inplace */
386 ALL_ONES
, /* src_mask */
387 ALL_ONES
, /* dst_mask */
388 TRUE
), /* pcrel_offset */
391 HOWTO (AARCH64_R (PREL32
), /* type */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
395 TRUE
, /* pc_relative */
397 complain_overflow_signed
, /* complain_on_overflow */
398 bfd_elf_generic_reloc
, /* special_function */
399 AARCH64_R_STR (PREL32
), /* name */
400 FALSE
, /* partial_inplace */
401 0xffffffff, /* src_mask */
402 0xffffffff, /* dst_mask */
403 TRUE
), /* pcrel_offset */
406 HOWTO (AARCH64_R (PREL16
), /* type */
408 1, /* size (0 = byte, 1 = short, 2 = long) */
410 TRUE
, /* pc_relative */
412 complain_overflow_signed
, /* complain_on_overflow */
413 bfd_elf_generic_reloc
, /* special_function */
414 AARCH64_R_STR (PREL16
), /* name */
415 FALSE
, /* partial_inplace */
416 0xffff, /* src_mask */
417 0xffff, /* dst_mask */
418 TRUE
), /* pcrel_offset */
420 /* Group relocations to create a 16, 32, 48 or 64 bit
421 unsigned data or abs address inline. */
423 /* MOVZ: ((S+A) >> 0) & 0xffff */
424 HOWTO (AARCH64_R (MOVW_UABS_G0
), /* type */
426 2, /* size (0 = byte, 1 = short, 2 = long) */
428 FALSE
, /* pc_relative */
430 complain_overflow_unsigned
, /* complain_on_overflow */
431 bfd_elf_generic_reloc
, /* special_function */
432 AARCH64_R_STR (MOVW_UABS_G0
), /* name */
433 FALSE
, /* partial_inplace */
434 0xffff, /* src_mask */
435 0xffff, /* dst_mask */
436 FALSE
), /* pcrel_offset */
438 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
439 HOWTO (AARCH64_R (MOVW_UABS_G0_NC
), /* type */
441 2, /* size (0 = byte, 1 = short, 2 = long) */
443 FALSE
, /* pc_relative */
445 complain_overflow_dont
, /* complain_on_overflow */
446 bfd_elf_generic_reloc
, /* special_function */
447 AARCH64_R_STR (MOVW_UABS_G0_NC
), /* name */
448 FALSE
, /* partial_inplace */
449 0xffff, /* src_mask */
450 0xffff, /* dst_mask */
451 FALSE
), /* pcrel_offset */
453 /* MOVZ: ((S+A) >> 16) & 0xffff */
454 HOWTO (AARCH64_R (MOVW_UABS_G1
), /* type */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
458 FALSE
, /* pc_relative */
460 complain_overflow_unsigned
, /* complain_on_overflow */
461 bfd_elf_generic_reloc
, /* special_function */
462 AARCH64_R_STR (MOVW_UABS_G1
), /* name */
463 FALSE
, /* partial_inplace */
464 0xffff, /* src_mask */
465 0xffff, /* dst_mask */
466 FALSE
), /* pcrel_offset */
468 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
469 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC
), /* type */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 FALSE
, /* pc_relative */
475 complain_overflow_dont
, /* complain_on_overflow */
476 bfd_elf_generic_reloc
, /* special_function */
477 AARCH64_R_STR (MOVW_UABS_G1_NC
), /* name */
478 FALSE
, /* partial_inplace */
479 0xffff, /* src_mask */
480 0xffff, /* dst_mask */
481 FALSE
), /* pcrel_offset */
483 /* MOVZ: ((S+A) >> 32) & 0xffff */
484 HOWTO64 (AARCH64_R (MOVW_UABS_G2
), /* type */
486 2, /* size (0 = byte, 1 = short, 2 = long) */
488 FALSE
, /* pc_relative */
490 complain_overflow_unsigned
, /* complain_on_overflow */
491 bfd_elf_generic_reloc
, /* special_function */
492 AARCH64_R_STR (MOVW_UABS_G2
), /* name */
493 FALSE
, /* partial_inplace */
494 0xffff, /* src_mask */
495 0xffff, /* dst_mask */
496 FALSE
), /* pcrel_offset */
498 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
499 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC
), /* type */
501 2, /* size (0 = byte, 1 = short, 2 = long) */
503 FALSE
, /* pc_relative */
505 complain_overflow_dont
, /* complain_on_overflow */
506 bfd_elf_generic_reloc
, /* special_function */
507 AARCH64_R_STR (MOVW_UABS_G2_NC
), /* name */
508 FALSE
, /* partial_inplace */
509 0xffff, /* src_mask */
510 0xffff, /* dst_mask */
511 FALSE
), /* pcrel_offset */
513 /* MOVZ: ((S+A) >> 48) & 0xffff */
514 HOWTO64 (AARCH64_R (MOVW_UABS_G3
), /* type */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
518 FALSE
, /* pc_relative */
520 complain_overflow_unsigned
, /* complain_on_overflow */
521 bfd_elf_generic_reloc
, /* special_function */
522 AARCH64_R_STR (MOVW_UABS_G3
), /* name */
523 FALSE
, /* partial_inplace */
524 0xffff, /* src_mask */
525 0xffff, /* dst_mask */
526 FALSE
), /* pcrel_offset */
528 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
529 signed data or abs address inline. Will change instruction
530 to MOVN or MOVZ depending on sign of calculated value. */
532 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
533 HOWTO (AARCH64_R (MOVW_SABS_G0
), /* type */
535 2, /* size (0 = byte, 1 = short, 2 = long) */
537 FALSE
, /* pc_relative */
539 complain_overflow_signed
, /* complain_on_overflow */
540 bfd_elf_generic_reloc
, /* special_function */
541 AARCH64_R_STR (MOVW_SABS_G0
), /* name */
542 FALSE
, /* partial_inplace */
543 0xffff, /* src_mask */
544 0xffff, /* dst_mask */
545 FALSE
), /* pcrel_offset */
547 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
548 HOWTO64 (AARCH64_R (MOVW_SABS_G1
), /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 FALSE
, /* pc_relative */
554 complain_overflow_signed
, /* complain_on_overflow */
555 bfd_elf_generic_reloc
, /* special_function */
556 AARCH64_R_STR (MOVW_SABS_G1
), /* name */
557 FALSE
, /* partial_inplace */
558 0xffff, /* src_mask */
559 0xffff, /* dst_mask */
560 FALSE
), /* pcrel_offset */
562 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
563 HOWTO64 (AARCH64_R (MOVW_SABS_G2
), /* type */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
567 FALSE
, /* pc_relative */
569 complain_overflow_signed
, /* complain_on_overflow */
570 bfd_elf_generic_reloc
, /* special_function */
571 AARCH64_R_STR (MOVW_SABS_G2
), /* name */
572 FALSE
, /* partial_inplace */
573 0xffff, /* src_mask */
574 0xffff, /* dst_mask */
575 FALSE
), /* pcrel_offset */
577 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
578 addresses: PG(x) is (x & ~0xfff). */
580 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
581 HOWTO (AARCH64_R (LD_PREL_LO19
), /* type */
583 2, /* size (0 = byte, 1 = short, 2 = long) */
585 TRUE
, /* pc_relative */
587 complain_overflow_signed
, /* complain_on_overflow */
588 bfd_elf_generic_reloc
, /* special_function */
589 AARCH64_R_STR (LD_PREL_LO19
), /* name */
590 FALSE
, /* partial_inplace */
591 0x7ffff, /* src_mask */
592 0x7ffff, /* dst_mask */
593 TRUE
), /* pcrel_offset */
595 /* ADR: (S+A-P) & 0x1fffff */
596 HOWTO (AARCH64_R (ADR_PREL_LO21
), /* type */
598 2, /* size (0 = byte, 1 = short, 2 = long) */
600 TRUE
, /* pc_relative */
602 complain_overflow_signed
, /* complain_on_overflow */
603 bfd_elf_generic_reloc
, /* special_function */
604 AARCH64_R_STR (ADR_PREL_LO21
), /* name */
605 FALSE
, /* partial_inplace */
606 0x1fffff, /* src_mask */
607 0x1fffff, /* dst_mask */
608 TRUE
), /* pcrel_offset */
610 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
611 HOWTO (AARCH64_R (ADR_PREL_PG_HI21
), /* type */
613 2, /* size (0 = byte, 1 = short, 2 = long) */
615 TRUE
, /* pc_relative */
617 complain_overflow_signed
, /* complain_on_overflow */
618 bfd_elf_generic_reloc
, /* special_function */
619 AARCH64_R_STR (ADR_PREL_PG_HI21
), /* name */
620 FALSE
, /* partial_inplace */
621 0x1fffff, /* src_mask */
622 0x1fffff, /* dst_mask */
623 TRUE
), /* pcrel_offset */
625 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
626 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC
), /* type */
628 2, /* size (0 = byte, 1 = short, 2 = long) */
630 TRUE
, /* pc_relative */
632 complain_overflow_dont
, /* complain_on_overflow */
633 bfd_elf_generic_reloc
, /* special_function */
634 AARCH64_R_STR (ADR_PREL_PG_HI21_NC
), /* name */
635 FALSE
, /* partial_inplace */
636 0x1fffff, /* src_mask */
637 0x1fffff, /* dst_mask */
638 TRUE
), /* pcrel_offset */
640 /* ADD: (S+A) & 0xfff [no overflow check] */
641 HOWTO (AARCH64_R (ADD_ABS_LO12_NC
), /* type */
643 2, /* size (0 = byte, 1 = short, 2 = long) */
645 FALSE
, /* pc_relative */
647 complain_overflow_dont
, /* complain_on_overflow */
648 bfd_elf_generic_reloc
, /* special_function */
649 AARCH64_R_STR (ADD_ABS_LO12_NC
), /* name */
650 FALSE
, /* partial_inplace */
651 0x3ffc00, /* src_mask */
652 0x3ffc00, /* dst_mask */
653 FALSE
), /* pcrel_offset */
655 /* LD/ST8: (S+A) & 0xfff */
656 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC
), /* type */
658 2, /* size (0 = byte, 1 = short, 2 = long) */
660 FALSE
, /* pc_relative */
662 complain_overflow_dont
, /* complain_on_overflow */
663 bfd_elf_generic_reloc
, /* special_function */
664 AARCH64_R_STR (LDST8_ABS_LO12_NC
), /* name */
665 FALSE
, /* partial_inplace */
666 0xfff, /* src_mask */
667 0xfff, /* dst_mask */
668 FALSE
), /* pcrel_offset */
670 /* Relocations for control-flow instructions. */
672 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
673 HOWTO (AARCH64_R (TSTBR14
), /* type */
675 2, /* size (0 = byte, 1 = short, 2 = long) */
677 TRUE
, /* pc_relative */
679 complain_overflow_signed
, /* complain_on_overflow */
680 bfd_elf_generic_reloc
, /* special_function */
681 AARCH64_R_STR (TSTBR14
), /* name */
682 FALSE
, /* partial_inplace */
683 0x3fff, /* src_mask */
684 0x3fff, /* dst_mask */
685 TRUE
), /* pcrel_offset */
687 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
688 HOWTO (AARCH64_R (CONDBR19
), /* type */
690 2, /* size (0 = byte, 1 = short, 2 = long) */
692 TRUE
, /* pc_relative */
694 complain_overflow_signed
, /* complain_on_overflow */
695 bfd_elf_generic_reloc
, /* special_function */
696 AARCH64_R_STR (CONDBR19
), /* name */
697 FALSE
, /* partial_inplace */
698 0x7ffff, /* src_mask */
699 0x7ffff, /* dst_mask */
700 TRUE
), /* pcrel_offset */
702 /* B: ((S+A-P) >> 2) & 0x3ffffff */
703 HOWTO (AARCH64_R (JUMP26
), /* type */
705 2, /* size (0 = byte, 1 = short, 2 = long) */
707 TRUE
, /* pc_relative */
709 complain_overflow_signed
, /* complain_on_overflow */
710 bfd_elf_generic_reloc
, /* special_function */
711 AARCH64_R_STR (JUMP26
), /* name */
712 FALSE
, /* partial_inplace */
713 0x3ffffff, /* src_mask */
714 0x3ffffff, /* dst_mask */
715 TRUE
), /* pcrel_offset */
717 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
718 HOWTO (AARCH64_R (CALL26
), /* type */
720 2, /* size (0 = byte, 1 = short, 2 = long) */
722 TRUE
, /* pc_relative */
724 complain_overflow_signed
, /* complain_on_overflow */
725 bfd_elf_generic_reloc
, /* special_function */
726 AARCH64_R_STR (CALL26
), /* name */
727 FALSE
, /* partial_inplace */
728 0x3ffffff, /* src_mask */
729 0x3ffffff, /* dst_mask */
730 TRUE
), /* pcrel_offset */
732 /* LD/ST16: (S+A) & 0xffe */
733 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC
), /* type */
735 2, /* size (0 = byte, 1 = short, 2 = long) */
737 FALSE
, /* pc_relative */
739 complain_overflow_dont
, /* complain_on_overflow */
740 bfd_elf_generic_reloc
, /* special_function */
741 AARCH64_R_STR (LDST16_ABS_LO12_NC
), /* name */
742 FALSE
, /* partial_inplace */
743 0xffe, /* src_mask */
744 0xffe, /* dst_mask */
745 FALSE
), /* pcrel_offset */
747 /* LD/ST32: (S+A) & 0xffc */
748 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC
), /* type */
750 2, /* size (0 = byte, 1 = short, 2 = long) */
752 FALSE
, /* pc_relative */
754 complain_overflow_dont
, /* complain_on_overflow */
755 bfd_elf_generic_reloc
, /* special_function */
756 AARCH64_R_STR (LDST32_ABS_LO12_NC
), /* name */
757 FALSE
, /* partial_inplace */
758 0xffc, /* src_mask */
759 0xffc, /* dst_mask */
760 FALSE
), /* pcrel_offset */
762 /* LD/ST64: (S+A) & 0xff8 */
763 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC
), /* type */
765 2, /* size (0 = byte, 1 = short, 2 = long) */
767 FALSE
, /* pc_relative */
769 complain_overflow_dont
, /* complain_on_overflow */
770 bfd_elf_generic_reloc
, /* special_function */
771 AARCH64_R_STR (LDST64_ABS_LO12_NC
), /* name */
772 FALSE
, /* partial_inplace */
773 0xff8, /* src_mask */
774 0xff8, /* dst_mask */
775 FALSE
), /* pcrel_offset */
777 /* LD/ST128: (S+A) & 0xff0 */
778 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC
), /* type */
780 2, /* size (0 = byte, 1 = short, 2 = long) */
782 FALSE
, /* pc_relative */
784 complain_overflow_dont
, /* complain_on_overflow */
785 bfd_elf_generic_reloc
, /* special_function */
786 AARCH64_R_STR (LDST128_ABS_LO12_NC
), /* name */
787 FALSE
, /* partial_inplace */
788 0xff0, /* src_mask */
789 0xff0, /* dst_mask */
790 FALSE
), /* pcrel_offset */
792 /* Set a load-literal immediate field to bits
793 0x1FFFFC of G(S)-P */
794 HOWTO (AARCH64_R (GOT_LD_PREL19
), /* type */
796 2, /* size (0 = byte,1 = short,2 = long) */
798 TRUE
, /* pc_relative */
800 complain_overflow_signed
, /* complain_on_overflow */
801 bfd_elf_generic_reloc
, /* special_function */
802 AARCH64_R_STR (GOT_LD_PREL19
), /* name */
803 FALSE
, /* partial_inplace */
804 0xffffe0, /* src_mask */
805 0xffffe0, /* dst_mask */
806 TRUE
), /* pcrel_offset */
808 /* Get to the page for the GOT entry for the symbol
809 (G(S) - P) using an ADRP instruction. */
810 HOWTO (AARCH64_R (ADR_GOT_PAGE
), /* type */
812 2, /* size (0 = byte, 1 = short, 2 = long) */
814 TRUE
, /* pc_relative */
816 complain_overflow_dont
, /* complain_on_overflow */
817 bfd_elf_generic_reloc
, /* special_function */
818 AARCH64_R_STR (ADR_GOT_PAGE
), /* name */
819 FALSE
, /* partial_inplace */
820 0x1fffff, /* src_mask */
821 0x1fffff, /* dst_mask */
822 TRUE
), /* pcrel_offset */
824 /* LD64: GOT offset G(S) & 0xff8 */
825 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC
), /* type */
827 2, /* size (0 = byte, 1 = short, 2 = long) */
829 FALSE
, /* pc_relative */
831 complain_overflow_dont
, /* complain_on_overflow */
832 bfd_elf_generic_reloc
, /* special_function */
833 AARCH64_R_STR (LD64_GOT_LO12_NC
), /* name */
834 FALSE
, /* partial_inplace */
835 0xff8, /* src_mask */
836 0xff8, /* dst_mask */
837 FALSE
), /* pcrel_offset */
839 /* LD32: GOT offset G(S) & 0xffc */
840 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC
), /* type */
842 2, /* size (0 = byte, 1 = short, 2 = long) */
844 FALSE
, /* pc_relative */
846 complain_overflow_dont
, /* complain_on_overflow */
847 bfd_elf_generic_reloc
, /* special_function */
848 AARCH64_R_STR (LD32_GOT_LO12_NC
), /* name */
849 FALSE
, /* partial_inplace */
850 0xffc, /* src_mask */
851 0xffc, /* dst_mask */
852 FALSE
), /* pcrel_offset */
854 /* LD64: GOT offset for the symbol. */
855 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15
), /* type */
857 2, /* size (0 = byte, 1 = short, 2 = long) */
859 FALSE
, /* pc_relative */
861 complain_overflow_unsigned
, /* complain_on_overflow */
862 bfd_elf_generic_reloc
, /* special_function */
863 AARCH64_R_STR (LD64_GOTOFF_LO15
), /* name */
864 FALSE
, /* partial_inplace */
865 0x7ff8, /* src_mask */
866 0x7ff8, /* dst_mask */
867 FALSE
), /* pcrel_offset */
869 /* LD32: GOT offset to the page address of GOT table.
870 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
871 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14
), /* type */
873 2, /* size (0 = byte, 1 = short, 2 = long) */
875 FALSE
, /* pc_relative */
877 complain_overflow_unsigned
, /* complain_on_overflow */
878 bfd_elf_generic_reloc
, /* special_function */
879 AARCH64_R_STR (LD32_GOTPAGE_LO14
), /* name */
880 FALSE
, /* partial_inplace */
881 0x5ffc, /* src_mask */
882 0x5ffc, /* dst_mask */
883 FALSE
), /* pcrel_offset */
885 /* LD64: GOT offset to the page address of GOT table.
886 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
887 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15
), /* type */
889 2, /* size (0 = byte, 1 = short, 2 = long) */
891 FALSE
, /* pc_relative */
893 complain_overflow_unsigned
, /* complain_on_overflow */
894 bfd_elf_generic_reloc
, /* special_function */
895 AARCH64_R_STR (LD64_GOTPAGE_LO15
), /* name */
896 FALSE
, /* partial_inplace */
897 0x7ff8, /* src_mask */
898 0x7ff8, /* dst_mask */
899 FALSE
), /* pcrel_offset */
901 /* Get to the page for the GOT entry for the symbol
902 (G(S) - P) using an ADRP instruction. */
903 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21
), /* type */
905 2, /* size (0 = byte, 1 = short, 2 = long) */
907 TRUE
, /* pc_relative */
909 complain_overflow_dont
, /* complain_on_overflow */
910 bfd_elf_generic_reloc
, /* special_function */
911 AARCH64_R_STR (TLSGD_ADR_PAGE21
), /* name */
912 FALSE
, /* partial_inplace */
913 0x1fffff, /* src_mask */
914 0x1fffff, /* dst_mask */
915 TRUE
), /* pcrel_offset */
917 HOWTO (AARCH64_R (TLSGD_ADR_PREL21
), /* type */
919 2, /* size (0 = byte, 1 = short, 2 = long) */
921 TRUE
, /* pc_relative */
923 complain_overflow_dont
, /* complain_on_overflow */
924 bfd_elf_generic_reloc
, /* special_function */
925 AARCH64_R_STR (TLSGD_ADR_PREL21
), /* name */
926 FALSE
, /* partial_inplace */
927 0x1fffff, /* src_mask */
928 0x1fffff, /* dst_mask */
929 TRUE
), /* pcrel_offset */
931 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
932 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC
), /* type */
934 2, /* size (0 = byte, 1 = short, 2 = long) */
936 FALSE
, /* pc_relative */
938 complain_overflow_dont
, /* complain_on_overflow */
939 bfd_elf_generic_reloc
, /* special_function */
940 AARCH64_R_STR (TLSGD_ADD_LO12_NC
), /* name */
941 FALSE
, /* partial_inplace */
942 0xfff, /* src_mask */
943 0xfff, /* dst_mask */
944 FALSE
), /* pcrel_offset */
946 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1
), /* type */
948 2, /* size (0 = byte, 1 = short, 2 = long) */
950 FALSE
, /* pc_relative */
952 complain_overflow_dont
, /* complain_on_overflow */
953 bfd_elf_generic_reloc
, /* special_function */
954 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1
), /* name */
955 FALSE
, /* partial_inplace */
956 0xffff, /* src_mask */
957 0xffff, /* dst_mask */
958 FALSE
), /* pcrel_offset */
960 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC
), /* type */
962 2, /* size (0 = byte, 1 = short, 2 = long) */
964 FALSE
, /* pc_relative */
966 complain_overflow_dont
, /* complain_on_overflow */
967 bfd_elf_generic_reloc
, /* special_function */
968 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC
), /* name */
969 FALSE
, /* partial_inplace */
970 0xffff, /* src_mask */
971 0xffff, /* dst_mask */
972 FALSE
), /* pcrel_offset */
974 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21
), /* type */
976 2, /* size (0 = byte, 1 = short, 2 = long) */
978 FALSE
, /* pc_relative */
980 complain_overflow_dont
, /* complain_on_overflow */
981 bfd_elf_generic_reloc
, /* special_function */
982 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21
), /* name */
983 FALSE
, /* partial_inplace */
984 0x1fffff, /* src_mask */
985 0x1fffff, /* dst_mask */
986 FALSE
), /* pcrel_offset */
988 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC
), /* type */
990 2, /* size (0 = byte, 1 = short, 2 = long) */
992 FALSE
, /* pc_relative */
994 complain_overflow_dont
, /* complain_on_overflow */
995 bfd_elf_generic_reloc
, /* special_function */
996 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC
), /* name */
997 FALSE
, /* partial_inplace */
998 0xff8, /* src_mask */
999 0xff8, /* dst_mask */
1000 FALSE
), /* pcrel_offset */
1002 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC
), /* type */
1004 2, /* size (0 = byte, 1 = short, 2 = long) */
1006 FALSE
, /* pc_relative */
1008 complain_overflow_dont
, /* complain_on_overflow */
1009 bfd_elf_generic_reloc
, /* special_function */
1010 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC
), /* name */
1011 FALSE
, /* partial_inplace */
1012 0xffc, /* src_mask */
1013 0xffc, /* dst_mask */
1014 FALSE
), /* pcrel_offset */
1016 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19
), /* type */
1018 2, /* size (0 = byte, 1 = short, 2 = long) */
1020 FALSE
, /* pc_relative */
1022 complain_overflow_dont
, /* complain_on_overflow */
1023 bfd_elf_generic_reloc
, /* special_function */
1024 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19
), /* name */
1025 FALSE
, /* partial_inplace */
1026 0x1ffffc, /* src_mask */
1027 0x1ffffc, /* dst_mask */
1028 FALSE
), /* pcrel_offset */
1030 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1031 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC
), /* type */
1033 2, /* size (0 = byte, 1 = short, 2 = long) */
1035 FALSE
, /* pc_relative */
1037 complain_overflow_dont
, /* complain_on_overflow */
1038 bfd_elf_generic_reloc
, /* special_function */
1039 AARCH64_R_STR (TLSLD_ADD_LO12_NC
), /* name */
1040 FALSE
, /* partial_inplace */
1041 0xfff, /* src_mask */
1042 0xfff, /* dst_mask */
1043 FALSE
), /* pcrel_offset */
1045 /* Get to the page for the GOT entry for the symbol
1046 (G(S) - P) using an ADRP instruction. */
1047 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21
), /* type */
1048 12, /* rightshift */
1049 2, /* size (0 = byte, 1 = short, 2 = long) */
1051 TRUE
, /* pc_relative */
1053 complain_overflow_signed
, /* complain_on_overflow */
1054 bfd_elf_generic_reloc
, /* special_function */
1055 AARCH64_R_STR (TLSLD_ADR_PAGE21
), /* name */
1056 FALSE
, /* partial_inplace */
1057 0x1fffff, /* src_mask */
1058 0x1fffff, /* dst_mask */
1059 TRUE
), /* pcrel_offset */
1061 HOWTO (AARCH64_R (TLSLD_ADR_PREL21
), /* type */
1063 2, /* size (0 = byte, 1 = short, 2 = long) */
1065 TRUE
, /* pc_relative */
1067 complain_overflow_signed
, /* complain_on_overflow */
1068 bfd_elf_generic_reloc
, /* special_function */
1069 AARCH64_R_STR (TLSLD_ADR_PREL21
), /* name */
1070 FALSE
, /* partial_inplace */
1071 0x1fffff, /* src_mask */
1072 0x1fffff, /* dst_mask */
1073 TRUE
), /* pcrel_offset */
1075 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2
), /* type */
1076 32, /* rightshift */
1077 2, /* size (0 = byte, 1 = short, 2 = long) */
1079 FALSE
, /* pc_relative */
1081 complain_overflow_unsigned
, /* complain_on_overflow */
1082 bfd_elf_generic_reloc
, /* special_function */
1083 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2
), /* name */
1084 FALSE
, /* partial_inplace */
1085 0xffff, /* src_mask */
1086 0xffff, /* dst_mask */
1087 FALSE
), /* pcrel_offset */
1089 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1
), /* type */
1090 16, /* rightshift */
1091 2, /* size (0 = byte, 1 = short, 2 = long) */
1093 FALSE
, /* pc_relative */
1095 complain_overflow_dont
, /* complain_on_overflow */
1096 bfd_elf_generic_reloc
, /* special_function */
1097 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1
), /* name */
1098 FALSE
, /* partial_inplace */
1099 0xffff, /* src_mask */
1100 0xffff, /* dst_mask */
1101 FALSE
), /* pcrel_offset */
1103 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC
), /* type */
1104 16, /* rightshift */
1105 2, /* size (0 = byte, 1 = short, 2 = long) */
1107 FALSE
, /* pc_relative */
1109 complain_overflow_dont
, /* complain_on_overflow */
1110 bfd_elf_generic_reloc
, /* special_function */
1111 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC
), /* name */
1112 FALSE
, /* partial_inplace */
1113 0xffff, /* src_mask */
1114 0xffff, /* dst_mask */
1115 FALSE
), /* pcrel_offset */
1117 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0
), /* type */
1119 2, /* size (0 = byte, 1 = short, 2 = long) */
1121 FALSE
, /* pc_relative */
1123 complain_overflow_dont
, /* complain_on_overflow */
1124 bfd_elf_generic_reloc
, /* special_function */
1125 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0
), /* name */
1126 FALSE
, /* partial_inplace */
1127 0xffff, /* src_mask */
1128 0xffff, /* dst_mask */
1129 FALSE
), /* pcrel_offset */
1131 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
), /* type */
1133 2, /* size (0 = byte, 1 = short, 2 = long) */
1135 FALSE
, /* pc_relative */
1137 complain_overflow_dont
, /* complain_on_overflow */
1138 bfd_elf_generic_reloc
, /* special_function */
1139 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC
), /* name */
1140 FALSE
, /* partial_inplace */
1141 0xffff, /* src_mask */
1142 0xffff, /* dst_mask */
1143 FALSE
), /* pcrel_offset */
1145 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12
), /* type */
1146 12, /* rightshift */
1147 2, /* size (0 = byte, 1 = short, 2 = long) */
1149 FALSE
, /* pc_relative */
1151 complain_overflow_unsigned
, /* complain_on_overflow */
1152 bfd_elf_generic_reloc
, /* special_function */
1153 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12
), /* name */
1154 FALSE
, /* partial_inplace */
1155 0xfff, /* src_mask */
1156 0xfff, /* dst_mask */
1157 FALSE
), /* pcrel_offset */
1159 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12
), /* type */
1161 2, /* size (0 = byte, 1 = short, 2 = long) */
1163 FALSE
, /* pc_relative */
1165 complain_overflow_unsigned
, /* complain_on_overflow */
1166 bfd_elf_generic_reloc
, /* special_function */
1167 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12
), /* name */
1168 FALSE
, /* partial_inplace */
1169 0xfff, /* src_mask */
1170 0xfff, /* dst_mask */
1171 FALSE
), /* pcrel_offset */
1173 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
), /* type */
1175 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 FALSE
, /* pc_relative */
1179 complain_overflow_dont
, /* complain_on_overflow */
1180 bfd_elf_generic_reloc
, /* special_function */
1181 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC
), /* name */
1182 FALSE
, /* partial_inplace */
1183 0xfff, /* src_mask */
1184 0xfff, /* dst_mask */
1185 FALSE
), /* pcrel_offset */
1187 HOWTO (AARCH64_R (TLSDESC_LD_PREL19
), /* type */
1189 2, /* size (0 = byte, 1 = short, 2 = long) */
1191 TRUE
, /* pc_relative */
1193 complain_overflow_dont
, /* complain_on_overflow */
1194 bfd_elf_generic_reloc
, /* special_function */
1195 AARCH64_R_STR (TLSDESC_LD_PREL19
), /* name */
1196 FALSE
, /* partial_inplace */
1197 0x0ffffe0, /* src_mask */
1198 0x0ffffe0, /* dst_mask */
1199 TRUE
), /* pcrel_offset */
1201 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21
), /* type */
1203 2, /* size (0 = byte, 1 = short, 2 = long) */
1205 TRUE
, /* pc_relative */
1207 complain_overflow_dont
, /* complain_on_overflow */
1208 bfd_elf_generic_reloc
, /* special_function */
1209 AARCH64_R_STR (TLSDESC_ADR_PREL21
), /* name */
1210 FALSE
, /* partial_inplace */
1211 0x1fffff, /* src_mask */
1212 0x1fffff, /* dst_mask */
1213 TRUE
), /* pcrel_offset */
1215 /* Get to the page for the GOT entry for the symbol
1216 (G(S) - P) using an ADRP instruction. */
1217 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21
), /* type */
1218 12, /* rightshift */
1219 2, /* size (0 = byte, 1 = short, 2 = long) */
1221 TRUE
, /* pc_relative */
1223 complain_overflow_dont
, /* complain_on_overflow */
1224 bfd_elf_generic_reloc
, /* special_function */
1225 AARCH64_R_STR (TLSDESC_ADR_PAGE21
), /* name */
1226 FALSE
, /* partial_inplace */
1227 0x1fffff, /* src_mask */
1228 0x1fffff, /* dst_mask */
1229 TRUE
), /* pcrel_offset */
1231 /* LD64: GOT offset G(S) & 0xff8. */
1232 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC
), /* type */
1234 2, /* size (0 = byte, 1 = short, 2 = long) */
1236 FALSE
, /* pc_relative */
1238 complain_overflow_dont
, /* complain_on_overflow */
1239 bfd_elf_generic_reloc
, /* special_function */
1240 AARCH64_R_STR (TLSDESC_LD64_LO12_NC
), /* name */
1241 FALSE
, /* partial_inplace */
1242 0xff8, /* src_mask */
1243 0xff8, /* dst_mask */
1244 FALSE
), /* pcrel_offset */
1246 /* LD32: GOT offset G(S) & 0xffc. */
1247 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC
), /* type */
1249 2, /* size (0 = byte, 1 = short, 2 = long) */
1251 FALSE
, /* pc_relative */
1253 complain_overflow_dont
, /* complain_on_overflow */
1254 bfd_elf_generic_reloc
, /* special_function */
1255 AARCH64_R_STR (TLSDESC_LD32_LO12_NC
), /* name */
1256 FALSE
, /* partial_inplace */
1257 0xffc, /* src_mask */
1258 0xffc, /* dst_mask */
1259 FALSE
), /* pcrel_offset */
1261 /* ADD: GOT offset G(S) & 0xfff. */
1262 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC
), /* type */
1264 2, /* size (0 = byte, 1 = short, 2 = long) */
1266 FALSE
, /* pc_relative */
1268 complain_overflow_dont
, /* complain_on_overflow */
1269 bfd_elf_generic_reloc
, /* special_function */
1270 AARCH64_R_STR (TLSDESC_ADD_LO12_NC
), /* name */
1271 FALSE
, /* partial_inplace */
1272 0xfff, /* src_mask */
1273 0xfff, /* dst_mask */
1274 FALSE
), /* pcrel_offset */
1276 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1
), /* type */
1277 16, /* rightshift */
1278 2, /* size (0 = byte, 1 = short, 2 = long) */
1280 FALSE
, /* pc_relative */
1282 complain_overflow_dont
, /* complain_on_overflow */
1283 bfd_elf_generic_reloc
, /* special_function */
1284 AARCH64_R_STR (TLSDESC_OFF_G1
), /* name */
1285 FALSE
, /* partial_inplace */
1286 0xffff, /* src_mask */
1287 0xffff, /* dst_mask */
1288 FALSE
), /* pcrel_offset */
1290 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC
), /* type */
1292 2, /* size (0 = byte, 1 = short, 2 = long) */
1294 FALSE
, /* pc_relative */
1296 complain_overflow_dont
, /* complain_on_overflow */
1297 bfd_elf_generic_reloc
, /* special_function */
1298 AARCH64_R_STR (TLSDESC_OFF_G0_NC
), /* name */
1299 FALSE
, /* partial_inplace */
1300 0xffff, /* src_mask */
1301 0xffff, /* dst_mask */
1302 FALSE
), /* pcrel_offset */
1304 HOWTO64 (AARCH64_R (TLSDESC_LDR
), /* type */
1306 2, /* size (0 = byte, 1 = short, 2 = long) */
1308 FALSE
, /* pc_relative */
1310 complain_overflow_dont
, /* complain_on_overflow */
1311 bfd_elf_generic_reloc
, /* special_function */
1312 AARCH64_R_STR (TLSDESC_LDR
), /* name */
1313 FALSE
, /* partial_inplace */
1316 FALSE
), /* pcrel_offset */
1318 HOWTO64 (AARCH64_R (TLSDESC_ADD
), /* type */
1320 2, /* size (0 = byte, 1 = short, 2 = long) */
1322 FALSE
, /* pc_relative */
1324 complain_overflow_dont
, /* complain_on_overflow */
1325 bfd_elf_generic_reloc
, /* special_function */
1326 AARCH64_R_STR (TLSDESC_ADD
), /* name */
1327 FALSE
, /* partial_inplace */
1330 FALSE
), /* pcrel_offset */
1332 HOWTO (AARCH64_R (TLSDESC_CALL
), /* type */
1334 2, /* size (0 = byte, 1 = short, 2 = long) */
1336 FALSE
, /* pc_relative */
1338 complain_overflow_dont
, /* complain_on_overflow */
1339 bfd_elf_generic_reloc
, /* special_function */
1340 AARCH64_R_STR (TLSDESC_CALL
), /* name */
1341 FALSE
, /* partial_inplace */
1344 FALSE
), /* pcrel_offset */
1346 HOWTO (AARCH64_R (COPY
), /* type */
1348 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 FALSE
, /* pc_relative */
1352 complain_overflow_bitfield
, /* complain_on_overflow */
1353 bfd_elf_generic_reloc
, /* special_function */
1354 AARCH64_R_STR (COPY
), /* name */
1355 TRUE
, /* partial_inplace */
1356 0xffffffff, /* src_mask */
1357 0xffffffff, /* dst_mask */
1358 FALSE
), /* pcrel_offset */
1360 HOWTO (AARCH64_R (GLOB_DAT
), /* type */
1362 2, /* size (0 = byte, 1 = short, 2 = long) */
1364 FALSE
, /* pc_relative */
1366 complain_overflow_bitfield
, /* complain_on_overflow */
1367 bfd_elf_generic_reloc
, /* special_function */
1368 AARCH64_R_STR (GLOB_DAT
), /* name */
1369 TRUE
, /* partial_inplace */
1370 0xffffffff, /* src_mask */
1371 0xffffffff, /* dst_mask */
1372 FALSE
), /* pcrel_offset */
1374 HOWTO (AARCH64_R (JUMP_SLOT
), /* type */
1376 2, /* size (0 = byte, 1 = short, 2 = long) */
1378 FALSE
, /* pc_relative */
1380 complain_overflow_bitfield
, /* complain_on_overflow */
1381 bfd_elf_generic_reloc
, /* special_function */
1382 AARCH64_R_STR (JUMP_SLOT
), /* name */
1383 TRUE
, /* partial_inplace */
1384 0xffffffff, /* src_mask */
1385 0xffffffff, /* dst_mask */
1386 FALSE
), /* pcrel_offset */
1388 HOWTO (AARCH64_R (RELATIVE
), /* type */
1390 2, /* size (0 = byte, 1 = short, 2 = long) */
1392 FALSE
, /* pc_relative */
1394 complain_overflow_bitfield
, /* complain_on_overflow */
1395 bfd_elf_generic_reloc
, /* special_function */
1396 AARCH64_R_STR (RELATIVE
), /* name */
1397 TRUE
, /* partial_inplace */
1398 ALL_ONES
, /* src_mask */
1399 ALL_ONES
, /* dst_mask */
1400 FALSE
), /* pcrel_offset */
1402 HOWTO (AARCH64_R (TLS_DTPMOD
), /* type */
1404 2, /* size (0 = byte, 1 = short, 2 = long) */
1406 FALSE
, /* pc_relative */
1408 complain_overflow_dont
, /* complain_on_overflow */
1409 bfd_elf_generic_reloc
, /* special_function */
1411 AARCH64_R_STR (TLS_DTPMOD64
), /* name */
1413 AARCH64_R_STR (TLS_DTPMOD
), /* name */
1415 FALSE
, /* partial_inplace */
1417 ALL_ONES
, /* dst_mask */
1418 FALSE
), /* pc_reloffset */
1420 HOWTO (AARCH64_R (TLS_DTPREL
), /* type */
1422 2, /* size (0 = byte, 1 = short, 2 = long) */
1424 FALSE
, /* pc_relative */
1426 complain_overflow_dont
, /* complain_on_overflow */
1427 bfd_elf_generic_reloc
, /* special_function */
1429 AARCH64_R_STR (TLS_DTPREL64
), /* name */
1431 AARCH64_R_STR (TLS_DTPREL
), /* name */
1433 FALSE
, /* partial_inplace */
1435 ALL_ONES
, /* dst_mask */
1436 FALSE
), /* pcrel_offset */
1438 HOWTO (AARCH64_R (TLS_TPREL
), /* type */
1440 2, /* size (0 = byte, 1 = short, 2 = long) */
1442 FALSE
, /* pc_relative */
1444 complain_overflow_dont
, /* complain_on_overflow */
1445 bfd_elf_generic_reloc
, /* special_function */
1447 AARCH64_R_STR (TLS_TPREL64
), /* name */
1449 AARCH64_R_STR (TLS_TPREL
), /* name */
1451 FALSE
, /* partial_inplace */
1453 ALL_ONES
, /* dst_mask */
1454 FALSE
), /* pcrel_offset */
1456 HOWTO (AARCH64_R (TLSDESC
), /* type */
1458 2, /* size (0 = byte, 1 = short, 2 = long) */
1460 FALSE
, /* pc_relative */
1462 complain_overflow_dont
, /* complain_on_overflow */
1463 bfd_elf_generic_reloc
, /* special_function */
1464 AARCH64_R_STR (TLSDESC
), /* name */
1465 FALSE
, /* partial_inplace */
1467 ALL_ONES
, /* dst_mask */
1468 FALSE
), /* pcrel_offset */
1470 HOWTO (AARCH64_R (IRELATIVE
), /* type */
1472 2, /* size (0 = byte, 1 = short, 2 = long) */
1474 FALSE
, /* pc_relative */
1476 complain_overflow_bitfield
, /* complain_on_overflow */
1477 bfd_elf_generic_reloc
, /* special_function */
1478 AARCH64_R_STR (IRELATIVE
), /* name */
1479 FALSE
, /* partial_inplace */
1481 ALL_ONES
, /* dst_mask */
1482 FALSE
), /* pcrel_offset */
1487 static reloc_howto_type elfNN_aarch64_howto_none
=
1488 HOWTO (R_AARCH64_NONE
, /* type */
1490 3, /* size (0 = byte, 1 = short, 2 = long) */
1492 FALSE
, /* pc_relative */
1494 complain_overflow_dont
,/* complain_on_overflow */
1495 bfd_elf_generic_reloc
, /* special_function */
1496 "R_AARCH64_NONE", /* name */
1497 FALSE
, /* partial_inplace */
1500 FALSE
); /* pcrel_offset */
1502 /* Given HOWTO, return the bfd internal relocation enumerator. */
1504 static bfd_reloc_code_real_type
1505 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type
*howto
)
1508 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table
);
1509 const ptrdiff_t offset
1510 = howto
- elfNN_aarch64_howto_table
;
1512 if (offset
> 0 && offset
< size
- 1)
1513 return BFD_RELOC_AARCH64_RELOC_START
+ offset
;
1515 if (howto
== &elfNN_aarch64_howto_none
)
1516 return BFD_RELOC_AARCH64_NONE
;
1518 return BFD_RELOC_AARCH64_RELOC_START
;
1521 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1523 static bfd_reloc_code_real_type
1524 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type
)
1526 static bfd_boolean initialized_p
= FALSE
;
1527 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1528 static unsigned int offsets
[R_AARCH64_end
];
1530 if (initialized_p
== FALSE
)
1534 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1535 if (elfNN_aarch64_howto_table
[i
].type
!= 0)
1536 offsets
[elfNN_aarch64_howto_table
[i
].type
] = i
;
1538 initialized_p
= TRUE
;
1541 if (r_type
== R_AARCH64_NONE
|| r_type
== R_AARCH64_NULL
)
1542 return BFD_RELOC_AARCH64_NONE
;
1544 /* PR 17512: file: b371e70a. */
1545 if (r_type
>= R_AARCH64_end
)
1547 _bfd_error_handler (_("Invalid AArch64 reloc number: %d"), r_type
);
1548 bfd_set_error (bfd_error_bad_value
);
1549 return BFD_RELOC_AARCH64_NONE
;
1552 return BFD_RELOC_AARCH64_RELOC_START
+ offsets
[r_type
];
1555 struct elf_aarch64_reloc_map
1557 bfd_reloc_code_real_type from
;
1558 bfd_reloc_code_real_type to
;
1561 /* Map bfd generic reloc to AArch64-specific reloc. */
1562 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map
[] =
1564 {BFD_RELOC_NONE
, BFD_RELOC_AARCH64_NONE
},
1566 /* Basic data relocations. */
1567 {BFD_RELOC_CTOR
, BFD_RELOC_AARCH64_NN
},
1568 {BFD_RELOC_64
, BFD_RELOC_AARCH64_64
},
1569 {BFD_RELOC_32
, BFD_RELOC_AARCH64_32
},
1570 {BFD_RELOC_16
, BFD_RELOC_AARCH64_16
},
1571 {BFD_RELOC_64_PCREL
, BFD_RELOC_AARCH64_64_PCREL
},
1572 {BFD_RELOC_32_PCREL
, BFD_RELOC_AARCH64_32_PCREL
},
1573 {BFD_RELOC_16_PCREL
, BFD_RELOC_AARCH64_16_PCREL
},
1576 /* Given the bfd internal relocation enumerator in CODE, return the
1577 corresponding howto entry. */
1579 static reloc_howto_type
*
1580 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code
)
1584 /* Convert bfd generic reloc to AArch64-specific reloc. */
1585 if (code
< BFD_RELOC_AARCH64_RELOC_START
1586 || code
> BFD_RELOC_AARCH64_RELOC_END
)
1587 for (i
= 0; i
< ARRAY_SIZE (elf_aarch64_reloc_map
); i
++)
1588 if (elf_aarch64_reloc_map
[i
].from
== code
)
1590 code
= elf_aarch64_reloc_map
[i
].to
;
1594 if (code
> BFD_RELOC_AARCH64_RELOC_START
1595 && code
< BFD_RELOC_AARCH64_RELOC_END
)
1596 if (elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
].type
)
1597 return &elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
];
1599 if (code
== BFD_RELOC_AARCH64_NONE
)
1600 return &elfNN_aarch64_howto_none
;
1605 static reloc_howto_type
*
1606 elfNN_aarch64_howto_from_type (unsigned int r_type
)
1608 bfd_reloc_code_real_type val
;
1609 reloc_howto_type
*howto
;
1614 bfd_set_error (bfd_error_bad_value
);
1619 if (r_type
== R_AARCH64_NONE
)
1620 return &elfNN_aarch64_howto_none
;
1622 val
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
1623 howto
= elfNN_aarch64_howto_from_bfd_reloc (val
);
1628 bfd_set_error (bfd_error_bad_value
);
1633 elfNN_aarch64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*bfd_reloc
,
1634 Elf_Internal_Rela
*elf_reloc
)
1636 unsigned int r_type
;
1638 r_type
= ELFNN_R_TYPE (elf_reloc
->r_info
);
1639 bfd_reloc
->howto
= elfNN_aarch64_howto_from_type (r_type
);
1642 static reloc_howto_type
*
1643 elfNN_aarch64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1644 bfd_reloc_code_real_type code
)
1646 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (code
);
1651 bfd_set_error (bfd_error_bad_value
);
1655 static reloc_howto_type
*
1656 elfNN_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1661 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1662 if (elfNN_aarch64_howto_table
[i
].name
!= NULL
1663 && strcasecmp (elfNN_aarch64_howto_table
[i
].name
, r_name
) == 0)
1664 return &elfNN_aarch64_howto_table
[i
];
1669 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
1670 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1671 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
1672 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1674 /* The linker script knows the section names for placement.
1675 The entry_names are used to do simple name mangling on the stubs.
1676 Given a function name, and its type, the stub can be found. The
1677 name can be changed. The only requirement is the %s be present. */
1678 #define STUB_ENTRY_NAME "__%s_veneer"
1680 /* The name of the dynamic interpreter. This is put in the .interp
1682 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1684 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1685 (((1 << 25) - 1) << 2)
1686 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1689 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1690 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1693 aarch64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
1695 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
1696 return offset
<= AARCH64_MAX_ADRP_IMM
&& offset
>= AARCH64_MIN_ADRP_IMM
;
1700 aarch64_valid_branch_p (bfd_vma value
, bfd_vma place
)
1702 bfd_signed_vma offset
= (bfd_signed_vma
) (value
- place
);
1703 return (offset
<= AARCH64_MAX_FWD_BRANCH_OFFSET
1704 && offset
>= AARCH64_MAX_BWD_BRANCH_OFFSET
);
1707 static const uint32_t aarch64_adrp_branch_stub
[] =
1709 0x90000010, /* adrp ip0, X */
1710 /* R_AARCH64_ADR_HI21_PCREL(X) */
1711 0x91000210, /* add ip0, ip0, :lo12:X */
1712 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
1713 0xd61f0200, /* br ip0 */
1716 static const uint32_t aarch64_long_branch_stub
[] =
1719 0x58000090, /* ldr ip0, 1f */
1721 0x18000090, /* ldr wip0, 1f */
1723 0x10000011, /* adr ip1, #0 */
1724 0x8b110210, /* add ip0, ip0, ip1 */
1725 0xd61f0200, /* br ip0 */
1726 0x00000000, /* 1: .xword or .word
1727 R_AARCH64_PRELNN(X) + 12
1732 static const uint32_t aarch64_erratum_835769_stub
[] =
1734 0x00000000, /* Placeholder for multiply accumulate. */
1735 0x14000000, /* b <label> */
1738 static const uint32_t aarch64_erratum_843419_stub
[] =
1740 0x00000000, /* Placeholder for LDR instruction. */
1741 0x14000000, /* b <label> */
1744 /* Section name for stubs is the associated section name plus this
1746 #define STUB_SUFFIX ".stub"
1748 enum elf_aarch64_stub_type
1751 aarch64_stub_adrp_branch
,
1752 aarch64_stub_long_branch
,
1753 aarch64_stub_erratum_835769_veneer
,
1754 aarch64_stub_erratum_843419_veneer
,
1757 struct elf_aarch64_stub_hash_entry
1759 /* Base hash table entry structure. */
1760 struct bfd_hash_entry root
;
1762 /* The stub section. */
1765 /* Offset within stub_sec of the beginning of this stub. */
1766 bfd_vma stub_offset
;
1768 /* Given the symbol's value and its section we can determine its final
1769 value when building the stubs (so the stub knows where to jump). */
1770 bfd_vma target_value
;
1771 asection
*target_section
;
1773 enum elf_aarch64_stub_type stub_type
;
1775 /* The symbol table entry, if any, that this was derived from. */
1776 struct elf_aarch64_link_hash_entry
*h
;
1778 /* Destination symbol type */
1779 unsigned char st_type
;
1781 /* Where this stub is being called from, or, in the case of combined
1782 stub sections, the first input section in the group. */
1785 /* The name for the local symbol at the start of this stub. The
1786 stub name in the hash table has to be unique; this does not, so
1787 it can be friendlier. */
1790 /* The instruction which caused this stub to be generated (only valid for
1791 erratum 835769 workaround stubs at present). */
1792 uint32_t veneered_insn
;
1794 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
1795 bfd_vma adrp_offset
;
1798 /* Used to build a map of a section. This is required for mixed-endian
1801 typedef struct elf_elf_section_map
1806 elf_aarch64_section_map
;
1809 typedef struct _aarch64_elf_section_data
1811 struct bfd_elf_section_data elf
;
1812 unsigned int mapcount
;
1813 unsigned int mapsize
;
1814 elf_aarch64_section_map
*map
;
1816 _aarch64_elf_section_data
;
1818 #define elf_aarch64_section_data(sec) \
1819 ((_aarch64_elf_section_data *) elf_section_data (sec))
1821 /* The size of the thread control block which is defined to be two pointers. */
1822 #define TCB_SIZE (ARCH_SIZE/8)*2
1824 struct elf_aarch64_local_symbol
1826 unsigned int got_type
;
1827 bfd_signed_vma got_refcount
;
1830 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
1831 offset is from the end of the jump table and reserved entries
1834 The magic value (bfd_vma) -1 indicates that an offset has not be
1836 bfd_vma tlsdesc_got_jump_table_offset
;
1839 struct elf_aarch64_obj_tdata
1841 struct elf_obj_tdata root
;
1843 /* local symbol descriptors */
1844 struct elf_aarch64_local_symbol
*locals
;
1846 /* Zero to warn when linking objects with incompatible enum sizes. */
1847 int no_enum_size_warning
;
1849 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
1850 int no_wchar_size_warning
;
1853 #define elf_aarch64_tdata(bfd) \
1854 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
1856 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
1858 #define is_aarch64_elf(bfd) \
1859 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
1860 && elf_tdata (bfd) != NULL \
1861 && elf_object_id (bfd) == AARCH64_ELF_DATA)
1864 elfNN_aarch64_mkobject (bfd
*abfd
)
1866 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
),
1870 #define elf_aarch64_hash_entry(ent) \
1871 ((struct elf_aarch64_link_hash_entry *)(ent))
1873 #define GOT_UNKNOWN 0
1874 #define GOT_NORMAL 1
1875 #define GOT_TLS_GD 2
1876 #define GOT_TLS_IE 4
1877 #define GOT_TLSDESC_GD 8
1879 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
1881 /* AArch64 ELF linker hash entry. */
1882 struct elf_aarch64_link_hash_entry
1884 struct elf_link_hash_entry root
;
1886 /* Track dynamic relocs copied for this symbol. */
1887 struct elf_dyn_relocs
*dyn_relocs
;
1889 /* Since PLT entries have variable size, we need to record the
1890 index into .got.plt instead of recomputing it from the PLT
1892 bfd_signed_vma plt_got_offset
;
1894 /* Bit mask representing the type of GOT entry(s) if any required by
1896 unsigned int got_type
;
1898 /* A pointer to the most recently used stub hash entry against this
1900 struct elf_aarch64_stub_hash_entry
*stub_cache
;
1902 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
1903 is from the end of the jump table and reserved entries within the PLTGOT.
1905 The magic value (bfd_vma) -1 indicates that an offset has not
1907 bfd_vma tlsdesc_got_jump_table_offset
;
1911 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
1913 unsigned long r_symndx
)
1916 return elf_aarch64_hash_entry (h
)->got_type
;
1918 if (! elf_aarch64_locals (abfd
))
1921 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
1924 /* Get the AArch64 elf linker hash table from a link_info structure. */
1925 #define elf_aarch64_hash_table(info) \
1926 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
1928 #define aarch64_stub_hash_lookup(table, string, create, copy) \
1929 ((struct elf_aarch64_stub_hash_entry *) \
1930 bfd_hash_lookup ((table), (string), (create), (copy)))
1932 /* AArch64 ELF linker hash table. */
1933 struct elf_aarch64_link_hash_table
1935 /* The main hash table. */
1936 struct elf_link_hash_table root
;
1938 /* Nonzero to force PIC branch veneers. */
1941 /* Fix erratum 835769. */
1942 int fix_erratum_835769
;
1944 /* Fix erratum 843419. */
1945 int fix_erratum_843419
;
1947 /* Enable ADRP->ADR rewrite for erratum 843419 workaround. */
1948 int fix_erratum_843419_adr
;
1950 /* The number of bytes in the initial entry in the PLT. */
1951 bfd_size_type plt_header_size
;
1953 /* The number of bytes in the subsequent PLT etries. */
1954 bfd_size_type plt_entry_size
;
1956 /* Short-cuts to get to dynamic linker sections. */
1960 /* Small local sym cache. */
1961 struct sym_cache sym_cache
;
1963 /* For convenience in allocate_dynrelocs. */
1966 /* The amount of space used by the reserved portion of the sgotplt
1967 section, plus whatever space is used by the jump slots. */
1968 bfd_vma sgotplt_jump_table_size
;
1970 /* The stub hash table. */
1971 struct bfd_hash_table stub_hash_table
;
1973 /* Linker stub bfd. */
1976 /* Linker call-backs. */
1977 asection
*(*add_stub_section
) (const char *, asection
*);
1978 void (*layout_sections_again
) (void);
1980 /* Array to keep track of which stub sections have been created, and
1981 information on stub grouping. */
1984 /* This is the section to which stubs in the group will be
1987 /* The stub section. */
1991 /* Assorted information used by elfNN_aarch64_size_stubs. */
1992 unsigned int bfd_count
;
1994 asection
**input_list
;
1996 /* The offset into splt of the PLT entry for the TLS descriptor
1997 resolver. Special values are 0, if not necessary (or not found
1998 to be necessary yet), and -1 if needed but not determined
2000 bfd_vma tlsdesc_plt
;
2002 /* The GOT offset for the lazy trampoline. Communicated to the
2003 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
2004 indicates an offset is not allocated. */
2005 bfd_vma dt_tlsdesc_got
;
2007 /* Used by local STT_GNU_IFUNC symbols. */
2008 htab_t loc_hash_table
;
2009 void * loc_hash_memory
;
2012 /* Create an entry in an AArch64 ELF linker hash table. */
2014 static struct bfd_hash_entry
*
2015 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
2016 struct bfd_hash_table
*table
,
2019 struct elf_aarch64_link_hash_entry
*ret
=
2020 (struct elf_aarch64_link_hash_entry
*) entry
;
2022 /* Allocate the structure if it has not already been allocated by a
2025 ret
= bfd_hash_allocate (table
,
2026 sizeof (struct elf_aarch64_link_hash_entry
));
2028 return (struct bfd_hash_entry
*) ret
;
2030 /* Call the allocation method of the superclass. */
2031 ret
= ((struct elf_aarch64_link_hash_entry
*)
2032 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
2036 ret
->dyn_relocs
= NULL
;
2037 ret
->got_type
= GOT_UNKNOWN
;
2038 ret
->plt_got_offset
= (bfd_vma
) - 1;
2039 ret
->stub_cache
= NULL
;
2040 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
2043 return (struct bfd_hash_entry
*) ret
;
2046 /* Initialize an entry in the stub hash table. */
2048 static struct bfd_hash_entry
*
2049 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
2050 struct bfd_hash_table
*table
, const char *string
)
2052 /* Allocate the structure if it has not already been allocated by a
2056 entry
= bfd_hash_allocate (table
,
2058 elf_aarch64_stub_hash_entry
));
2063 /* Call the allocation method of the superclass. */
2064 entry
= bfd_hash_newfunc (entry
, table
, string
);
2067 struct elf_aarch64_stub_hash_entry
*eh
;
2069 /* Initialize the local fields. */
2070 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
2071 eh
->adrp_offset
= 0;
2072 eh
->stub_sec
= NULL
;
2073 eh
->stub_offset
= 0;
2074 eh
->target_value
= 0;
2075 eh
->target_section
= NULL
;
2076 eh
->stub_type
= aarch64_stub_none
;
2084 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
2085 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2086 as global symbol. We reuse indx and dynstr_index for local symbol
2087 hash since they aren't used by global symbols in this backend. */
2090 elfNN_aarch64_local_htab_hash (const void *ptr
)
2092 struct elf_link_hash_entry
*h
2093 = (struct elf_link_hash_entry
*) ptr
;
2094 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
2097 /* Compare local hash entries. */
2100 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
2102 struct elf_link_hash_entry
*h1
2103 = (struct elf_link_hash_entry
*) ptr1
;
2104 struct elf_link_hash_entry
*h2
2105 = (struct elf_link_hash_entry
*) ptr2
;
2107 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
2110 /* Find and/or create a hash entry for local symbol. */
2112 static struct elf_link_hash_entry
*
2113 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
2114 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2117 struct elf_aarch64_link_hash_entry e
, *ret
;
2118 asection
*sec
= abfd
->sections
;
2119 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
2120 ELFNN_R_SYM (rel
->r_info
));
2123 e
.root
.indx
= sec
->id
;
2124 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2125 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
2126 create
? INSERT
: NO_INSERT
);
2133 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
2137 ret
= (struct elf_aarch64_link_hash_entry
*)
2138 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
2139 sizeof (struct elf_aarch64_link_hash_entry
));
2142 memset (ret
, 0, sizeof (*ret
));
2143 ret
->root
.indx
= sec
->id
;
2144 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2145 ret
->root
.dynindx
= -1;
2151 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2154 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
2155 struct elf_link_hash_entry
*dir
,
2156 struct elf_link_hash_entry
*ind
)
2158 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
2160 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
2161 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
2163 if (eind
->dyn_relocs
!= NULL
)
2165 if (edir
->dyn_relocs
!= NULL
)
2167 struct elf_dyn_relocs
**pp
;
2168 struct elf_dyn_relocs
*p
;
2170 /* Add reloc counts against the indirect sym to the direct sym
2171 list. Merge any entries against the same section. */
2172 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
2174 struct elf_dyn_relocs
*q
;
2176 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
2177 if (q
->sec
== p
->sec
)
2179 q
->pc_count
+= p
->pc_count
;
2180 q
->count
+= p
->count
;
2187 *pp
= edir
->dyn_relocs
;
2190 edir
->dyn_relocs
= eind
->dyn_relocs
;
2191 eind
->dyn_relocs
= NULL
;
2194 if (ind
->root
.type
== bfd_link_hash_indirect
)
2196 /* Copy over PLT info. */
2197 if (dir
->got
.refcount
<= 0)
2199 edir
->got_type
= eind
->got_type
;
2200 eind
->got_type
= GOT_UNKNOWN
;
2204 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2207 /* Destroy an AArch64 elf linker hash table. */
2210 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
2212 struct elf_aarch64_link_hash_table
*ret
2213 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
2215 if (ret
->loc_hash_table
)
2216 htab_delete (ret
->loc_hash_table
);
2217 if (ret
->loc_hash_memory
)
2218 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
2220 bfd_hash_table_free (&ret
->stub_hash_table
);
2221 _bfd_elf_link_hash_table_free (obfd
);
2224 /* Create an AArch64 elf linker hash table. */
2226 static struct bfd_link_hash_table
*
2227 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
2229 struct elf_aarch64_link_hash_table
*ret
;
2230 bfd_size_type amt
= sizeof (struct elf_aarch64_link_hash_table
);
2232 ret
= bfd_zmalloc (amt
);
2236 if (!_bfd_elf_link_hash_table_init
2237 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
2238 sizeof (struct elf_aarch64_link_hash_entry
), AARCH64_ELF_DATA
))
2244 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
2245 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
2247 ret
->dt_tlsdesc_got
= (bfd_vma
) - 1;
2249 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
2250 sizeof (struct elf_aarch64_stub_hash_entry
)))
2252 _bfd_elf_link_hash_table_free (abfd
);
2256 ret
->loc_hash_table
= htab_try_create (1024,
2257 elfNN_aarch64_local_htab_hash
,
2258 elfNN_aarch64_local_htab_eq
,
2260 ret
->loc_hash_memory
= objalloc_create ();
2261 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
2263 elfNN_aarch64_link_hash_table_free (abfd
);
2266 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
2268 return &ret
->root
.root
;
2272 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
2273 bfd_vma offset
, bfd_vma value
)
2275 reloc_howto_type
*howto
;
2278 howto
= elfNN_aarch64_howto_from_type (r_type
);
2279 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
2282 r_type
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
2283 value
= _bfd_aarch64_elf_resolve_relocation (r_type
, place
, value
, 0, FALSE
);
2284 return _bfd_aarch64_elf_put_addend (input_bfd
,
2285 input_section
->contents
+ offset
, r_type
,
2289 static enum elf_aarch64_stub_type
2290 aarch64_select_branch_stub (bfd_vma value
, bfd_vma place
)
2292 if (aarch64_valid_for_adrp_p (value
, place
))
2293 return aarch64_stub_adrp_branch
;
2294 return aarch64_stub_long_branch
;
2297 /* Determine the type of stub needed, if any, for a call. */
2299 static enum elf_aarch64_stub_type
2300 aarch64_type_of_stub (struct bfd_link_info
*info
,
2301 asection
*input_sec
,
2302 const Elf_Internal_Rela
*rel
,
2303 unsigned char st_type
,
2304 struct elf_aarch64_link_hash_entry
*hash
,
2305 bfd_vma destination
)
2308 bfd_signed_vma branch_offset
;
2309 unsigned int r_type
;
2310 struct elf_aarch64_link_hash_table
*globals
;
2311 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
2312 bfd_boolean via_plt_p
;
2314 if (st_type
!= STT_FUNC
)
2317 globals
= elf_aarch64_hash_table (info
);
2318 via_plt_p
= (globals
->root
.splt
!= NULL
&& hash
!= NULL
2319 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1);
2324 /* Determine where the call point is. */
2325 location
= (input_sec
->output_offset
2326 + input_sec
->output_section
->vma
+ rel
->r_offset
);
2328 branch_offset
= (bfd_signed_vma
) (destination
- location
);
2330 r_type
= ELFNN_R_TYPE (rel
->r_info
);
2332 /* We don't want to redirect any old unconditional jump in this way,
2333 only one which is being used for a sibcall, where it is
2334 acceptable for the IP0 and IP1 registers to be clobbered. */
2335 if ((r_type
== AARCH64_R (CALL26
) || r_type
== AARCH64_R (JUMP26
))
2336 && (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
2337 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
))
2339 stub_type
= aarch64_stub_long_branch
;
2345 /* Build a name for an entry in the stub hash table. */
2348 elfNN_aarch64_stub_name (const asection
*input_section
,
2349 const asection
*sym_sec
,
2350 const struct elf_aarch64_link_hash_entry
*hash
,
2351 const Elf_Internal_Rela
*rel
)
2358 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
2359 stub_name
= bfd_malloc (len
);
2360 if (stub_name
!= NULL
)
2361 snprintf (stub_name
, len
, "%08x_%s+%" BFD_VMA_FMT
"x",
2362 (unsigned int) input_section
->id
,
2363 hash
->root
.root
.root
.string
,
2368 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2369 stub_name
= bfd_malloc (len
);
2370 if (stub_name
!= NULL
)
2371 snprintf (stub_name
, len
, "%08x_%x:%x+%" BFD_VMA_FMT
"x",
2372 (unsigned int) input_section
->id
,
2373 (unsigned int) sym_sec
->id
,
2374 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
2381 /* Look up an entry in the stub hash. Stub entries are cached because
2382 creating the stub name takes a bit of time. */
2384 static struct elf_aarch64_stub_hash_entry
*
2385 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
2386 const asection
*sym_sec
,
2387 struct elf_link_hash_entry
*hash
,
2388 const Elf_Internal_Rela
*rel
,
2389 struct elf_aarch64_link_hash_table
*htab
)
2391 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2392 struct elf_aarch64_link_hash_entry
*h
=
2393 (struct elf_aarch64_link_hash_entry
*) hash
;
2394 const asection
*id_sec
;
2396 if ((input_section
->flags
& SEC_CODE
) == 0)
2399 /* If this input section is part of a group of sections sharing one
2400 stub section, then use the id of the first section in the group.
2401 Stub names need to include a section id, as there may well be
2402 more than one stub used to reach say, printf, and we need to
2403 distinguish between them. */
2404 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
2406 if (h
!= NULL
&& h
->stub_cache
!= NULL
2407 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
2409 stub_entry
= h
->stub_cache
;
2415 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
);
2416 if (stub_name
== NULL
)
2419 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
2420 stub_name
, FALSE
, FALSE
);
2422 h
->stub_cache
= stub_entry
;
2431 /* Create a stub section. */
2434 _bfd_aarch64_create_stub_section (asection
*section
,
2435 struct elf_aarch64_link_hash_table
*htab
)
2441 namelen
= strlen (section
->name
);
2442 len
= namelen
+ sizeof (STUB_SUFFIX
);
2443 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
2447 memcpy (s_name
, section
->name
, namelen
);
2448 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
2449 return (*htab
->add_stub_section
) (s_name
, section
);
2453 /* Find or create a stub section for a link section.
2455 Fix or create the stub section used to collect stubs attached to
2456 the specified link section. */
2459 _bfd_aarch64_get_stub_for_link_section (asection
*link_section
,
2460 struct elf_aarch64_link_hash_table
*htab
)
2462 if (htab
->stub_group
[link_section
->id
].stub_sec
== NULL
)
2463 htab
->stub_group
[link_section
->id
].stub_sec
2464 = _bfd_aarch64_create_stub_section (link_section
, htab
);
2465 return htab
->stub_group
[link_section
->id
].stub_sec
;
2469 /* Find or create a stub section in the stub group for an input
2473 _bfd_aarch64_create_or_find_stub_sec (asection
*section
,
2474 struct elf_aarch64_link_hash_table
*htab
)
2476 asection
*link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2477 return _bfd_aarch64_get_stub_for_link_section (link_sec
, htab
);
2481 /* Add a new stub entry in the stub group associated with an input
2482 section to the stub hash. Not all fields of the new stub entry are
2485 static struct elf_aarch64_stub_hash_entry
*
2486 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name
,
2488 struct elf_aarch64_link_hash_table
*htab
)
2492 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2494 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2495 stub_sec
= _bfd_aarch64_create_or_find_stub_sec (section
, htab
);
2497 /* Enter this entry into the linker stub hash table. */
2498 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2500 if (stub_entry
== NULL
)
2502 (*_bfd_error_handler
) (_("%s: cannot create stub entry %s"),
2503 section
->owner
, stub_name
);
2507 stub_entry
->stub_sec
= stub_sec
;
2508 stub_entry
->stub_offset
= 0;
2509 stub_entry
->id_sec
= link_sec
;
2514 /* Add a new stub entry in the final stub section to the stub hash.
2515 Not all fields of the new stub entry are initialised. */
2517 static struct elf_aarch64_stub_hash_entry
*
2518 _bfd_aarch64_add_stub_entry_after (const char *stub_name
,
2519 asection
*link_section
,
2520 struct elf_aarch64_link_hash_table
*htab
)
2523 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2525 stub_sec
= _bfd_aarch64_get_stub_for_link_section (link_section
, htab
);
2526 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2528 if (stub_entry
== NULL
)
2530 (*_bfd_error_handler
) (_("cannot create stub entry %s"), stub_name
);
2534 stub_entry
->stub_sec
= stub_sec
;
2535 stub_entry
->stub_offset
= 0;
2536 stub_entry
->id_sec
= link_section
;
2543 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
2544 void *in_arg ATTRIBUTE_UNUSED
)
2546 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2551 bfd_vma veneered_insn_loc
;
2552 bfd_vma veneer_entry_loc
;
2553 bfd_signed_vma branch_offset
= 0;
2554 unsigned int template_size
;
2555 const uint32_t *template;
2558 /* Massage our args to the form they really have. */
2559 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2561 stub_sec
= stub_entry
->stub_sec
;
2563 /* Make a note of the offset within the stubs for this entry. */
2564 stub_entry
->stub_offset
= stub_sec
->size
;
2565 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
2567 stub_bfd
= stub_sec
->owner
;
2569 /* This is the address of the stub destination. */
2570 sym_value
= (stub_entry
->target_value
2571 + stub_entry
->target_section
->output_offset
2572 + stub_entry
->target_section
->output_section
->vma
);
2574 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
2576 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
2577 + stub_sec
->output_offset
);
2579 /* See if we can relax the stub. */
2580 if (aarch64_valid_for_adrp_p (sym_value
, place
))
2581 stub_entry
->stub_type
= aarch64_select_branch_stub (sym_value
, place
);
2584 switch (stub_entry
->stub_type
)
2586 case aarch64_stub_adrp_branch
:
2587 template = aarch64_adrp_branch_stub
;
2588 template_size
= sizeof (aarch64_adrp_branch_stub
);
2590 case aarch64_stub_long_branch
:
2591 template = aarch64_long_branch_stub
;
2592 template_size
= sizeof (aarch64_long_branch_stub
);
2594 case aarch64_stub_erratum_835769_veneer
:
2595 template = aarch64_erratum_835769_stub
;
2596 template_size
= sizeof (aarch64_erratum_835769_stub
);
2598 case aarch64_stub_erratum_843419_veneer
:
2599 template = aarch64_erratum_843419_stub
;
2600 template_size
= sizeof (aarch64_erratum_843419_stub
);
2606 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
2608 bfd_putl32 (template[i
], loc
);
2612 template_size
= (template_size
+ 7) & ~7;
2613 stub_sec
->size
+= template_size
;
2615 switch (stub_entry
->stub_type
)
2617 case aarch64_stub_adrp_branch
:
2618 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
2619 stub_entry
->stub_offset
, sym_value
))
2620 /* The stub would not have been relaxed if the offset was out
2624 if (aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
2625 stub_entry
->stub_offset
+ 4, sym_value
))
2629 case aarch64_stub_long_branch
:
2630 /* We want the value relative to the address 12 bytes back from the
2632 if (aarch64_relocate (AARCH64_R (PRELNN
), stub_bfd
, stub_sec
,
2633 stub_entry
->stub_offset
+ 16, sym_value
+ 12))
2637 case aarch64_stub_erratum_835769_veneer
:
2638 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
2639 + stub_entry
->target_section
->output_offset
2640 + stub_entry
->target_value
;
2641 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
2642 + stub_entry
->stub_sec
->output_offset
2643 + stub_entry
->stub_offset
;
2644 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
2645 branch_offset
>>= 2;
2646 branch_offset
&= 0x3ffffff;
2647 bfd_putl32 (stub_entry
->veneered_insn
,
2648 stub_sec
->contents
+ stub_entry
->stub_offset
);
2649 bfd_putl32 (template[1] | branch_offset
,
2650 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
2653 case aarch64_stub_erratum_843419_veneer
:
2654 if (aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
2655 stub_entry
->stub_offset
+ 4, sym_value
+ 4))
2666 /* As above, but don't actually build the stub. Just bump offset so
2667 we know stub section sizes. */
2670 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
,
2671 void *in_arg ATTRIBUTE_UNUSED
)
2673 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2676 /* Massage our args to the form they really have. */
2677 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2679 switch (stub_entry
->stub_type
)
2681 case aarch64_stub_adrp_branch
:
2682 size
= sizeof (aarch64_adrp_branch_stub
);
2684 case aarch64_stub_long_branch
:
2685 size
= sizeof (aarch64_long_branch_stub
);
2687 case aarch64_stub_erratum_835769_veneer
:
2688 size
= sizeof (aarch64_erratum_835769_stub
);
2690 case aarch64_stub_erratum_843419_veneer
:
2691 size
= sizeof (aarch64_erratum_843419_stub
);
2697 size
= (size
+ 7) & ~7;
2698 stub_entry
->stub_sec
->size
+= size
;
2702 /* External entry points for sizing and building linker stubs. */
2704 /* Set up various things so that we can make a list of input sections
2705 for each output section included in the link. Returns -1 on error,
2706 0 when no stubs will be needed, and 1 on success. */
2709 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
2710 struct bfd_link_info
*info
)
2713 unsigned int bfd_count
;
2714 int top_id
, top_index
;
2716 asection
**input_list
, **list
;
2718 struct elf_aarch64_link_hash_table
*htab
=
2719 elf_aarch64_hash_table (info
);
2721 if (!is_elf_hash_table (htab
))
2724 /* Count the number of input BFDs and find the top input section id. */
2725 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
2726 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
2729 for (section
= input_bfd
->sections
;
2730 section
!= NULL
; section
= section
->next
)
2732 if (top_id
< section
->id
)
2733 top_id
= section
->id
;
2736 htab
->bfd_count
= bfd_count
;
2738 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
2739 htab
->stub_group
= bfd_zmalloc (amt
);
2740 if (htab
->stub_group
== NULL
)
2743 /* We can't use output_bfd->section_count here to find the top output
2744 section index as some sections may have been removed, and
2745 _bfd_strip_section_from_output doesn't renumber the indices. */
2746 for (section
= output_bfd
->sections
, top_index
= 0;
2747 section
!= NULL
; section
= section
->next
)
2749 if (top_index
< section
->index
)
2750 top_index
= section
->index
;
2753 htab
->top_index
= top_index
;
2754 amt
= sizeof (asection
*) * (top_index
+ 1);
2755 input_list
= bfd_malloc (amt
);
2756 htab
->input_list
= input_list
;
2757 if (input_list
== NULL
)
2760 /* For sections we aren't interested in, mark their entries with a
2761 value we can check later. */
2762 list
= input_list
+ top_index
;
2764 *list
= bfd_abs_section_ptr
;
2765 while (list
-- != input_list
);
2767 for (section
= output_bfd
->sections
;
2768 section
!= NULL
; section
= section
->next
)
2770 if ((section
->flags
& SEC_CODE
) != 0)
2771 input_list
[section
->index
] = NULL
;
2777 /* Used by elfNN_aarch64_next_input_section and group_sections. */
2778 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
2780 /* The linker repeatedly calls this function for each input section,
2781 in the order that input sections are linked into output sections.
2782 Build lists of input sections to determine groupings between which
2783 we may insert linker stubs. */
2786 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
2788 struct elf_aarch64_link_hash_table
*htab
=
2789 elf_aarch64_hash_table (info
);
2791 if (isec
->output_section
->index
<= htab
->top_index
)
2793 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
2795 if (*list
!= bfd_abs_section_ptr
)
2797 /* Steal the link_sec pointer for our list. */
2798 /* This happens to make the list in reverse order,
2799 which is what we want. */
2800 PREV_SEC (isec
) = *list
;
2806 /* See whether we can group stub sections together. Grouping stub
2807 sections may result in fewer stubs. More importantly, we need to
2808 put all .init* and .fini* stubs at the beginning of the .init or
2809 .fini output sections respectively, because glibc splits the
2810 _init and _fini functions into multiple parts. Putting a stub in
2811 the middle of a function is not a good idea. */
2814 group_sections (struct elf_aarch64_link_hash_table
*htab
,
2815 bfd_size_type stub_group_size
,
2816 bfd_boolean stubs_always_before_branch
)
2818 asection
**list
= htab
->input_list
+ htab
->top_index
;
2822 asection
*tail
= *list
;
2824 if (tail
== bfd_abs_section_ptr
)
2827 while (tail
!= NULL
)
2831 bfd_size_type total
;
2835 while ((prev
= PREV_SEC (curr
)) != NULL
2836 && ((total
+= curr
->output_offset
- prev
->output_offset
)
2840 /* OK, the size from the start of CURR to the end is less
2841 than stub_group_size and thus can be handled by one stub
2842 section. (Or the tail section is itself larger than
2843 stub_group_size, in which case we may be toast.)
2844 We should really be keeping track of the total size of
2845 stubs added here, as stubs contribute to the final output
2849 prev
= PREV_SEC (tail
);
2850 /* Set up this stub group. */
2851 htab
->stub_group
[tail
->id
].link_sec
= curr
;
2853 while (tail
!= curr
&& (tail
= prev
) != NULL
);
2855 /* But wait, there's more! Input sections up to stub_group_size
2856 bytes before the stub section can be handled by it too. */
2857 if (!stubs_always_before_branch
)
2861 && ((total
+= tail
->output_offset
- prev
->output_offset
)
2865 prev
= PREV_SEC (tail
);
2866 htab
->stub_group
[tail
->id
].link_sec
= curr
;
2872 while (list
-- != htab
->input_list
);
2874 free (htab
->input_list
);
2879 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
2881 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
2882 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
2883 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
2884 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
2885 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
2886 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
2888 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
2889 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
2890 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
2891 #define AARCH64_ZR 0x1f
2893 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
2894 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
2896 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
2897 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
2898 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
2899 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
2900 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
2901 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
2902 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
2903 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
2904 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
2905 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
2906 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
2907 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
2908 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
2909 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
2910 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
2911 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
2912 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
2913 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
2915 /* Classify an INSN if it is indeed a load/store.
2917 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
2919 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
2922 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned.
2927 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rt2
,
2928 bfd_boolean
*pair
, bfd_boolean
*load
)
2936 /* Bail out quickly if INSN doesn't fall into the the load-store
2938 if (!AARCH64_LDST (insn
))
2943 if (AARCH64_LDST_EX (insn
))
2945 *rt
= AARCH64_RT (insn
);
2947 if (AARCH64_BIT (insn
, 21) == 1)
2950 *rt2
= AARCH64_RT2 (insn
);
2952 *load
= AARCH64_LD (insn
);
2955 else if (AARCH64_LDST_NAP (insn
)
2956 || AARCH64_LDSTP_PI (insn
)
2957 || AARCH64_LDSTP_O (insn
)
2958 || AARCH64_LDSTP_PRE (insn
))
2961 *rt
= AARCH64_RT (insn
);
2962 *rt2
= AARCH64_RT2 (insn
);
2963 *load
= AARCH64_LD (insn
);
2966 else if (AARCH64_LDST_PCREL (insn
)
2967 || AARCH64_LDST_UI (insn
)
2968 || AARCH64_LDST_PIIMM (insn
)
2969 || AARCH64_LDST_U (insn
)
2970 || AARCH64_LDST_PREIMM (insn
)
2971 || AARCH64_LDST_RO (insn
)
2972 || AARCH64_LDST_UIMM (insn
))
2974 *rt
= AARCH64_RT (insn
);
2976 if (AARCH64_LDST_PCREL (insn
))
2978 opc
= AARCH64_BITS (insn
, 22, 2);
2979 v
= AARCH64_BIT (insn
, 26);
2980 opc_v
= opc
| (v
<< 2);
2981 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
2982 || opc_v
== 5 || opc_v
== 7);
2985 else if (AARCH64_LDST_SIMD_M (insn
)
2986 || AARCH64_LDST_SIMD_M_PI (insn
))
2988 *rt
= AARCH64_RT (insn
);
2989 *load
= AARCH64_BIT (insn
, 22);
2990 opcode
= (insn
>> 12) & 0xf;
3017 else if (AARCH64_LDST_SIMD_S (insn
)
3018 || AARCH64_LDST_SIMD_S_PI (insn
))
3020 *rt
= AARCH64_RT (insn
);
3021 r
= (insn
>> 21) & 1;
3022 *load
= AARCH64_BIT (insn
, 22);
3023 opcode
= (insn
>> 13) & 0x7;
3035 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3043 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3055 /* Return TRUE if INSN is multiply-accumulate. */
3058 aarch64_mlxl_p (uint32_t insn
)
3060 uint32_t op31
= AARCH64_OP31 (insn
);
3062 if (AARCH64_MAC (insn
)
3063 && (op31
== 0 || op31
== 1 || op31
== 5)
3064 /* Exclude MUL instructions which are encoded as a multiple accumulate
3066 && AARCH64_RA (insn
) != AARCH64_ZR
)
3072 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3073 it is possible for a 64-bit multiply-accumulate instruction to generate an
3074 incorrect result. The details are quite complex and hard to
3075 determine statically, since branches in the code may exist in some
3076 circumstances, but all cases end with a memory (load, store, or
3077 prefetch) instruction followed immediately by the multiply-accumulate
3078 operation. We employ a linker patching technique, by moving the potentially
3079 affected multiply-accumulate instruction into a patch region and replacing
3080 the original instruction with a branch to the patch. This function checks
3081 if INSN_1 is the memory operation followed by a multiply-accumulate
3082 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3083 if INSN_1 and INSN_2 are safe. */
3086 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
3096 if (aarch64_mlxl_p (insn_2
)
3097 && aarch64_mem_op_p (insn_1
, &rt
, &rt2
, &pair
, &load
))
3099 /* Any SIMD memory op is independent of the subsequent MLA
3100 by definition of the erratum. */
3101 if (AARCH64_BIT (insn_1
, 26))
3104 /* If not SIMD, check for integer memory ops and MLA relationship. */
3105 rn
= AARCH64_RN (insn_2
);
3106 ra
= AARCH64_RA (insn_2
);
3107 rm
= AARCH64_RM (insn_2
);
3109 /* If this is a load and there's a true(RAW) dependency, we are safe
3110 and this is not an erratum sequence. */
3112 (rt
== rn
|| rt
== rm
|| rt
== ra
3113 || (pair
&& (rt2
== rn
|| rt2
== rm
|| rt2
== ra
))))
3116 /* We conservatively put out stubs for all other cases (including
3124 /* Used to order a list of mapping symbols by address. */
3127 elf_aarch64_compare_mapping (const void *a
, const void *b
)
3129 const elf_aarch64_section_map
*amap
= (const elf_aarch64_section_map
*) a
;
3130 const elf_aarch64_section_map
*bmap
= (const elf_aarch64_section_map
*) b
;
3132 if (amap
->vma
> bmap
->vma
)
3134 else if (amap
->vma
< bmap
->vma
)
3136 else if (amap
->type
> bmap
->type
)
3137 /* Ensure results do not depend on the host qsort for objects with
3138 multiple mapping symbols at the same address by sorting on type
3141 else if (amap
->type
< bmap
->type
)
3149 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes
)
3151 char *stub_name
= (char *) bfd_malloc
3152 (strlen ("__erratum_835769_veneer_") + 16);
3153 sprintf (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
3157 /* Scan for Cortex-A53 erratum 835769 sequence.
3159 Return TRUE else FALSE on abnormal termination. */
3162 _bfd_aarch64_erratum_835769_scan (bfd
*input_bfd
,
3163 struct bfd_link_info
*info
,
3164 unsigned int *num_fixes_p
)
3167 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3168 unsigned int num_fixes
= *num_fixes_p
;
3173 for (section
= input_bfd
->sections
;
3175 section
= section
->next
)
3177 bfd_byte
*contents
= NULL
;
3178 struct _aarch64_elf_section_data
*sec_data
;
3181 if (elf_section_type (section
) != SHT_PROGBITS
3182 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3183 || (section
->flags
& SEC_EXCLUDE
) != 0
3184 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3185 || (section
->output_section
== bfd_abs_section_ptr
))
3188 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3189 contents
= elf_section_data (section
)->this_hdr
.contents
;
3190 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3193 sec_data
= elf_aarch64_section_data (section
);
3195 qsort (sec_data
->map
, sec_data
->mapcount
,
3196 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3198 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3200 unsigned int span_start
= sec_data
->map
[span
].vma
;
3201 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3202 ? sec_data
->map
[0].vma
+ section
->size
3203 : sec_data
->map
[span
+ 1].vma
);
3205 char span_type
= sec_data
->map
[span
].type
;
3207 if (span_type
== 'd')
3210 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
3212 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3213 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3215 if (aarch64_erratum_sequence (insn_1
, insn_2
))
3217 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3218 char *stub_name
= _bfd_aarch64_erratum_835769_stub_name (num_fixes
);
3222 stub_entry
= _bfd_aarch64_add_stub_entry_in_group (stub_name
,
3228 stub_entry
->stub_type
= aarch64_stub_erratum_835769_veneer
;
3229 stub_entry
->target_section
= section
;
3230 stub_entry
->target_value
= i
+ 4;
3231 stub_entry
->veneered_insn
= insn_2
;
3232 stub_entry
->output_name
= stub_name
;
3237 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3241 *num_fixes_p
= num_fixes
;
3247 /* Test if instruction INSN is ADRP. */
3250 _bfd_aarch64_adrp_p (uint32_t insn
)
3252 return ((insn
& 0x9f000000) == 0x90000000);
3256 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
3259 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1
, uint32_t insn_2
,
3267 return (aarch64_mem_op_p (insn_2
, &rt
, &rt2
, &pair
, &load
)
3270 && AARCH64_LDST_UIMM (insn_3
)
3271 && AARCH64_RN (insn_3
) == AARCH64_RD (insn_1
));
3275 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
3277 Return TRUE if section CONTENTS at offset I contains one of the
3278 erratum 843419 sequences, otherwise return FALSE. If a sequence is
3279 seen set P_VENEER_I to the offset of the final LOAD/STORE
3280 instruction in the sequence.
3284 _bfd_aarch64_erratum_843419_p (bfd_byte
*contents
, bfd_vma vma
,
3285 bfd_vma i
, bfd_vma span_end
,
3286 bfd_vma
*p_veneer_i
)
3288 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3290 if (!_bfd_aarch64_adrp_p (insn_1
))
3293 if (span_end
< i
+ 12)
3296 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3297 uint32_t insn_3
= bfd_getl32 (contents
+ i
+ 8);
3299 if ((vma
& 0xfff) != 0xff8 && (vma
& 0xfff) != 0xffc)
3302 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_3
))
3304 *p_veneer_i
= i
+ 8;
3308 if (span_end
< i
+ 16)
3311 uint32_t insn_4
= bfd_getl32 (contents
+ i
+ 12);
3313 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_4
))
3315 *p_veneer_i
= i
+ 12;
3323 /* Resize all stub sections. */
3326 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table
*htab
)
3330 /* OK, we've added some stubs. Find out the new size of the
3332 for (section
= htab
->stub_bfd
->sections
;
3333 section
!= NULL
; section
= section
->next
)
3335 /* Ignore non-stub sections. */
3336 if (!strstr (section
->name
, STUB_SUFFIX
))
3341 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
3343 for (section
= htab
->stub_bfd
->sections
;
3344 section
!= NULL
; section
= section
->next
)
3346 if (!strstr (section
->name
, STUB_SUFFIX
))
3352 /* Ensure all stub sections have a size which is a multiple of
3353 4096. This is important in order to ensure that the insertion
3354 of stub sections does not in itself move existing code around
3355 in such a way that new errata sequences are created. */
3356 if (htab
->fix_erratum_843419
)
3358 section
->size
= BFD_ALIGN (section
->size
, 0x1000);
3363 /* Construct an erratum 843419 workaround stub name.
3367 _bfd_aarch64_erratum_843419_stub_name (asection
*input_section
,
3370 const bfd_size_type len
= 8 + 4 + 1 + 8 + 1 + 16 + 1;
3371 char *stub_name
= bfd_malloc (len
);
3373 if (stub_name
!= NULL
)
3374 snprintf (stub_name
, len
, "e843419@%04x_%08x_%" BFD_VMA_FMT
"x",
3375 input_section
->owner
->id
,
3381 /* Build a stub_entry structure describing an 843419 fixup.
3383 The stub_entry constructed is populated with the bit pattern INSN
3384 of the instruction located at OFFSET within input SECTION.
3386 Returns TRUE on success. */
3389 _bfd_aarch64_erratum_843419_fixup (uint32_t insn
,
3390 bfd_vma adrp_offset
,
3391 bfd_vma ldst_offset
,
3393 struct bfd_link_info
*info
)
3395 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3397 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3399 stub_name
= _bfd_aarch64_erratum_843419_stub_name (section
, ldst_offset
);
3400 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3408 /* We always place an 843419 workaround veneer in the stub section
3409 attached to the input section in which an erratum sequence has
3410 been found. This ensures that later in the link process (in
3411 elfNN_aarch64_write_section) when we copy the veneered
3412 instruction from the input section into the stub section the
3413 copied instruction will have had any relocations applied to it.
3414 If we placed workaround veneers in any other stub section then we
3415 could not assume that all relocations have been processed on the
3416 corresponding input section at the point we output the stub
3420 stub_entry
= _bfd_aarch64_add_stub_entry_after (stub_name
, section
, htab
);
3421 if (stub_entry
== NULL
)
3427 stub_entry
->adrp_offset
= adrp_offset
;
3428 stub_entry
->target_value
= ldst_offset
;
3429 stub_entry
->target_section
= section
;
3430 stub_entry
->stub_type
= aarch64_stub_erratum_843419_veneer
;
3431 stub_entry
->veneered_insn
= insn
;
3432 stub_entry
->output_name
= stub_name
;
3438 /* Scan an input section looking for the signature of erratum 843419.
3440 Scans input SECTION in INPUT_BFD looking for erratum 843419
3441 signatures, for each signature found a stub_entry is created
3442 describing the location of the erratum for subsequent fixup.
3444 Return TRUE on successful scan, FALSE on failure to scan.
3448 _bfd_aarch64_erratum_843419_scan (bfd
*input_bfd
, asection
*section
,
3449 struct bfd_link_info
*info
)
3451 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3456 if (elf_section_type (section
) != SHT_PROGBITS
3457 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3458 || (section
->flags
& SEC_EXCLUDE
) != 0
3459 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3460 || (section
->output_section
== bfd_abs_section_ptr
))
3465 bfd_byte
*contents
= NULL
;
3466 struct _aarch64_elf_section_data
*sec_data
;
3469 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3470 contents
= elf_section_data (section
)->this_hdr
.contents
;
3471 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3474 sec_data
= elf_aarch64_section_data (section
);
3476 qsort (sec_data
->map
, sec_data
->mapcount
,
3477 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3479 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3481 unsigned int span_start
= sec_data
->map
[span
].vma
;
3482 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3483 ? sec_data
->map
[0].vma
+ section
->size
3484 : sec_data
->map
[span
+ 1].vma
);
3486 char span_type
= sec_data
->map
[span
].type
;
3488 if (span_type
== 'd')
3491 for (i
= span_start
; i
+ 8 < span_end
; i
+= 4)
3493 bfd_vma vma
= (section
->output_section
->vma
3494 + section
->output_offset
3498 if (_bfd_aarch64_erratum_843419_p
3499 (contents
, vma
, i
, span_end
, &veneer_i
))
3501 uint32_t insn
= bfd_getl32 (contents
+ veneer_i
);
3503 if (!_bfd_aarch64_erratum_843419_fixup (insn
, i
, veneer_i
,
3510 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3519 /* Determine and set the size of the stub section for a final link.
3521 The basic idea here is to examine all the relocations looking for
3522 PC-relative calls to a target that is unreachable with a "bl"
3526 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
3528 struct bfd_link_info
*info
,
3529 bfd_signed_vma group_size
,
3530 asection
* (*add_stub_section
) (const char *,
3532 void (*layout_sections_again
) (void))
3534 bfd_size_type stub_group_size
;
3535 bfd_boolean stubs_always_before_branch
;
3536 bfd_boolean stub_changed
= FALSE
;
3537 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3538 unsigned int num_erratum_835769_fixes
= 0;
3540 /* Propagate mach to stub bfd, because it may not have been
3541 finalized when we created stub_bfd. */
3542 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
3543 bfd_get_mach (output_bfd
));
3545 /* Stash our params away. */
3546 htab
->stub_bfd
= stub_bfd
;
3547 htab
->add_stub_section
= add_stub_section
;
3548 htab
->layout_sections_again
= layout_sections_again
;
3549 stubs_always_before_branch
= group_size
< 0;
3551 stub_group_size
= -group_size
;
3553 stub_group_size
= group_size
;
3555 if (stub_group_size
== 1)
3557 /* Default values. */
3558 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
3559 stub_group_size
= 127 * 1024 * 1024;
3562 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
3564 (*htab
->layout_sections_again
) ();
3566 if (htab
->fix_erratum_835769
)
3570 for (input_bfd
= info
->input_bfds
;
3571 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3572 if (!_bfd_aarch64_erratum_835769_scan (input_bfd
, info
,
3573 &num_erratum_835769_fixes
))
3576 _bfd_aarch64_resize_stubs (htab
);
3577 (*htab
->layout_sections_again
) ();
3580 if (htab
->fix_erratum_843419
)
3584 for (input_bfd
= info
->input_bfds
;
3586 input_bfd
= input_bfd
->link
.next
)
3590 for (section
= input_bfd
->sections
;
3592 section
= section
->next
)
3593 if (!_bfd_aarch64_erratum_843419_scan (input_bfd
, section
, info
))
3597 _bfd_aarch64_resize_stubs (htab
);
3598 (*htab
->layout_sections_again
) ();
3605 for (input_bfd
= info
->input_bfds
;
3606 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3608 Elf_Internal_Shdr
*symtab_hdr
;
3610 Elf_Internal_Sym
*local_syms
= NULL
;
3612 /* We'll need the symbol table in a second. */
3613 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3614 if (symtab_hdr
->sh_info
== 0)
3617 /* Walk over each section attached to the input bfd. */
3618 for (section
= input_bfd
->sections
;
3619 section
!= NULL
; section
= section
->next
)
3621 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
3623 /* If there aren't any relocs, then there's nothing more
3625 if ((section
->flags
& SEC_RELOC
) == 0
3626 || section
->reloc_count
== 0
3627 || (section
->flags
& SEC_CODE
) == 0)
3630 /* If this section is a link-once section that will be
3631 discarded, then don't create any stubs. */
3632 if (section
->output_section
== NULL
3633 || section
->output_section
->owner
!= output_bfd
)
3636 /* Get the relocs. */
3638 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
3639 NULL
, info
->keep_memory
);
3640 if (internal_relocs
== NULL
)
3641 goto error_ret_free_local
;
3643 /* Now examine each relocation. */
3644 irela
= internal_relocs
;
3645 irelaend
= irela
+ section
->reloc_count
;
3646 for (; irela
< irelaend
; irela
++)
3648 unsigned int r_type
, r_indx
;
3649 enum elf_aarch64_stub_type stub_type
;
3650 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3653 bfd_vma destination
;
3654 struct elf_aarch64_link_hash_entry
*hash
;
3655 const char *sym_name
;
3657 const asection
*id_sec
;
3658 unsigned char st_type
;
3661 r_type
= ELFNN_R_TYPE (irela
->r_info
);
3662 r_indx
= ELFNN_R_SYM (irela
->r_info
);
3664 if (r_type
>= (unsigned int) R_AARCH64_end
)
3666 bfd_set_error (bfd_error_bad_value
);
3667 error_ret_free_internal
:
3668 if (elf_section_data (section
)->relocs
== NULL
)
3669 free (internal_relocs
);
3670 goto error_ret_free_local
;
3673 /* Only look for stubs on unconditional branch and
3674 branch and link instructions. */
3675 if (r_type
!= (unsigned int) AARCH64_R (CALL26
)
3676 && r_type
!= (unsigned int) AARCH64_R (JUMP26
))
3679 /* Now determine the call target, its name, value,
3686 if (r_indx
< symtab_hdr
->sh_info
)
3688 /* It's a local symbol. */
3689 Elf_Internal_Sym
*sym
;
3690 Elf_Internal_Shdr
*hdr
;
3692 if (local_syms
== NULL
)
3695 = (Elf_Internal_Sym
*) symtab_hdr
->contents
;
3696 if (local_syms
== NULL
)
3698 = bfd_elf_get_elf_syms (input_bfd
, symtab_hdr
,
3699 symtab_hdr
->sh_info
, 0,
3701 if (local_syms
== NULL
)
3702 goto error_ret_free_internal
;
3705 sym
= local_syms
+ r_indx
;
3706 hdr
= elf_elfsections (input_bfd
)[sym
->st_shndx
];
3707 sym_sec
= hdr
->bfd_section
;
3709 /* This is an undefined symbol. It can never
3713 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
3714 sym_value
= sym
->st_value
;
3715 destination
= (sym_value
+ irela
->r_addend
3716 + sym_sec
->output_offset
3717 + sym_sec
->output_section
->vma
);
3718 st_type
= ELF_ST_TYPE (sym
->st_info
);
3720 = bfd_elf_string_from_elf_section (input_bfd
,
3721 symtab_hdr
->sh_link
,
3728 e_indx
= r_indx
- symtab_hdr
->sh_info
;
3729 hash
= ((struct elf_aarch64_link_hash_entry
*)
3730 elf_sym_hashes (input_bfd
)[e_indx
]);
3732 while (hash
->root
.root
.type
== bfd_link_hash_indirect
3733 || hash
->root
.root
.type
== bfd_link_hash_warning
)
3734 hash
= ((struct elf_aarch64_link_hash_entry
*)
3735 hash
->root
.root
.u
.i
.link
);
3737 if (hash
->root
.root
.type
== bfd_link_hash_defined
3738 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
3740 struct elf_aarch64_link_hash_table
*globals
=
3741 elf_aarch64_hash_table (info
);
3742 sym_sec
= hash
->root
.root
.u
.def
.section
;
3743 sym_value
= hash
->root
.root
.u
.def
.value
;
3744 /* For a destination in a shared library,
3745 use the PLT stub as target address to
3746 decide whether a branch stub is
3748 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
3749 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
3751 sym_sec
= globals
->root
.splt
;
3752 sym_value
= hash
->root
.plt
.offset
;
3753 if (sym_sec
->output_section
!= NULL
)
3754 destination
= (sym_value
3755 + sym_sec
->output_offset
3757 sym_sec
->output_section
->vma
);
3759 else if (sym_sec
->output_section
!= NULL
)
3760 destination
= (sym_value
+ irela
->r_addend
3761 + sym_sec
->output_offset
3762 + sym_sec
->output_section
->vma
);
3764 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
3765 || (hash
->root
.root
.type
3766 == bfd_link_hash_undefweak
))
3768 /* For a shared library, use the PLT stub as
3769 target address to decide whether a long
3770 branch stub is needed.
3771 For absolute code, they cannot be handled. */
3772 struct elf_aarch64_link_hash_table
*globals
=
3773 elf_aarch64_hash_table (info
);
3775 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
3776 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
3778 sym_sec
= globals
->root
.splt
;
3779 sym_value
= hash
->root
.plt
.offset
;
3780 if (sym_sec
->output_section
!= NULL
)
3781 destination
= (sym_value
3782 + sym_sec
->output_offset
3784 sym_sec
->output_section
->vma
);
3791 bfd_set_error (bfd_error_bad_value
);
3792 goto error_ret_free_internal
;
3794 st_type
= ELF_ST_TYPE (hash
->root
.type
);
3795 sym_name
= hash
->root
.root
.root
.string
;
3798 /* Determine what (if any) linker stub is needed. */
3799 stub_type
= aarch64_type_of_stub
3800 (info
, section
, irela
, st_type
, hash
, destination
);
3801 if (stub_type
== aarch64_stub_none
)
3804 /* Support for grouping stub sections. */
3805 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
3807 /* Get the name of this stub. */
3808 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
3811 goto error_ret_free_internal
;
3814 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
3815 stub_name
, FALSE
, FALSE
);
3816 if (stub_entry
!= NULL
)
3818 /* The proper stub has already been created. */
3823 stub_entry
= _bfd_aarch64_add_stub_entry_in_group
3824 (stub_name
, section
, htab
);
3825 if (stub_entry
== NULL
)
3828 goto error_ret_free_internal
;
3831 stub_entry
->target_value
= sym_value
;
3832 stub_entry
->target_section
= sym_sec
;
3833 stub_entry
->stub_type
= stub_type
;
3834 stub_entry
->h
= hash
;
3835 stub_entry
->st_type
= st_type
;
3837 if (sym_name
== NULL
)
3838 sym_name
= "unnamed";
3839 len
= sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
);
3840 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
3841 if (stub_entry
->output_name
== NULL
)
3844 goto error_ret_free_internal
;
3847 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
3850 stub_changed
= TRUE
;
3853 /* We're done with the internal relocs, free them. */
3854 if (elf_section_data (section
)->relocs
== NULL
)
3855 free (internal_relocs
);
3862 _bfd_aarch64_resize_stubs (htab
);
3864 /* Ask the linker to do its stuff. */
3865 (*htab
->layout_sections_again
) ();
3866 stub_changed
= FALSE
;
3871 error_ret_free_local
:
3875 /* Build all the stubs associated with the current output file. The
3876 stubs are kept in a hash table attached to the main linker hash
3877 table. We also set up the .plt entries for statically linked PIC
3878 functions here. This function is called via aarch64_elf_finish in the
3882 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
3885 struct bfd_hash_table
*table
;
3886 struct elf_aarch64_link_hash_table
*htab
;
3888 htab
= elf_aarch64_hash_table (info
);
3890 for (stub_sec
= htab
->stub_bfd
->sections
;
3891 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
3895 /* Ignore non-stub sections. */
3896 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
3899 /* Allocate memory to hold the linker stubs. */
3900 size
= stub_sec
->size
;
3901 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
3902 if (stub_sec
->contents
== NULL
&& size
!= 0)
3906 bfd_putl32 (0x14000000 | (size
>> 2), stub_sec
->contents
);
3907 stub_sec
->size
+= 4;
3910 /* Build the stubs as directed by the stub hash table. */
3911 table
= &htab
->stub_hash_table
;
3912 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
3918 /* Add an entry to the code/data map for section SEC. */
3921 elfNN_aarch64_section_map_add (asection
*sec
, char type
, bfd_vma vma
)
3923 struct _aarch64_elf_section_data
*sec_data
=
3924 elf_aarch64_section_data (sec
);
3925 unsigned int newidx
;
3927 if (sec_data
->map
== NULL
)
3929 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
3930 sec_data
->mapcount
= 0;
3931 sec_data
->mapsize
= 1;
3934 newidx
= sec_data
->mapcount
++;
3936 if (sec_data
->mapcount
> sec_data
->mapsize
)
3938 sec_data
->mapsize
*= 2;
3939 sec_data
->map
= bfd_realloc_or_free
3940 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
3945 sec_data
->map
[newidx
].vma
= vma
;
3946 sec_data
->map
[newidx
].type
= type
;
3951 /* Initialise maps of insn/data for input BFDs. */
3953 bfd_elfNN_aarch64_init_maps (bfd
*abfd
)
3955 Elf_Internal_Sym
*isymbuf
;
3956 Elf_Internal_Shdr
*hdr
;
3957 unsigned int i
, localsyms
;
3959 /* Make sure that we are dealing with an AArch64 elf binary. */
3960 if (!is_aarch64_elf (abfd
))
3963 if ((abfd
->flags
& DYNAMIC
) != 0)
3966 hdr
= &elf_symtab_hdr (abfd
);
3967 localsyms
= hdr
->sh_info
;
3969 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
3970 should contain the number of local symbols, which should come before any
3971 global symbols. Mapping symbols are always local. */
3972 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
3974 /* No internal symbols read? Skip this BFD. */
3975 if (isymbuf
== NULL
)
3978 for (i
= 0; i
< localsyms
; i
++)
3980 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
3981 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
3984 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
3986 name
= bfd_elf_string_from_elf_section (abfd
,
3990 if (bfd_is_aarch64_special_symbol_name
3991 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
3992 elfNN_aarch64_section_map_add (sec
, name
[1], isym
->st_value
);
3997 /* Set option values needed during linking. */
3999 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
4000 struct bfd_link_info
*link_info
,
4002 int no_wchar_warn
, int pic_veneer
,
4003 int fix_erratum_835769
,
4004 int fix_erratum_843419
)
4006 struct elf_aarch64_link_hash_table
*globals
;
4008 globals
= elf_aarch64_hash_table (link_info
);
4009 globals
->pic_veneer
= pic_veneer
;
4010 globals
->fix_erratum_835769
= fix_erratum_835769
;
4011 globals
->fix_erratum_843419
= fix_erratum_843419
;
4012 globals
->fix_erratum_843419_adr
= TRUE
;
4014 BFD_ASSERT (is_aarch64_elf (output_bfd
));
4015 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
4016 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
4020 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
4021 struct elf_aarch64_link_hash_table
4022 *globals
, struct bfd_link_info
*info
,
4023 bfd_vma value
, bfd
*output_bfd
,
4024 bfd_boolean
*unresolved_reloc_p
)
4026 bfd_vma off
= (bfd_vma
) - 1;
4027 asection
*basegot
= globals
->root
.sgot
;
4028 bfd_boolean dyn
= globals
->root
.dynamic_sections_created
;
4032 BFD_ASSERT (basegot
!= NULL
);
4033 off
= h
->got
.offset
;
4034 BFD_ASSERT (off
!= (bfd_vma
) - 1);
4035 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, info
->shared
, h
)
4037 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4038 || (ELF_ST_VISIBILITY (h
->other
)
4039 && h
->root
.type
== bfd_link_hash_undefweak
))
4041 /* This is actually a static link, or it is a -Bsymbolic link
4042 and the symbol is defined locally. We must initialize this
4043 entry in the global offset table. Since the offset must
4044 always be a multiple of 8 (4 in the case of ILP32), we use
4045 the least significant bit to record whether we have
4046 initialized it already.
4047 When doing a dynamic link, we create a .rel(a).got relocation
4048 entry to initialize the value. This is done in the
4049 finish_dynamic_symbol routine. */
4054 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
4059 *unresolved_reloc_p
= FALSE
;
4061 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
4067 /* Change R_TYPE to a more efficient access model where possible,
4068 return the new reloc type. */
4070 static bfd_reloc_code_real_type
4071 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
4072 struct elf_link_hash_entry
*h
)
4074 bfd_boolean is_local
= h
== NULL
;
4078 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4079 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4081 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4082 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
4084 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
4086 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4089 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
4091 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4092 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
4094 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
4095 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4097 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4098 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
4100 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4101 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
4103 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
4104 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
4106 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4109 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4111 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
4112 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
4114 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4115 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4116 /* Instructions with these relocations will become NOPs. */
4117 return BFD_RELOC_AARCH64_NONE
;
4127 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
4131 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4132 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4133 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4134 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4135 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4136 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4139 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4140 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4141 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4142 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
4143 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
4144 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
4147 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4148 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4149 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
4150 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4151 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
4152 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
4153 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
4154 return GOT_TLSDESC_GD
;
4156 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4157 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
4158 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
4159 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4162 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
4163 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
4164 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
4165 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
4166 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
4167 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
4168 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
4169 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
4179 aarch64_can_relax_tls (bfd
*input_bfd
,
4180 struct bfd_link_info
*info
,
4181 bfd_reloc_code_real_type r_type
,
4182 struct elf_link_hash_entry
*h
,
4183 unsigned long r_symndx
)
4185 unsigned int symbol_got_type
;
4186 unsigned int reloc_got_type
;
4188 if (! IS_AARCH64_TLS_RELOC (r_type
))
4191 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
4192 reloc_got_type
= aarch64_reloc_got_type (r_type
);
4194 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
4200 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
4206 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
4209 static bfd_reloc_code_real_type
4210 aarch64_tls_transition (bfd
*input_bfd
,
4211 struct bfd_link_info
*info
,
4212 unsigned int r_type
,
4213 struct elf_link_hash_entry
*h
,
4214 unsigned long r_symndx
)
4216 bfd_reloc_code_real_type bfd_r_type
4217 = elfNN_aarch64_bfd_reloc_from_type (r_type
);
4219 if (! aarch64_can_relax_tls (input_bfd
, info
, bfd_r_type
, h
, r_symndx
))
4222 return aarch64_tls_transition_without_check (bfd_r_type
, h
);
4225 /* Return the base VMA address which should be subtracted from real addresses
4226 when resolving R_AARCH64_TLS_DTPREL relocation. */
4229 dtpoff_base (struct bfd_link_info
*info
)
4231 /* If tls_sec is NULL, we should have signalled an error already. */
4232 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
4233 return elf_hash_table (info
)->tls_sec
->vma
;
4236 /* Return the base VMA address which should be subtracted from real addresses
4237 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
4240 tpoff_base (struct bfd_link_info
*info
)
4242 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
4244 /* If tls_sec is NULL, we should have signalled an error already. */
4245 BFD_ASSERT (htab
->tls_sec
!= NULL
);
4247 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE
,
4248 htab
->tls_sec
->alignment_power
);
4249 return htab
->tls_sec
->vma
- base
;
4253 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4254 unsigned long r_symndx
)
4256 /* Calculate the address of the GOT entry for symbol
4257 referred to in h. */
4259 return &h
->got
.offset
;
4263 struct elf_aarch64_local_symbol
*l
;
4265 l
= elf_aarch64_locals (input_bfd
);
4266 return &l
[r_symndx
].got_offset
;
4271 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4272 unsigned long r_symndx
)
4275 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4280 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4281 unsigned long r_symndx
)
4284 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4289 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4290 unsigned long r_symndx
)
4293 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4299 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4300 unsigned long r_symndx
)
4302 /* Calculate the address of the GOT entry for symbol
4303 referred to in h. */
4306 struct elf_aarch64_link_hash_entry
*eh
;
4307 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
4308 return &eh
->tlsdesc_got_jump_table_offset
;
4313 struct elf_aarch64_local_symbol
*l
;
4315 l
= elf_aarch64_locals (input_bfd
);
4316 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
4321 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4322 unsigned long r_symndx
)
4325 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4330 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
4331 struct elf_link_hash_entry
*h
,
4332 unsigned long r_symndx
)
4335 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4340 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4341 unsigned long r_symndx
)
4344 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4349 /* Data for make_branch_to_erratum_835769_stub(). */
4351 struct erratum_835769_branch_to_stub_data
4353 struct bfd_link_info
*info
;
4354 asection
*output_section
;
4358 /* Helper to insert branches to erratum 835769 stubs in the right
4359 places for a particular section. */
4362 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
4365 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4366 struct erratum_835769_branch_to_stub_data
*data
;
4368 unsigned long branch_insn
= 0;
4369 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
4370 bfd_signed_vma branch_offset
;
4371 unsigned int target
;
4374 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4375 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4377 if (stub_entry
->target_section
!= data
->output_section
4378 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
4381 contents
= data
->contents
;
4382 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4383 + stub_entry
->target_section
->output_offset
4384 + stub_entry
->target_value
;
4385 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4386 + stub_entry
->stub_sec
->output_offset
4387 + stub_entry
->stub_offset
;
4388 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4390 abfd
= stub_entry
->target_section
->owner
;
4391 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4392 (*_bfd_error_handler
)
4393 (_("%B: error: Erratum 835769 stub out "
4394 "of range (input file too large)"), abfd
);
4396 target
= stub_entry
->target_value
;
4397 branch_insn
= 0x14000000;
4398 branch_offset
>>= 2;
4399 branch_offset
&= 0x3ffffff;
4400 branch_insn
|= branch_offset
;
4401 bfd_putl32 (branch_insn
, &contents
[target
]);
4408 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry
*gen_entry
,
4411 struct elf_aarch64_stub_hash_entry
*stub_entry
4412 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4413 struct erratum_835769_branch_to_stub_data
*data
4414 = (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4415 struct bfd_link_info
*info
;
4416 struct elf_aarch64_link_hash_table
*htab
;
4424 contents
= data
->contents
;
4425 section
= data
->output_section
;
4427 htab
= elf_aarch64_hash_table (info
);
4429 if (stub_entry
->target_section
!= section
4430 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
)
4433 insn
= bfd_getl32 (contents
+ stub_entry
->target_value
);
4435 stub_entry
->stub_sec
->contents
+ stub_entry
->stub_offset
);
4437 place
= (section
->output_section
->vma
+ section
->output_offset
4438 + stub_entry
->adrp_offset
);
4439 insn
= bfd_getl32 (contents
+ stub_entry
->adrp_offset
);
4441 if ((insn
& AARCH64_ADRP_OP_MASK
) != AARCH64_ADRP_OP
)
4444 bfd_signed_vma imm
=
4445 (_bfd_aarch64_sign_extend
4446 ((bfd_vma
) _bfd_aarch64_decode_adrp_imm (insn
) << 12, 33)
4449 if (htab
->fix_erratum_843419_adr
4450 && (imm
>= AARCH64_MIN_ADRP_IMM
&& imm
<= AARCH64_MAX_ADRP_IMM
))
4452 insn
= (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP
, imm
)
4453 | AARCH64_RT (insn
));
4454 bfd_putl32 (insn
, contents
+ stub_entry
->adrp_offset
);
4458 bfd_vma veneered_insn_loc
;
4459 bfd_vma veneer_entry_loc
;
4460 bfd_signed_vma branch_offset
;
4461 uint32_t branch_insn
;
4463 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4464 + stub_entry
->target_section
->output_offset
4465 + stub_entry
->target_value
;
4466 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4467 + stub_entry
->stub_sec
->output_offset
4468 + stub_entry
->stub_offset
;
4469 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4471 abfd
= stub_entry
->target_section
->owner
;
4472 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4473 (*_bfd_error_handler
)
4474 (_("%B: error: Erratum 843419 stub out "
4475 "of range (input file too large)"), abfd
);
4477 branch_insn
= 0x14000000;
4478 branch_offset
>>= 2;
4479 branch_offset
&= 0x3ffffff;
4480 branch_insn
|= branch_offset
;
4481 bfd_putl32 (branch_insn
, contents
+ stub_entry
->target_value
);
4488 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4489 struct bfd_link_info
*link_info
,
4494 struct elf_aarch64_link_hash_table
*globals
=
4495 elf_aarch64_hash_table (link_info
);
4497 if (globals
== NULL
)
4500 /* Fix code to point to erratum 835769 stubs. */
4501 if (globals
->fix_erratum_835769
)
4503 struct erratum_835769_branch_to_stub_data data
;
4505 data
.info
= link_info
;
4506 data
.output_section
= sec
;
4507 data
.contents
= contents
;
4508 bfd_hash_traverse (&globals
->stub_hash_table
,
4509 make_branch_to_erratum_835769_stub
, &data
);
4512 if (globals
->fix_erratum_843419
)
4514 struct erratum_835769_branch_to_stub_data data
;
4516 data
.info
= link_info
;
4517 data
.output_section
= sec
;
4518 data
.contents
= contents
;
4519 bfd_hash_traverse (&globals
->stub_hash_table
,
4520 _bfd_aarch64_erratum_843419_branch_to_stub
, &data
);
4526 /* Perform a relocation as part of a final link. */
4527 static bfd_reloc_status_type
4528 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
4531 asection
*input_section
,
4533 Elf_Internal_Rela
*rel
,
4535 struct bfd_link_info
*info
,
4537 struct elf_link_hash_entry
*h
,
4538 bfd_boolean
*unresolved_reloc_p
,
4539 bfd_boolean save_addend
,
4540 bfd_vma
*saved_addend
,
4541 Elf_Internal_Sym
*sym
)
4543 Elf_Internal_Shdr
*symtab_hdr
;
4544 unsigned int r_type
= howto
->type
;
4545 bfd_reloc_code_real_type bfd_r_type
4546 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
4547 bfd_reloc_code_real_type new_bfd_r_type
;
4548 unsigned long r_symndx
;
4549 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
4551 bfd_signed_vma signed_addend
;
4552 struct elf_aarch64_link_hash_table
*globals
;
4553 bfd_boolean weak_undef_p
;
4556 globals
= elf_aarch64_hash_table (info
);
4558 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
4560 BFD_ASSERT (is_aarch64_elf (input_bfd
));
4562 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4564 /* It is possible to have linker relaxations on some TLS access
4565 models. Update our information here. */
4566 new_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
, h
, r_symndx
);
4567 if (new_bfd_r_type
!= bfd_r_type
)
4569 bfd_r_type
= new_bfd_r_type
;
4570 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
4571 BFD_ASSERT (howto
!= NULL
);
4572 r_type
= howto
->type
;
4575 place
= input_section
->output_section
->vma
4576 + input_section
->output_offset
+ rel
->r_offset
;
4578 /* Get addend, accumulating the addend for consecutive relocs
4579 which refer to the same offset. */
4580 signed_addend
= saved_addend
? *saved_addend
: 0;
4581 signed_addend
+= rel
->r_addend
;
4583 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
4584 : bfd_is_und_section (sym_sec
));
4586 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
4587 it here if it is defined in a non-shared object. */
4589 && h
->type
== STT_GNU_IFUNC
4596 if ((input_section
->flags
& SEC_ALLOC
) == 0
4597 || h
->plt
.offset
== (bfd_vma
) -1)
4600 /* STT_GNU_IFUNC symbol must go through PLT. */
4601 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
4602 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
4607 if (h
->root
.root
.string
)
4608 name
= h
->root
.root
.string
;
4610 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4612 (*_bfd_error_handler
)
4613 (_("%B: relocation %s against STT_GNU_IFUNC "
4614 "symbol `%s' isn't handled by %s"), input_bfd
,
4615 howto
->name
, name
, __FUNCTION__
);
4616 bfd_set_error (bfd_error_bad_value
);
4619 case BFD_RELOC_AARCH64_NN
:
4620 if (rel
->r_addend
!= 0)
4622 if (h
->root
.root
.string
)
4623 name
= h
->root
.root
.string
;
4625 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
4627 (*_bfd_error_handler
)
4628 (_("%B: relocation %s against STT_GNU_IFUNC "
4629 "symbol `%s' has non-zero addend: %d"),
4630 input_bfd
, howto
->name
, name
, rel
->r_addend
);
4631 bfd_set_error (bfd_error_bad_value
);
4635 /* Generate dynamic relocation only when there is a
4636 non-GOT reference in a shared object. */
4637 if (info
->shared
&& h
->non_got_ref
)
4639 Elf_Internal_Rela outrel
;
4642 /* Need a dynamic relocation to get the real function
4644 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
4648 if (outrel
.r_offset
== (bfd_vma
) -1
4649 || outrel
.r_offset
== (bfd_vma
) -2)
4652 outrel
.r_offset
+= (input_section
->output_section
->vma
4653 + input_section
->output_offset
);
4655 if (h
->dynindx
== -1
4657 || info
->executable
)
4659 /* This symbol is resolved locally. */
4660 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
4661 outrel
.r_addend
= (h
->root
.u
.def
.value
4662 + h
->root
.u
.def
.section
->output_section
->vma
4663 + h
->root
.u
.def
.section
->output_offset
);
4667 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
4668 outrel
.r_addend
= 0;
4671 sreloc
= globals
->root
.irelifunc
;
4672 elf_append_rela (output_bfd
, sreloc
, &outrel
);
4674 /* If this reloc is against an external symbol, we
4675 do not want to fiddle with the addend. Otherwise,
4676 we need to include the symbol value so that it
4677 becomes an addend for the dynamic reloc. For an
4678 internal symbol, we have updated addend. */
4679 return bfd_reloc_ok
;
4682 case BFD_RELOC_AARCH64_CALL26
:
4683 case BFD_RELOC_AARCH64_JUMP26
:
4684 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4687 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
4689 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4690 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4691 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4692 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4693 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4694 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4695 base_got
= globals
->root
.sgot
;
4696 off
= h
->got
.offset
;
4698 if (base_got
== NULL
)
4701 if (off
== (bfd_vma
) -1)
4705 /* We can't use h->got.offset here to save state, or
4706 even just remember the offset, as finish_dynamic_symbol
4707 would use that as offset into .got. */
4709 if (globals
->root
.splt
!= NULL
)
4711 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
4712 globals
->plt_entry_size
);
4713 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
4714 base_got
= globals
->root
.sgotplt
;
4718 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
4719 off
= plt_index
* GOT_ENTRY_SIZE
;
4720 base_got
= globals
->root
.igotplt
;
4723 if (h
->dynindx
== -1
4727 /* This references the local definition. We must
4728 initialize this entry in the global offset table.
4729 Since the offset must always be a multiple of 8,
4730 we use the least significant bit to record
4731 whether we have initialized it already.
4733 When doing a dynamic link, we create a .rela.got
4734 relocation entry to initialize the value. This
4735 is done in the finish_dynamic_symbol routine. */
4740 bfd_put_NN (output_bfd
, value
,
4741 base_got
->contents
+ off
);
4742 /* Note that this is harmless as -1 | 1 still is -1. */
4746 value
= (base_got
->output_section
->vma
4747 + base_got
->output_offset
+ off
);
4750 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
4752 unresolved_reloc_p
);
4753 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
4754 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
4755 addend
= (globals
->root
.sgot
->output_section
->vma
4756 + globals
->root
.sgot
->output_offset
);
4757 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4758 addend
, weak_undef_p
);
4759 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
4760 case BFD_RELOC_AARCH64_ADD_LO12
:
4761 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
4768 case BFD_RELOC_AARCH64_NONE
:
4769 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4770 *unresolved_reloc_p
= FALSE
;
4771 return bfd_reloc_ok
;
4773 case BFD_RELOC_AARCH64_NN
:
4775 /* When generating a shared object or relocatable executable, these
4776 relocations are copied into the output file to be resolved at
4778 if (((info
->shared
== TRUE
) || globals
->root
.is_relocatable_executable
)
4779 && (input_section
->flags
& SEC_ALLOC
)
4781 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
4782 || h
->root
.type
!= bfd_link_hash_undefweak
))
4784 Elf_Internal_Rela outrel
;
4786 bfd_boolean skip
, relocate
;
4789 *unresolved_reloc_p
= FALSE
;
4794 outrel
.r_addend
= signed_addend
;
4796 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
4798 if (outrel
.r_offset
== (bfd_vma
) - 1)
4800 else if (outrel
.r_offset
== (bfd_vma
) - 2)
4806 outrel
.r_offset
+= (input_section
->output_section
->vma
4807 + input_section
->output_offset
);
4810 memset (&outrel
, 0, sizeof outrel
);
4813 && (!info
->shared
|| !SYMBOLIC_BIND (info
, h
) || !h
->def_regular
))
4814 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
4819 /* On SVR4-ish systems, the dynamic loader cannot
4820 relocate the text and data segments independently,
4821 so the symbol does not matter. */
4823 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
4824 outrel
.r_addend
+= value
;
4827 sreloc
= elf_section_data (input_section
)->sreloc
;
4828 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
4829 return bfd_reloc_notsupported
;
4831 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
4832 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
4834 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
4836 /* Sanity to check that we have previously allocated
4837 sufficient space in the relocation section for the
4838 number of relocations we actually want to emit. */
4842 /* If this reloc is against an external symbol, we do not want to
4843 fiddle with the addend. Otherwise, we need to include the symbol
4844 value so that it becomes an addend for the dynamic reloc. */
4846 return bfd_reloc_ok
;
4848 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
4849 contents
, rel
->r_offset
, value
,
4853 value
+= signed_addend
;
4856 case BFD_RELOC_AARCH64_CALL26
:
4857 case BFD_RELOC_AARCH64_JUMP26
:
4859 asection
*splt
= globals
->root
.splt
;
4860 bfd_boolean via_plt_p
=
4861 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
4863 /* A call to an undefined weak symbol is converted to a jump to
4864 the next instruction unless a PLT entry will be created.
4865 The jump to the next instruction is optimized as a NOP.
4866 Do the same for local undefined symbols. */
4867 if (weak_undef_p
&& ! via_plt_p
)
4869 bfd_putl32 (INSN_NOP
, hit_data
);
4870 return bfd_reloc_ok
;
4873 /* If the call goes through a PLT entry, make sure to
4874 check distance to the right destination address. */
4877 value
= (splt
->output_section
->vma
4878 + splt
->output_offset
+ h
->plt
.offset
);
4879 *unresolved_reloc_p
= FALSE
;
4882 /* If the target symbol is global and marked as a function the
4883 relocation applies a function call or a tail call. In this
4884 situation we can veneer out of range branches. The veneers
4885 use IP0 and IP1 hence cannot be used arbitrary out of range
4886 branches that occur within the body of a function. */
4887 if (h
&& h
->type
== STT_FUNC
)
4889 /* Check if a stub has to be inserted because the destination
4891 if (! aarch64_valid_branch_p (value
, place
))
4893 /* The target is out of reach, so redirect the branch to
4894 the local stub for this function. */
4895 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4896 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
,
4899 if (stub_entry
!= NULL
)
4900 value
= (stub_entry
->stub_offset
4901 + stub_entry
->stub_sec
->output_offset
4902 + stub_entry
->stub_sec
->output_section
->vma
);
4906 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4907 signed_addend
, weak_undef_p
);
4910 case BFD_RELOC_AARCH64_16_PCREL
:
4911 case BFD_RELOC_AARCH64_32_PCREL
:
4912 case BFD_RELOC_AARCH64_64_PCREL
:
4913 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
4914 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
4915 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
4916 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
4918 && (input_section
->flags
& SEC_ALLOC
) != 0
4919 && (input_section
->flags
& SEC_READONLY
) != 0
4923 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
4925 (*_bfd_error_handler
)
4926 (_("%B: relocation %s against external symbol `%s' can not be used"
4927 " when making a shared object; recompile with -fPIC"),
4928 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
4929 h
->root
.root
.string
);
4930 bfd_set_error (bfd_error_bad_value
);
4934 case BFD_RELOC_AARCH64_16
:
4936 case BFD_RELOC_AARCH64_32
:
4938 case BFD_RELOC_AARCH64_ADD_LO12
:
4939 case BFD_RELOC_AARCH64_BRANCH19
:
4940 case BFD_RELOC_AARCH64_LDST128_LO12
:
4941 case BFD_RELOC_AARCH64_LDST16_LO12
:
4942 case BFD_RELOC_AARCH64_LDST32_LO12
:
4943 case BFD_RELOC_AARCH64_LDST64_LO12
:
4944 case BFD_RELOC_AARCH64_LDST8_LO12
:
4945 case BFD_RELOC_AARCH64_MOVW_G0
:
4946 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
4947 case BFD_RELOC_AARCH64_MOVW_G0_S
:
4948 case BFD_RELOC_AARCH64_MOVW_G1
:
4949 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
4950 case BFD_RELOC_AARCH64_MOVW_G1_S
:
4951 case BFD_RELOC_AARCH64_MOVW_G2
:
4952 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
4953 case BFD_RELOC_AARCH64_MOVW_G2_S
:
4954 case BFD_RELOC_AARCH64_MOVW_G3
:
4955 case BFD_RELOC_AARCH64_TSTBR14
:
4956 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4957 signed_addend
, weak_undef_p
);
4960 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4961 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4962 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4963 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4964 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4965 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4966 if (globals
->root
.sgot
== NULL
)
4967 BFD_ASSERT (h
!= NULL
);
4972 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
, value
,
4974 unresolved_reloc_p
);
4975 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
4976 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
4977 addend
= (globals
->root
.sgot
->output_section
->vma
4978 + globals
->root
.sgot
->output_offset
);
4979 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4980 addend
, weak_undef_p
);
4985 struct elf_aarch64_local_symbol
*locals
4986 = elf_aarch64_locals (input_bfd
);
4990 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
4991 (*_bfd_error_handler
)
4992 (_("%B: Local symbol descriptor table be NULL when applying "
4993 "relocation %s against local symbol"),
4994 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
4998 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
4999 base_got
= globals
->root
.sgot
;
5000 bfd_vma got_entry_addr
= (base_got
->output_section
->vma
5001 + base_got
->output_offset
+ off
);
5003 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5005 bfd_put_64 (output_bfd
, value
, base_got
->contents
+ off
);
5010 Elf_Internal_Rela outrel
;
5012 /* For local symbol, we have done absolute relocation in static
5013 linking stageh. While for share library, we need to update
5014 the content of GOT entry according to the share objects
5015 loading base address. So we need to generate a
5016 R_AARCH64_RELATIVE reloc for dynamic linker. */
5017 s
= globals
->root
.srelgot
;
5021 outrel
.r_offset
= got_entry_addr
;
5022 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
5023 outrel
.r_addend
= value
;
5024 elf_append_rela (output_bfd
, s
, &outrel
);
5027 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5030 /* Update the relocation value to GOT entry addr as we have transformed
5031 the direct data access into indirect data access through GOT. */
5032 value
= got_entry_addr
;
5034 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5035 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
5036 addend
= base_got
->output_section
->vma
+ base_got
->output_offset
;
5038 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5039 addend
, weak_undef_p
);
5044 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5045 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5046 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5047 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5048 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5049 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5050 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5051 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5052 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5053 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5054 if (globals
->root
.sgot
== NULL
)
5055 return bfd_reloc_notsupported
;
5057 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
5058 + globals
->root
.sgot
->output_section
->vma
5059 + globals
->root
.sgot
->output_offset
);
5061 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5063 *unresolved_reloc_p
= FALSE
;
5066 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5067 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5068 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5069 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5070 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5071 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5072 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5073 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5074 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5075 signed_addend
- tpoff_base (info
),
5077 *unresolved_reloc_p
= FALSE
;
5080 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5081 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5082 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5083 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5084 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5085 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
5086 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5087 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5088 if (globals
->root
.sgot
== NULL
)
5089 return bfd_reloc_notsupported
;
5090 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
5091 + globals
->root
.sgotplt
->output_section
->vma
5092 + globals
->root
.sgotplt
->output_offset
5093 + globals
->sgotplt_jump_table_size
);
5095 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5097 *unresolved_reloc_p
= FALSE
;
5101 return bfd_reloc_notsupported
;
5105 *saved_addend
= value
;
5107 /* Only apply the final relocation in a sequence. */
5109 return bfd_reloc_continue
;
5111 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
5115 /* Handle TLS relaxations. Relaxing is possible for symbols that use
5116 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
5119 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
5120 is to then call final_link_relocate. Return other values in the
5123 static bfd_reloc_status_type
5124 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table
*globals
,
5125 bfd
*input_bfd
, bfd_byte
*contents
,
5126 Elf_Internal_Rela
*rel
, struct elf_link_hash_entry
*h
)
5128 bfd_boolean is_local
= h
== NULL
;
5129 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
5132 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
5134 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
5136 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5137 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5140 /* GD->LE relaxation:
5141 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
5143 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
5145 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
5146 return bfd_reloc_continue
;
5150 /* GD->IE relaxation:
5151 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
5153 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
5155 return bfd_reloc_continue
;
5158 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5162 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5165 /* Tiny TLSDESC->LE relaxation:
5166 ldr x1, :tlsdesc:var => movz x0, #:tprel_g1:var
5167 adr x0, :tlsdesc:var => movk x0, #:tprel_g0_nc:var
5171 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
5172 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
5174 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5175 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
5176 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5178 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
5179 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
+ 4);
5180 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
5181 return bfd_reloc_continue
;
5185 /* Tiny TLSDESC->IE relaxation:
5186 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
5187 adr x0, :tlsdesc:var => nop
5191 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
5192 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
5194 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5195 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5197 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
5198 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
5199 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
5200 return bfd_reloc_continue
;
5203 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5206 /* Tiny GD->LE relaxation:
5207 adr x0, :tlsgd:var => mrs x1, tpidr_el0
5208 bl __tls_get_addr => add x0, x1, #:tprel_hi12:x, lsl #12
5209 nop => add x0, x0, #:tprel_lo12_nc:x
5212 /* First kill the tls_get_addr reloc on the bl instruction. */
5213 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5215 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
5216 bfd_putl32 (0x91400020, contents
+ rel
->r_offset
+ 4);
5217 bfd_putl32 (0x91000000, contents
+ rel
->r_offset
+ 8);
5219 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5220 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
5221 rel
[1].r_offset
= rel
->r_offset
+ 8;
5223 /* Move the current relocation to the second instruction in
5226 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5227 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
5228 return bfd_reloc_continue
;
5232 /* Tiny GD->IE relaxation:
5233 adr x0, :tlsgd:var => ldr x0, :gottprel:var
5234 bl __tls_get_addr => mrs x1, tpidr_el0
5235 nop => add x0, x0, x1
5238 /* First kill the tls_get_addr reloc on the bl instruction. */
5239 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5240 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5242 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
5243 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
5244 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
5245 return bfd_reloc_continue
;
5248 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5249 return bfd_reloc_continue
;
5251 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5254 /* GD->LE relaxation:
5255 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
5257 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
5258 return bfd_reloc_continue
;
5262 /* GD->IE relaxation:
5263 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
5265 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5267 bfd_putl32 (insn
, contents
+ rel
->r_offset
);
5268 return bfd_reloc_continue
;
5271 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5274 /* GD->LE relaxation
5275 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
5276 bl __tls_get_addr => mrs x1, tpidr_el0
5277 nop => add x0, x1, x0
5280 /* First kill the tls_get_addr reloc on the bl instruction. */
5281 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5282 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5284 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
5285 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
5286 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
5287 return bfd_reloc_continue
;
5291 /* GD->IE relaxation
5292 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
5293 BL __tls_get_addr => mrs x1, tpidr_el0
5295 NOP => add x0, x1, x0
5298 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
5300 /* Remove the relocation on the BL instruction. */
5301 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5303 bfd_putl32 (0xf9400000, contents
+ rel
->r_offset
);
5305 /* We choose to fixup the BL and NOP instructions using the
5306 offset from the second relocation to allow flexibility in
5307 scheduling instructions between the ADD and BL. */
5308 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
5309 bfd_putl32 (0x8b000020, contents
+ rel
[1].r_offset
+ 4);
5310 return bfd_reloc_continue
;
5313 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5314 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5315 /* GD->IE/LE relaxation:
5316 add x0, x0, #:tlsdesc_lo12:var => nop
5319 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
5320 return bfd_reloc_ok
;
5322 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5323 /* IE->LE relaxation:
5324 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
5328 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5329 bfd_putl32 (0xd2a00000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
5331 return bfd_reloc_continue
;
5333 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5334 /* IE->LE relaxation:
5335 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
5339 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5340 bfd_putl32 (0xf2800000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
5342 return bfd_reloc_continue
;
5345 return bfd_reloc_continue
;
5348 return bfd_reloc_ok
;
5351 /* Relocate an AArch64 ELF section. */
5354 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
5355 struct bfd_link_info
*info
,
5357 asection
*input_section
,
5359 Elf_Internal_Rela
*relocs
,
5360 Elf_Internal_Sym
*local_syms
,
5361 asection
**local_sections
)
5363 Elf_Internal_Shdr
*symtab_hdr
;
5364 struct elf_link_hash_entry
**sym_hashes
;
5365 Elf_Internal_Rela
*rel
;
5366 Elf_Internal_Rela
*relend
;
5368 struct elf_aarch64_link_hash_table
*globals
;
5369 bfd_boolean save_addend
= FALSE
;
5372 globals
= elf_aarch64_hash_table (info
);
5374 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
5375 sym_hashes
= elf_sym_hashes (input_bfd
);
5378 relend
= relocs
+ input_section
->reloc_count
;
5379 for (; rel
< relend
; rel
++)
5381 unsigned int r_type
;
5382 bfd_reloc_code_real_type bfd_r_type
;
5383 bfd_reloc_code_real_type relaxed_bfd_r_type
;
5384 reloc_howto_type
*howto
;
5385 unsigned long r_symndx
;
5386 Elf_Internal_Sym
*sym
;
5388 struct elf_link_hash_entry
*h
;
5390 bfd_reloc_status_type r
;
5393 bfd_boolean unresolved_reloc
= FALSE
;
5394 char *error_message
= NULL
;
5396 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5397 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5399 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (r_type
);
5400 howto
= bfd_reloc
.howto
;
5404 (*_bfd_error_handler
)
5405 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
5406 input_bfd
, input_section
, r_type
);
5409 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
5415 if (r_symndx
< symtab_hdr
->sh_info
)
5417 sym
= local_syms
+ r_symndx
;
5418 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
5419 sec
= local_sections
[r_symndx
];
5421 /* An object file might have a reference to a local
5422 undefined symbol. This is a daft object file, but we
5423 should at least do something about it. */
5424 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
5425 && bfd_is_und_section (sec
)
5426 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
5428 if (!info
->callbacks
->undefined_symbol
5429 (info
, bfd_elf_string_from_elf_section
5430 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
5431 input_bfd
, input_section
, rel
->r_offset
, TRUE
))
5435 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
5437 /* Relocate against local STT_GNU_IFUNC symbol. */
5438 if (!info
->relocatable
5439 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
5441 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
5446 /* Set STT_GNU_IFUNC symbol value. */
5447 h
->root
.u
.def
.value
= sym
->st_value
;
5448 h
->root
.u
.def
.section
= sec
;
5453 bfd_boolean warned
, ignored
;
5455 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
5456 r_symndx
, symtab_hdr
, sym_hashes
,
5458 unresolved_reloc
, warned
, ignored
);
5463 if (sec
!= NULL
&& discarded_section (sec
))
5464 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
5465 rel
, 1, relend
, howto
, 0, contents
);
5467 if (info
->relocatable
)
5471 name
= h
->root
.root
.string
;
5474 name
= (bfd_elf_string_from_elf_section
5475 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
5476 if (name
== NULL
|| *name
== '\0')
5477 name
= bfd_section_name (input_bfd
, sec
);
5481 && r_type
!= R_AARCH64_NONE
5482 && r_type
!= R_AARCH64_NULL
5484 || h
->root
.type
== bfd_link_hash_defined
5485 || h
->root
.type
== bfd_link_hash_defweak
)
5486 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
5488 (*_bfd_error_handler
)
5489 ((sym_type
== STT_TLS
5490 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
5491 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
5493 input_section
, (long) rel
->r_offset
, howto
->name
, name
);
5496 /* We relax only if we can see that there can be a valid transition
5497 from a reloc type to another.
5498 We call elfNN_aarch64_final_link_relocate unless we're completely
5499 done, i.e., the relaxation produced the final output we want. */
5501 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
,
5503 if (relaxed_bfd_r_type
!= bfd_r_type
)
5505 bfd_r_type
= relaxed_bfd_r_type
;
5506 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
5507 BFD_ASSERT (howto
!= NULL
);
5508 r_type
= howto
->type
;
5509 r
= elfNN_aarch64_tls_relax (globals
, input_bfd
, contents
, rel
, h
);
5510 unresolved_reloc
= 0;
5513 r
= bfd_reloc_continue
;
5515 /* There may be multiple consecutive relocations for the
5516 same offset. In that case we are supposed to treat the
5517 output of each relocation as the addend for the next. */
5518 if (rel
+ 1 < relend
5519 && rel
->r_offset
== rel
[1].r_offset
5520 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
5521 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
5524 save_addend
= FALSE
;
5526 if (r
== bfd_reloc_continue
)
5527 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
5528 input_section
, contents
, rel
,
5529 relocation
, info
, sec
,
5530 h
, &unresolved_reloc
,
5531 save_addend
, &addend
, sym
);
5533 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
5535 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5536 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5537 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5538 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5539 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5540 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5541 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5543 bfd_boolean need_relocs
= FALSE
;
5548 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5549 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5552 (info
->shared
|| indx
!= 0) &&
5554 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5555 || h
->root
.type
!= bfd_link_hash_undefweak
);
5557 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5561 Elf_Internal_Rela rela
;
5562 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
5564 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
5565 globals
->root
.sgot
->output_offset
+ off
;
5568 loc
= globals
->root
.srelgot
->contents
;
5569 loc
+= globals
->root
.srelgot
->reloc_count
++
5570 * RELOC_SIZE (htab
);
5571 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5573 bfd_reloc_code_real_type real_type
=
5574 elfNN_aarch64_bfd_reloc_from_type (r_type
);
5576 if (real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
5577 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
5578 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
)
5580 /* For local dynamic, don't generate DTPREL in any case.
5581 Initialize the DTPREL slot into zero, so we get module
5582 base address when invoke runtime TLS resolver. */
5583 bfd_put_NN (output_bfd
, 0,
5584 globals
->root
.sgot
->contents
+ off
5589 bfd_put_NN (output_bfd
,
5590 relocation
- dtpoff_base (info
),
5591 globals
->root
.sgot
->contents
+ off
5596 /* This TLS symbol is global. We emit a
5597 relocation to fixup the tls offset at load
5600 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
5603 (globals
->root
.sgot
->output_section
->vma
5604 + globals
->root
.sgot
->output_offset
+ off
5607 loc
= globals
->root
.srelgot
->contents
;
5608 loc
+= globals
->root
.srelgot
->reloc_count
++
5609 * RELOC_SIZE (globals
);
5610 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5611 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5612 globals
->root
.sgot
->contents
+ off
5618 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
5619 globals
->root
.sgot
->contents
+ off
);
5620 bfd_put_NN (output_bfd
,
5621 relocation
- dtpoff_base (info
),
5622 globals
->root
.sgot
->contents
+ off
5626 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5630 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5631 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5632 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5633 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5635 bfd_boolean need_relocs
= FALSE
;
5640 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5642 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5645 (info
->shared
|| indx
!= 0) &&
5647 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5648 || h
->root
.type
!= bfd_link_hash_undefweak
);
5650 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5654 Elf_Internal_Rela rela
;
5657 rela
.r_addend
= relocation
- dtpoff_base (info
);
5661 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
5662 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
5663 globals
->root
.sgot
->output_offset
+ off
;
5665 loc
= globals
->root
.srelgot
->contents
;
5666 loc
+= globals
->root
.srelgot
->reloc_count
++
5667 * RELOC_SIZE (htab
);
5669 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5671 bfd_put_NN (output_bfd
, rela
.r_addend
,
5672 globals
->root
.sgot
->contents
+ off
);
5675 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
5676 globals
->root
.sgot
->contents
+ off
);
5678 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5682 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5683 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5684 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5685 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5686 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5687 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5688 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5689 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5692 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5693 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5694 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5695 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5696 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5697 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5699 bfd_boolean need_relocs
= FALSE
;
5700 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5701 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
5703 need_relocs
= (h
== NULL
5704 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5705 || h
->root
.type
!= bfd_link_hash_undefweak
);
5707 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5708 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
5713 Elf_Internal_Rela rela
;
5714 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLSDESC
));
5717 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
5718 + globals
->root
.sgotplt
->output_offset
5719 + off
+ globals
->sgotplt_jump_table_size
);
5722 rela
.r_addend
= relocation
- dtpoff_base (info
);
5724 /* Allocate the next available slot in the PLT reloc
5725 section to hold our R_AARCH64_TLSDESC, the next
5726 available slot is determined from reloc_count,
5727 which we step. But note, reloc_count was
5728 artifically moved down while allocating slots for
5729 real PLT relocs such that all of the PLT relocs
5730 will fit above the initial reloc_count and the
5731 extra stuff will fit below. */
5732 loc
= globals
->root
.srelplt
->contents
;
5733 loc
+= globals
->root
.srelplt
->reloc_count
++
5734 * RELOC_SIZE (globals
);
5736 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5738 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5739 globals
->root
.sgotplt
->contents
+ off
+
5740 globals
->sgotplt_jump_table_size
);
5741 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5742 globals
->root
.sgotplt
->contents
+ off
+
5743 globals
->sgotplt_jump_table_size
+
5747 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
5758 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
5759 because such sections are not SEC_ALLOC and thus ld.so will
5760 not process them. */
5761 if (unresolved_reloc
5762 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
5764 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
5765 +rel
->r_offset
) != (bfd_vma
) - 1)
5767 (*_bfd_error_handler
)
5769 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
5770 input_bfd
, input_section
, (long) rel
->r_offset
, howto
->name
,
5771 h
->root
.root
.string
);
5775 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
5779 case bfd_reloc_overflow
:
5780 if (!(*info
->callbacks
->reloc_overflow
)
5781 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
5782 input_bfd
, input_section
, rel
->r_offset
))
5786 case bfd_reloc_undefined
:
5787 if (!((*info
->callbacks
->undefined_symbol
)
5788 (info
, name
, input_bfd
, input_section
,
5789 rel
->r_offset
, TRUE
)))
5793 case bfd_reloc_outofrange
:
5794 error_message
= _("out of range");
5797 case bfd_reloc_notsupported
:
5798 error_message
= _("unsupported relocation");
5801 case bfd_reloc_dangerous
:
5802 /* error_message should already be set. */
5806 error_message
= _("unknown error");
5810 BFD_ASSERT (error_message
!= NULL
);
5811 if (!((*info
->callbacks
->reloc_dangerous
)
5812 (info
, error_message
, input_bfd
, input_section
,
5823 /* Set the right machine number. */
5826 elfNN_aarch64_object_p (bfd
*abfd
)
5829 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
5831 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
5836 /* Function to keep AArch64 specific flags in the ELF header. */
5839 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
5841 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
5846 elf_elfheader (abfd
)->e_flags
= flags
;
5847 elf_flags_init (abfd
) = TRUE
;
5853 /* Merge backend specific data from an object file to the output
5854 object file when linking. */
5857 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
5861 bfd_boolean flags_compatible
= TRUE
;
5864 /* Check if we have the same endianess. */
5865 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
5868 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
5871 /* The input BFD must have had its flags initialised. */
5872 /* The following seems bogus to me -- The flags are initialized in
5873 the assembler but I don't think an elf_flags_init field is
5874 written into the object. */
5875 /* BFD_ASSERT (elf_flags_init (ibfd)); */
5877 in_flags
= elf_elfheader (ibfd
)->e_flags
;
5878 out_flags
= elf_elfheader (obfd
)->e_flags
;
5880 if (!elf_flags_init (obfd
))
5882 /* If the input is the default architecture and had the default
5883 flags then do not bother setting the flags for the output
5884 architecture, instead allow future merges to do this. If no
5885 future merges ever set these flags then they will retain their
5886 uninitialised values, which surprise surprise, correspond
5887 to the default values. */
5888 if (bfd_get_arch_info (ibfd
)->the_default
5889 && elf_elfheader (ibfd
)->e_flags
== 0)
5892 elf_flags_init (obfd
) = TRUE
;
5893 elf_elfheader (obfd
)->e_flags
= in_flags
;
5895 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
5896 && bfd_get_arch_info (obfd
)->the_default
)
5897 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
5898 bfd_get_mach (ibfd
));
5903 /* Identical flags must be compatible. */
5904 if (in_flags
== out_flags
)
5907 /* Check to see if the input BFD actually contains any sections. If
5908 not, its flags may not have been initialised either, but it
5909 cannot actually cause any incompatiblity. Do not short-circuit
5910 dynamic objects; their section list may be emptied by
5911 elf_link_add_object_symbols.
5913 Also check to see if there are no code sections in the input.
5914 In this case there is no need to check for code specific flags.
5915 XXX - do we need to worry about floating-point format compatability
5916 in data sections ? */
5917 if (!(ibfd
->flags
& DYNAMIC
))
5919 bfd_boolean null_input_bfd
= TRUE
;
5920 bfd_boolean only_data_sections
= TRUE
;
5922 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5924 if ((bfd_get_section_flags (ibfd
, sec
)
5925 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
5926 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
5927 only_data_sections
= FALSE
;
5929 null_input_bfd
= FALSE
;
5933 if (null_input_bfd
|| only_data_sections
)
5937 return flags_compatible
;
5940 /* Display the flags field. */
5943 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
5945 FILE *file
= (FILE *) ptr
;
5946 unsigned long flags
;
5948 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
5950 /* Print normal ELF private data. */
5951 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
5953 flags
= elf_elfheader (abfd
)->e_flags
;
5954 /* Ignore init flag - it may not be set, despite the flags field
5955 containing valid data. */
5957 /* xgettext:c-format */
5958 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
5961 fprintf (file
, _("<Unrecognised flag bits set>"));
5968 /* Update the got entry reference counts for the section being removed. */
5971 elfNN_aarch64_gc_sweep_hook (bfd
*abfd
,
5972 struct bfd_link_info
*info
,
5974 const Elf_Internal_Rela
* relocs
)
5976 struct elf_aarch64_link_hash_table
*htab
;
5977 Elf_Internal_Shdr
*symtab_hdr
;
5978 struct elf_link_hash_entry
**sym_hashes
;
5979 struct elf_aarch64_local_symbol
*locals
;
5980 const Elf_Internal_Rela
*rel
, *relend
;
5982 if (info
->relocatable
)
5985 htab
= elf_aarch64_hash_table (info
);
5990 elf_section_data (sec
)->local_dynrel
= NULL
;
5992 symtab_hdr
= &elf_symtab_hdr (abfd
);
5993 sym_hashes
= elf_sym_hashes (abfd
);
5995 locals
= elf_aarch64_locals (abfd
);
5997 relend
= relocs
+ sec
->reloc_count
;
5998 for (rel
= relocs
; rel
< relend
; rel
++)
6000 unsigned long r_symndx
;
6001 unsigned int r_type
;
6002 struct elf_link_hash_entry
*h
= NULL
;
6004 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6006 if (r_symndx
>= symtab_hdr
->sh_info
)
6009 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
6010 while (h
->root
.type
== bfd_link_hash_indirect
6011 || h
->root
.type
== bfd_link_hash_warning
)
6012 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6016 Elf_Internal_Sym
*isym
;
6018 /* A local symbol. */
6019 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6022 /* Check relocation against local STT_GNU_IFUNC symbol. */
6024 && ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
6026 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
, FALSE
);
6034 struct elf_aarch64_link_hash_entry
*eh
;
6035 struct elf_dyn_relocs
**pp
;
6036 struct elf_dyn_relocs
*p
;
6038 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6040 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
; pp
= &p
->next
)
6043 /* Everything must go for SEC. */
6049 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6050 switch (aarch64_tls_transition (abfd
,info
, r_type
, h
,r_symndx
))
6052 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6053 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6054 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6055 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6056 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6057 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6058 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6059 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6060 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6061 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6062 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
6063 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6064 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6065 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6066 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6067 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6068 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6069 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6070 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6071 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6072 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6073 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6074 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
6075 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
6076 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
6077 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
6078 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
6079 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
6080 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
6081 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
6084 if (h
->got
.refcount
> 0)
6085 h
->got
.refcount
-= 1;
6087 if (h
->type
== STT_GNU_IFUNC
)
6089 if (h
->plt
.refcount
> 0)
6090 h
->plt
.refcount
-= 1;
6093 else if (locals
!= NULL
)
6095 if (locals
[r_symndx
].got_refcount
> 0)
6096 locals
[r_symndx
].got_refcount
-= 1;
6100 case BFD_RELOC_AARCH64_CALL26
:
6101 case BFD_RELOC_AARCH64_JUMP26
:
6102 /* If this is a local symbol then we resolve it
6103 directly without creating a PLT entry. */
6107 if (h
->plt
.refcount
> 0)
6108 h
->plt
.refcount
-= 1;
6111 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6112 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6113 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6114 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6115 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6116 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6117 case BFD_RELOC_AARCH64_MOVW_G3
:
6118 case BFD_RELOC_AARCH64_NN
:
6119 if (h
!= NULL
&& info
->executable
)
6121 if (h
->plt
.refcount
> 0)
6122 h
->plt
.refcount
-= 1;
6134 /* Adjust a symbol defined by a dynamic object and referenced by a
6135 regular object. The current definition is in some section of the
6136 dynamic object, but we're not including those sections. We have to
6137 change the definition to something the rest of the link can
6141 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
6142 struct elf_link_hash_entry
*h
)
6144 struct elf_aarch64_link_hash_table
*htab
;
6147 /* If this is a function, put it in the procedure linkage table. We
6148 will fill in the contents of the procedure linkage table later,
6149 when we know the address of the .got section. */
6150 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
6152 if (h
->plt
.refcount
<= 0
6153 || (h
->type
!= STT_GNU_IFUNC
6154 && (SYMBOL_CALLS_LOCAL (info
, h
)
6155 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
6156 && h
->root
.type
== bfd_link_hash_undefweak
))))
6158 /* This case can occur if we saw a CALL26 reloc in
6159 an input file, but the symbol wasn't referred to
6160 by a dynamic object or all references were
6161 garbage collected. In which case we can end up
6163 h
->plt
.offset
= (bfd_vma
) - 1;
6170 /* Otherwise, reset to -1. */
6171 h
->plt
.offset
= (bfd_vma
) - 1;
6174 /* If this is a weak symbol, and there is a real definition, the
6175 processor independent code will have arranged for us to see the
6176 real definition first, and we can just use the same value. */
6177 if (h
->u
.weakdef
!= NULL
)
6179 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
6180 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
6181 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
6182 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
6183 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
6184 h
->non_got_ref
= h
->u
.weakdef
->non_got_ref
;
6188 /* If we are creating a shared library, we must presume that the
6189 only references to the symbol are via the global offset table.
6190 For such cases we need not do anything here; the relocations will
6191 be handled correctly by relocate_section. */
6195 /* If there are no references to this symbol that do not use the
6196 GOT, we don't need to generate a copy reloc. */
6197 if (!h
->non_got_ref
)
6200 /* If -z nocopyreloc was given, we won't generate them either. */
6201 if (info
->nocopyreloc
)
6207 /* We must allocate the symbol in our .dynbss section, which will
6208 become part of the .bss section of the executable. There will be
6209 an entry for this symbol in the .dynsym section. The dynamic
6210 object will contain position independent code, so all references
6211 from the dynamic object to this symbol will go through the global
6212 offset table. The dynamic linker will use the .dynsym entry to
6213 determine the address it must put in the global offset table, so
6214 both the dynamic object and the regular object will refer to the
6215 same memory location for the variable. */
6217 htab
= elf_aarch64_hash_table (info
);
6219 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
6220 to copy the initial value out of the dynamic object and into the
6221 runtime process image. */
6222 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
6224 htab
->srelbss
->size
+= RELOC_SIZE (htab
);
6230 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
6235 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
6237 struct elf_aarch64_local_symbol
*locals
;
6238 locals
= elf_aarch64_locals (abfd
);
6241 locals
= (struct elf_aarch64_local_symbol
*)
6242 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
6245 elf_aarch64_locals (abfd
) = locals
;
6250 /* Create the .got section to hold the global offset table. */
6253 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
6255 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
6258 struct elf_link_hash_entry
*h
;
6259 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
6261 /* This function may be called more than once. */
6262 s
= bfd_get_linker_section (abfd
, ".got");
6266 flags
= bed
->dynamic_sec_flags
;
6268 s
= bfd_make_section_anyway_with_flags (abfd
,
6269 (bed
->rela_plts_and_copies_p
6270 ? ".rela.got" : ".rel.got"),
6271 (bed
->dynamic_sec_flags
6274 || ! bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
6278 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
6280 || !bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
6283 htab
->sgot
->size
+= GOT_ENTRY_SIZE
;
6285 if (bed
->want_got_sym
)
6287 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
6288 (or .got.plt) section. We don't do this in the linker script
6289 because we don't want to define the symbol if we are not creating
6290 a global offset table. */
6291 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
6292 "_GLOBAL_OFFSET_TABLE_");
6293 elf_hash_table (info
)->hgot
= h
;
6298 if (bed
->want_got_plt
)
6300 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
6302 || !bfd_set_section_alignment (abfd
, s
,
6303 bed
->s
->log_file_align
))
6308 /* The first bit of the global offset table is the header. */
6309 s
->size
+= bed
->got_header_size
;
6314 /* Look through the relocs for a section during the first phase. */
6317 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
6318 asection
*sec
, const Elf_Internal_Rela
*relocs
)
6320 Elf_Internal_Shdr
*symtab_hdr
;
6321 struct elf_link_hash_entry
**sym_hashes
;
6322 const Elf_Internal_Rela
*rel
;
6323 const Elf_Internal_Rela
*rel_end
;
6326 struct elf_aarch64_link_hash_table
*htab
;
6328 if (info
->relocatable
)
6331 BFD_ASSERT (is_aarch64_elf (abfd
));
6333 htab
= elf_aarch64_hash_table (info
);
6336 symtab_hdr
= &elf_symtab_hdr (abfd
);
6337 sym_hashes
= elf_sym_hashes (abfd
);
6339 rel_end
= relocs
+ sec
->reloc_count
;
6340 for (rel
= relocs
; rel
< rel_end
; rel
++)
6342 struct elf_link_hash_entry
*h
;
6343 unsigned long r_symndx
;
6344 unsigned int r_type
;
6345 bfd_reloc_code_real_type bfd_r_type
;
6346 Elf_Internal_Sym
*isym
;
6348 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6349 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6351 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
6353 (*_bfd_error_handler
) (_("%B: bad symbol index: %d"), abfd
,
6358 if (r_symndx
< symtab_hdr
->sh_info
)
6360 /* A local symbol. */
6361 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6366 /* Check relocation against local STT_GNU_IFUNC symbol. */
6367 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
6369 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
6374 /* Fake a STT_GNU_IFUNC symbol. */
6375 h
->type
= STT_GNU_IFUNC
;
6378 h
->forced_local
= 1;
6379 h
->root
.type
= bfd_link_hash_defined
;
6386 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
6387 while (h
->root
.type
== bfd_link_hash_indirect
6388 || h
->root
.type
== bfd_link_hash_warning
)
6389 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6391 /* PR15323, ref flags aren't set for references in the same
6393 h
->root
.non_ir_ref
= 1;
6396 /* Could be done earlier, if h were already available. */
6397 bfd_r_type
= aarch64_tls_transition (abfd
, info
, r_type
, h
, r_symndx
);
6401 /* Create the ifunc sections for static executables. If we
6402 never see an indirect function symbol nor we are building
6403 a static executable, those sections will be empty and
6404 won't appear in output. */
6410 case BFD_RELOC_AARCH64_ADD_LO12
:
6411 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6412 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6413 case BFD_RELOC_AARCH64_CALL26
:
6414 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6415 case BFD_RELOC_AARCH64_JUMP26
:
6416 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6417 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6418 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6419 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6420 case BFD_RELOC_AARCH64_NN
:
6421 if (htab
->root
.dynobj
== NULL
)
6422 htab
->root
.dynobj
= abfd
;
6423 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
6428 /* It is referenced by a non-shared object. */
6430 h
->root
.non_ir_ref
= 1;
6435 case BFD_RELOC_AARCH64_NN
:
6437 /* We don't need to handle relocs into sections not going into
6438 the "real" output. */
6439 if ((sec
->flags
& SEC_ALLOC
) == 0)
6447 h
->plt
.refcount
+= 1;
6448 h
->pointer_equality_needed
= 1;
6451 /* No need to do anything if we're not creating a shared
6457 struct elf_dyn_relocs
*p
;
6458 struct elf_dyn_relocs
**head
;
6460 /* We must copy these reloc types into the output file.
6461 Create a reloc section in dynobj and make room for
6465 if (htab
->root
.dynobj
== NULL
)
6466 htab
->root
.dynobj
= abfd
;
6468 sreloc
= _bfd_elf_make_dynamic_reloc_section
6469 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ TRUE
);
6475 /* If this is a global symbol, we count the number of
6476 relocations we need for this symbol. */
6479 struct elf_aarch64_link_hash_entry
*eh
;
6480 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6481 head
= &eh
->dyn_relocs
;
6485 /* Track dynamic relocs needed for local syms too.
6486 We really need local syms available to do this
6492 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6497 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
6501 /* Beware of type punned pointers vs strict aliasing
6503 vpp
= &(elf_section_data (s
)->local_dynrel
);
6504 head
= (struct elf_dyn_relocs
**) vpp
;
6508 if (p
== NULL
|| p
->sec
!= sec
)
6510 bfd_size_type amt
= sizeof *p
;
6511 p
= ((struct elf_dyn_relocs
*)
6512 bfd_zalloc (htab
->root
.dynobj
, amt
));
6525 /* RR: We probably want to keep a consistency check that
6526 there are no dangling GOT_PAGE relocs. */
6527 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6528 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6529 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6530 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6531 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6532 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6533 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6534 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6535 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6536 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6537 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
6538 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6539 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6540 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6541 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6542 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6543 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6544 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6545 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6546 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6547 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6548 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6549 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
6550 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
6551 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
6552 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
6553 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
6554 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
6555 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
6556 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
6559 unsigned old_got_type
;
6561 got_type
= aarch64_reloc_got_type (bfd_r_type
);
6565 h
->got
.refcount
+= 1;
6566 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
6570 struct elf_aarch64_local_symbol
*locals
;
6572 if (!elfNN_aarch64_allocate_local_symbols
6573 (abfd
, symtab_hdr
->sh_info
))
6576 locals
= elf_aarch64_locals (abfd
);
6577 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
6578 locals
[r_symndx
].got_refcount
+= 1;
6579 old_got_type
= locals
[r_symndx
].got_type
;
6582 /* If a variable is accessed with both general dynamic TLS
6583 methods, two slots may be created. */
6584 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
6585 got_type
|= old_got_type
;
6587 /* We will already have issued an error message if there
6588 is a TLS/non-TLS mismatch, based on the symbol type.
6589 So just combine any TLS types needed. */
6590 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
6591 && got_type
!= GOT_NORMAL
)
6592 got_type
|= old_got_type
;
6594 /* If the symbol is accessed by both IE and GD methods, we
6595 are able to relax. Turn off the GD flag, without
6596 messing up with any other kind of TLS types that may be
6598 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
6599 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
6601 if (old_got_type
!= got_type
)
6604 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
6607 struct elf_aarch64_local_symbol
*locals
;
6608 locals
= elf_aarch64_locals (abfd
);
6609 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
6610 locals
[r_symndx
].got_type
= got_type
;
6614 if (htab
->root
.dynobj
== NULL
)
6615 htab
->root
.dynobj
= abfd
;
6616 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
6621 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6622 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6623 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6624 case BFD_RELOC_AARCH64_MOVW_G3
:
6627 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6628 (*_bfd_error_handler
)
6629 (_("%B: relocation %s against `%s' can not be used when making "
6630 "a shared object; recompile with -fPIC"),
6631 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
6632 (h
) ? h
->root
.root
.string
: "a local symbol");
6633 bfd_set_error (bfd_error_bad_value
);
6637 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6638 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6639 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6640 if (h
!= NULL
&& info
->executable
)
6642 /* If this reloc is in a read-only section, we might
6643 need a copy reloc. We can't check reliably at this
6644 stage whether the section is read-only, as input
6645 sections have not yet been mapped to output sections.
6646 Tentatively set the flag for now, and correct in
6647 adjust_dynamic_symbol. */
6649 h
->plt
.refcount
+= 1;
6650 h
->pointer_equality_needed
= 1;
6652 /* FIXME:: RR need to handle these in shared libraries
6653 and essentially bomb out as these being non-PIC
6654 relocations in shared libraries. */
6657 case BFD_RELOC_AARCH64_CALL26
:
6658 case BFD_RELOC_AARCH64_JUMP26
:
6659 /* If this is a local symbol then we resolve it
6660 directly without creating a PLT entry. */
6665 if (h
->plt
.refcount
<= 0)
6666 h
->plt
.refcount
= 1;
6668 h
->plt
.refcount
+= 1;
6679 /* Treat mapping symbols as special target symbols. */
6682 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
6685 return bfd_is_aarch64_special_symbol_name (sym
->name
,
6686 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
6689 /* This is a copy of elf_find_function () from elf.c except that
6690 AArch64 mapping symbols are ignored when looking for function names. */
6693 aarch64_elf_find_function (bfd
*abfd ATTRIBUTE_UNUSED
,
6697 const char **filename_ptr
,
6698 const char **functionname_ptr
)
6700 const char *filename
= NULL
;
6701 asymbol
*func
= NULL
;
6702 bfd_vma low_func
= 0;
6705 for (p
= symbols
; *p
!= NULL
; p
++)
6709 q
= (elf_symbol_type
*) * p
;
6711 switch (ELF_ST_TYPE (q
->internal_elf_sym
.st_info
))
6716 filename
= bfd_asymbol_name (&q
->symbol
);
6720 /* Skip mapping symbols. */
6721 if ((q
->symbol
.flags
& BSF_LOCAL
)
6722 && (bfd_is_aarch64_special_symbol_name
6723 (q
->symbol
.name
, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
)))
6726 if (bfd_get_section (&q
->symbol
) == section
6727 && q
->symbol
.value
>= low_func
&& q
->symbol
.value
<= offset
)
6729 func
= (asymbol
*) q
;
6730 low_func
= q
->symbol
.value
;
6740 *filename_ptr
= filename
;
6741 if (functionname_ptr
)
6742 *functionname_ptr
= bfd_asymbol_name (func
);
6748 /* Find the nearest line to a particular section and offset, for error
6749 reporting. This code is a duplicate of the code in elf.c, except
6750 that it uses aarch64_elf_find_function. */
6753 elfNN_aarch64_find_nearest_line (bfd
*abfd
,
6757 const char **filename_ptr
,
6758 const char **functionname_ptr
,
6759 unsigned int *line_ptr
,
6760 unsigned int *discriminator_ptr
)
6762 bfd_boolean found
= FALSE
;
6764 if (_bfd_dwarf2_find_nearest_line (abfd
, symbols
, NULL
, section
, offset
,
6765 filename_ptr
, functionname_ptr
,
6766 line_ptr
, discriminator_ptr
,
6767 dwarf_debug_sections
, 0,
6768 &elf_tdata (abfd
)->dwarf2_find_line_info
))
6770 if (!*functionname_ptr
)
6771 aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
6772 *filename_ptr
? NULL
: filename_ptr
,
6778 /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
6779 toolchain uses DWARF1. */
6781 if (!_bfd_stab_section_find_nearest_line (abfd
, symbols
, section
, offset
,
6782 &found
, filename_ptr
,
6783 functionname_ptr
, line_ptr
,
6784 &elf_tdata (abfd
)->line_info
))
6787 if (found
&& (*functionname_ptr
|| *line_ptr
))
6790 if (symbols
== NULL
)
6793 if (!aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
6794 filename_ptr
, functionname_ptr
))
6802 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
6803 const char **filename_ptr
,
6804 const char **functionname_ptr
,
6805 unsigned int *line_ptr
)
6808 found
= _bfd_dwarf2_find_inliner_info
6809 (abfd
, filename_ptr
,
6810 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
6816 elfNN_aarch64_post_process_headers (bfd
*abfd
,
6817 struct bfd_link_info
*link_info
)
6819 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
6821 i_ehdrp
= elf_elfheader (abfd
);
6822 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
6824 _bfd_elf_post_process_headers (abfd
, link_info
);
6827 static enum elf_reloc_type_class
6828 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
6829 const asection
*rel_sec ATTRIBUTE_UNUSED
,
6830 const Elf_Internal_Rela
*rela
)
6832 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
6834 case AARCH64_R (RELATIVE
):
6835 return reloc_class_relative
;
6836 case AARCH64_R (JUMP_SLOT
):
6837 return reloc_class_plt
;
6838 case AARCH64_R (COPY
):
6839 return reloc_class_copy
;
6841 return reloc_class_normal
;
6845 /* Handle an AArch64 specific section when reading an object file. This is
6846 called when bfd_section_from_shdr finds a section with an unknown
6850 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
6851 Elf_Internal_Shdr
*hdr
,
6852 const char *name
, int shindex
)
6854 /* There ought to be a place to keep ELF backend specific flags, but
6855 at the moment there isn't one. We just keep track of the
6856 sections by their name, instead. Fortunately, the ABI gives
6857 names for all the AArch64 specific sections, so we will probably get
6859 switch (hdr
->sh_type
)
6861 case SHT_AARCH64_ATTRIBUTES
:
6868 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
6874 /* A structure used to record a list of sections, independently
6875 of the next and prev fields in the asection structure. */
6876 typedef struct section_list
6879 struct section_list
*next
;
6880 struct section_list
*prev
;
6884 /* Unfortunately we need to keep a list of sections for which
6885 an _aarch64_elf_section_data structure has been allocated. This
6886 is because it is possible for functions like elfNN_aarch64_write_section
6887 to be called on a section which has had an elf_data_structure
6888 allocated for it (and so the used_by_bfd field is valid) but
6889 for which the AArch64 extended version of this structure - the
6890 _aarch64_elf_section_data structure - has not been allocated. */
6891 static section_list
*sections_with_aarch64_elf_section_data
= NULL
;
6894 record_section_with_aarch64_elf_section_data (asection
*sec
)
6896 struct section_list
*entry
;
6898 entry
= bfd_malloc (sizeof (*entry
));
6902 entry
->next
= sections_with_aarch64_elf_section_data
;
6904 if (entry
->next
!= NULL
)
6905 entry
->next
->prev
= entry
;
6906 sections_with_aarch64_elf_section_data
= entry
;
6909 static struct section_list
*
6910 find_aarch64_elf_section_entry (asection
*sec
)
6912 struct section_list
*entry
;
6913 static struct section_list
*last_entry
= NULL
;
6915 /* This is a short cut for the typical case where the sections are added
6916 to the sections_with_aarch64_elf_section_data list in forward order and
6917 then looked up here in backwards order. This makes a real difference
6918 to the ld-srec/sec64k.exp linker test. */
6919 entry
= sections_with_aarch64_elf_section_data
;
6920 if (last_entry
!= NULL
)
6922 if (last_entry
->sec
== sec
)
6924 else if (last_entry
->next
!= NULL
&& last_entry
->next
->sec
== sec
)
6925 entry
= last_entry
->next
;
6928 for (; entry
; entry
= entry
->next
)
6929 if (entry
->sec
== sec
)
6933 /* Record the entry prior to this one - it is the entry we are
6934 most likely to want to locate next time. Also this way if we
6935 have been called from
6936 unrecord_section_with_aarch64_elf_section_data () we will not
6937 be caching a pointer that is about to be freed. */
6938 last_entry
= entry
->prev
;
6944 unrecord_section_with_aarch64_elf_section_data (asection
*sec
)
6946 struct section_list
*entry
;
6948 entry
= find_aarch64_elf_section_entry (sec
);
6952 if (entry
->prev
!= NULL
)
6953 entry
->prev
->next
= entry
->next
;
6954 if (entry
->next
!= NULL
)
6955 entry
->next
->prev
= entry
->prev
;
6956 if (entry
== sections_with_aarch64_elf_section_data
)
6957 sections_with_aarch64_elf_section_data
= entry
->next
;
6966 struct bfd_link_info
*info
;
6969 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
6970 asection
*, struct elf_link_hash_entry
*);
6971 } output_arch_syminfo
;
6973 enum map_symbol_type
6980 /* Output a single mapping symbol. */
6983 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
6984 enum map_symbol_type type
, bfd_vma offset
)
6986 static const char *names
[2] = { "$x", "$d" };
6987 Elf_Internal_Sym sym
;
6989 sym
.st_value
= (osi
->sec
->output_section
->vma
6990 + osi
->sec
->output_offset
+ offset
);
6993 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
6994 sym
.st_shndx
= osi
->sec_shndx
;
6995 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
7000 /* Output mapping symbols for PLT entries associated with H. */
7003 elfNN_aarch64_output_plt_map (struct elf_link_hash_entry
*h
, void *inf
)
7005 output_arch_syminfo
*osi
= (output_arch_syminfo
*) inf
;
7008 if (h
->root
.type
== bfd_link_hash_indirect
)
7011 if (h
->root
.type
== bfd_link_hash_warning
)
7012 /* When warning symbols are created, they **replace** the "real"
7013 entry in the hash table, thus we never get to see the real
7014 symbol in a hash traversal. So look at it now. */
7015 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7017 if (h
->plt
.offset
== (bfd_vma
) - 1)
7020 addr
= h
->plt
.offset
;
7023 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7030 /* Output a single local symbol for a generated stub. */
7033 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
7034 bfd_vma offset
, bfd_vma size
)
7036 Elf_Internal_Sym sym
;
7038 sym
.st_value
= (osi
->sec
->output_section
->vma
7039 + osi
->sec
->output_offset
+ offset
);
7042 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
7043 sym
.st_shndx
= osi
->sec_shndx
;
7044 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
7048 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
7050 struct elf_aarch64_stub_hash_entry
*stub_entry
;
7054 output_arch_syminfo
*osi
;
7056 /* Massage our args to the form they really have. */
7057 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
7058 osi
= (output_arch_syminfo
*) in_arg
;
7060 stub_sec
= stub_entry
->stub_sec
;
7062 /* Ensure this stub is attached to the current section being
7064 if (stub_sec
!= osi
->sec
)
7067 addr
= (bfd_vma
) stub_entry
->stub_offset
;
7069 stub_name
= stub_entry
->output_name
;
7071 switch (stub_entry
->stub_type
)
7073 case aarch64_stub_adrp_branch
:
7074 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7075 sizeof (aarch64_adrp_branch_stub
)))
7077 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7080 case aarch64_stub_long_branch
:
7081 if (!elfNN_aarch64_output_stub_sym
7082 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
7084 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7086 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
7089 case aarch64_stub_erratum_835769_veneer
:
7090 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7091 sizeof (aarch64_erratum_835769_stub
)))
7093 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7096 case aarch64_stub_erratum_843419_veneer
:
7097 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7098 sizeof (aarch64_erratum_843419_stub
)))
7100 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7111 /* Output mapping symbols for linker generated sections. */
7114 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
7115 struct bfd_link_info
*info
,
7117 int (*func
) (void *, const char *,
7120 struct elf_link_hash_entry
7123 output_arch_syminfo osi
;
7124 struct elf_aarch64_link_hash_table
*htab
;
7126 htab
= elf_aarch64_hash_table (info
);
7132 /* Long calls stubs. */
7133 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
7137 for (stub_sec
= htab
->stub_bfd
->sections
;
7138 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
7140 /* Ignore non-stub sections. */
7141 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
7146 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
7147 (output_bfd
, osi
.sec
->output_section
);
7149 /* The first instruction in a stub is always a branch. */
7150 if (!elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0))
7153 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
7158 /* Finally, output mapping symbols for the PLT. */
7159 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
7162 /* For now live without mapping symbols for the plt. */
7163 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
7164 (output_bfd
, htab
->root
.splt
->output_section
);
7165 osi
.sec
= htab
->root
.splt
;
7167 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_output_plt_map
,
7174 /* Allocate target specific section data. */
7177 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
7179 if (!sec
->used_by_bfd
)
7181 _aarch64_elf_section_data
*sdata
;
7182 bfd_size_type amt
= sizeof (*sdata
);
7184 sdata
= bfd_zalloc (abfd
, amt
);
7187 sec
->used_by_bfd
= sdata
;
7190 record_section_with_aarch64_elf_section_data (sec
);
7192 return _bfd_elf_new_section_hook (abfd
, sec
);
7197 unrecord_section_via_map_over_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
7199 void *ignore ATTRIBUTE_UNUSED
)
7201 unrecord_section_with_aarch64_elf_section_data (sec
);
7205 elfNN_aarch64_close_and_cleanup (bfd
*abfd
)
7208 bfd_map_over_sections (abfd
,
7209 unrecord_section_via_map_over_sections
, NULL
);
7211 return _bfd_elf_close_and_cleanup (abfd
);
7215 elfNN_aarch64_bfd_free_cached_info (bfd
*abfd
)
7218 bfd_map_over_sections (abfd
,
7219 unrecord_section_via_map_over_sections
, NULL
);
7221 return _bfd_free_cached_info (abfd
);
7224 /* Create dynamic sections. This is different from the ARM backend in that
7225 the got, plt, gotplt and their relocation sections are all created in the
7226 standard part of the bfd elf backend. */
7229 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
7230 struct bfd_link_info
*info
)
7232 struct elf_aarch64_link_hash_table
*htab
;
7234 /* We need to create .got section. */
7235 if (!aarch64_elf_create_got_section (dynobj
, info
))
7238 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
7241 htab
= elf_aarch64_hash_table (info
);
7242 htab
->sdynbss
= bfd_get_linker_section (dynobj
, ".dynbss");
7244 htab
->srelbss
= bfd_get_linker_section (dynobj
, ".rela.bss");
7246 if (!htab
->sdynbss
|| (!info
->shared
&& !htab
->srelbss
))
7253 /* Allocate space in .plt, .got and associated reloc sections for
7257 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
7259 struct bfd_link_info
*info
;
7260 struct elf_aarch64_link_hash_table
*htab
;
7261 struct elf_aarch64_link_hash_entry
*eh
;
7262 struct elf_dyn_relocs
*p
;
7264 /* An example of a bfd_link_hash_indirect symbol is versioned
7265 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7266 -> __gxx_personality_v0(bfd_link_hash_defined)
7268 There is no need to process bfd_link_hash_indirect symbols here
7269 because we will also be presented with the concrete instance of
7270 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7271 called to copy all relevant data from the generic to the concrete
7274 if (h
->root
.type
== bfd_link_hash_indirect
)
7277 if (h
->root
.type
== bfd_link_hash_warning
)
7278 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7280 info
= (struct bfd_link_info
*) inf
;
7281 htab
= elf_aarch64_hash_table (info
);
7283 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7284 here if it is defined and referenced in a non-shared object. */
7285 if (h
->type
== STT_GNU_IFUNC
7288 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
7290 /* Make sure this symbol is output as a dynamic symbol.
7291 Undefined weak syms won't yet be marked as dynamic. */
7292 if (h
->dynindx
== -1 && !h
->forced_local
)
7294 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
7298 if (info
->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
7300 asection
*s
= htab
->root
.splt
;
7302 /* If this is the first .plt entry, make room for the special
7305 s
->size
+= htab
->plt_header_size
;
7307 h
->plt
.offset
= s
->size
;
7309 /* If this symbol is not defined in a regular file, and we are
7310 not generating a shared library, then set the symbol to this
7311 location in the .plt. This is required to make function
7312 pointers compare as equal between the normal executable and
7313 the shared library. */
7314 if (!info
->shared
&& !h
->def_regular
)
7316 h
->root
.u
.def
.section
= s
;
7317 h
->root
.u
.def
.value
= h
->plt
.offset
;
7320 /* Make room for this entry. For now we only create the
7321 small model PLT entries. We later need to find a way
7322 of relaxing into these from the large model PLT entries. */
7323 s
->size
+= PLT_SMALL_ENTRY_SIZE
;
7325 /* We also need to make an entry in the .got.plt section, which
7326 will be placed in the .got section by the linker script. */
7327 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
;
7329 /* We also need to make an entry in the .rela.plt section. */
7330 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7332 /* We need to ensure that all GOT entries that serve the PLT
7333 are consecutive with the special GOT slots [0] [1] and
7334 [2]. Any addtional relocations, such as
7335 R_AARCH64_TLSDESC, must be placed after the PLT related
7336 entries. We abuse the reloc_count such that during
7337 sizing we adjust reloc_count to indicate the number of
7338 PLT related reserved entries. In subsequent phases when
7339 filling in the contents of the reloc entries, PLT related
7340 entries are placed by computing their PLT index (0
7341 .. reloc_count). While other none PLT relocs are placed
7342 at the slot indicated by reloc_count and reloc_count is
7345 htab
->root
.srelplt
->reloc_count
++;
7349 h
->plt
.offset
= (bfd_vma
) - 1;
7355 h
->plt
.offset
= (bfd_vma
) - 1;
7359 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7360 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
7362 if (h
->got
.refcount
> 0)
7365 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
7367 h
->got
.offset
= (bfd_vma
) - 1;
7369 dyn
= htab
->root
.dynamic_sections_created
;
7371 /* Make sure this symbol is output as a dynamic symbol.
7372 Undefined weak syms won't yet be marked as dynamic. */
7373 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
)
7375 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
7379 if (got_type
== GOT_UNKNOWN
)
7382 else if (got_type
== GOT_NORMAL
)
7384 h
->got
.offset
= htab
->root
.sgot
->size
;
7385 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7386 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7387 || h
->root
.type
!= bfd_link_hash_undefweak
)
7389 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
7391 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7397 if (got_type
& GOT_TLSDESC_GD
)
7399 eh
->tlsdesc_got_jump_table_offset
=
7400 (htab
->root
.sgotplt
->size
7401 - aarch64_compute_jump_table_size (htab
));
7402 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
7403 h
->got
.offset
= (bfd_vma
) - 2;
7406 if (got_type
& GOT_TLS_GD
)
7408 h
->got
.offset
= htab
->root
.sgot
->size
;
7409 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
7412 if (got_type
& GOT_TLS_IE
)
7414 h
->got
.offset
= htab
->root
.sgot
->size
;
7415 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7418 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
7419 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7420 || h
->root
.type
!= bfd_link_hash_undefweak
)
7423 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
7425 if (got_type
& GOT_TLSDESC_GD
)
7427 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7428 /* Note reloc_count not incremented here! We have
7429 already adjusted reloc_count for this relocation
7432 /* TLSDESC PLT is now needed, but not yet determined. */
7433 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
7436 if (got_type
& GOT_TLS_GD
)
7437 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
7439 if (got_type
& GOT_TLS_IE
)
7440 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7446 h
->got
.offset
= (bfd_vma
) - 1;
7449 if (eh
->dyn_relocs
== NULL
)
7452 /* In the shared -Bsymbolic case, discard space allocated for
7453 dynamic pc-relative relocs against symbols which turn out to be
7454 defined in regular objects. For the normal shared case, discard
7455 space for pc-relative relocs that have become local due to symbol
7456 visibility changes. */
7460 /* Relocs that use pc_count are those that appear on a call
7461 insn, or certain REL relocs that can generated via assembly.
7462 We want calls to protected symbols to resolve directly to the
7463 function rather than going via the plt. If people want
7464 function pointer comparisons to work as expected then they
7465 should avoid writing weird assembly. */
7466 if (SYMBOL_CALLS_LOCAL (info
, h
))
7468 struct elf_dyn_relocs
**pp
;
7470 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
;)
7472 p
->count
-= p
->pc_count
;
7481 /* Also discard relocs on undefined weak syms with non-default
7483 if (eh
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
7485 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
7486 eh
->dyn_relocs
= NULL
;
7488 /* Make sure undefined weak symbols are output as a dynamic
7490 else if (h
->dynindx
== -1
7492 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
7497 else if (ELIMINATE_COPY_RELOCS
)
7499 /* For the non-shared case, discard space for relocs against
7500 symbols which turn out to need copy relocs or are not
7506 || (htab
->root
.dynamic_sections_created
7507 && (h
->root
.type
== bfd_link_hash_undefweak
7508 || h
->root
.type
== bfd_link_hash_undefined
))))
7510 /* Make sure this symbol is output as a dynamic symbol.
7511 Undefined weak syms won't yet be marked as dynamic. */
7512 if (h
->dynindx
== -1
7514 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
7517 /* If that succeeded, we know we'll be keeping all the
7519 if (h
->dynindx
!= -1)
7523 eh
->dyn_relocs
= NULL
;
7528 /* Finally, allocate space. */
7529 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
7533 sreloc
= elf_section_data (p
->sec
)->sreloc
;
7535 BFD_ASSERT (sreloc
!= NULL
);
7537 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
7543 /* Allocate space in .plt, .got and associated reloc sections for
7544 ifunc dynamic relocs. */
7547 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
7550 struct bfd_link_info
*info
;
7551 struct elf_aarch64_link_hash_table
*htab
;
7552 struct elf_aarch64_link_hash_entry
*eh
;
7554 /* An example of a bfd_link_hash_indirect symbol is versioned
7555 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7556 -> __gxx_personality_v0(bfd_link_hash_defined)
7558 There is no need to process bfd_link_hash_indirect symbols here
7559 because we will also be presented with the concrete instance of
7560 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7561 called to copy all relevant data from the generic to the concrete
7564 if (h
->root
.type
== bfd_link_hash_indirect
)
7567 if (h
->root
.type
== bfd_link_hash_warning
)
7568 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7570 info
= (struct bfd_link_info
*) inf
;
7571 htab
= elf_aarch64_hash_table (info
);
7573 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7575 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7576 here if it is defined and referenced in a non-shared object. */
7577 if (h
->type
== STT_GNU_IFUNC
7579 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
7581 htab
->plt_entry_size
,
7582 htab
->plt_header_size
,
7587 /* Allocate space in .plt, .got and associated reloc sections for
7588 local dynamic relocs. */
7591 elfNN_aarch64_allocate_local_dynrelocs (void **slot
, void *inf
)
7593 struct elf_link_hash_entry
*h
7594 = (struct elf_link_hash_entry
*) *slot
;
7596 if (h
->type
!= STT_GNU_IFUNC
7600 || h
->root
.type
!= bfd_link_hash_defined
)
7603 return elfNN_aarch64_allocate_dynrelocs (h
, inf
);
7606 /* Allocate space in .plt, .got and associated reloc sections for
7607 local ifunc dynamic relocs. */
7610 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
7612 struct elf_link_hash_entry
*h
7613 = (struct elf_link_hash_entry
*) *slot
;
7615 if (h
->type
!= STT_GNU_IFUNC
7619 || h
->root
.type
!= bfd_link_hash_defined
)
7622 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
7625 /* Find any dynamic relocs that apply to read-only sections. */
7628 aarch64_readonly_dynrelocs (struct elf_link_hash_entry
* h
, void * inf
)
7630 struct elf_aarch64_link_hash_entry
* eh
;
7631 struct elf_dyn_relocs
* p
;
7633 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7634 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
7636 asection
*s
= p
->sec
;
7638 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
7640 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
7642 info
->flags
|= DF_TEXTREL
;
7644 /* Not an error, just cut short the traversal. */
7651 /* This is the most important function of all . Innocuosly named
7654 elfNN_aarch64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
7655 struct bfd_link_info
*info
)
7657 struct elf_aarch64_link_hash_table
*htab
;
7663 htab
= elf_aarch64_hash_table ((info
));
7664 dynobj
= htab
->root
.dynobj
;
7666 BFD_ASSERT (dynobj
!= NULL
);
7668 if (htab
->root
.dynamic_sections_created
)
7670 if (info
->executable
)
7672 s
= bfd_get_linker_section (dynobj
, ".interp");
7675 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
7676 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
7680 /* Set up .got offsets for local syms, and space for local dynamic
7682 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
7684 struct elf_aarch64_local_symbol
*locals
= NULL
;
7685 Elf_Internal_Shdr
*symtab_hdr
;
7689 if (!is_aarch64_elf (ibfd
))
7692 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
7694 struct elf_dyn_relocs
*p
;
7696 for (p
= (struct elf_dyn_relocs
*)
7697 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
7699 if (!bfd_is_abs_section (p
->sec
)
7700 && bfd_is_abs_section (p
->sec
->output_section
))
7702 /* Input section has been discarded, either because
7703 it is a copy of a linkonce section or due to
7704 linker script /DISCARD/, so we'll be discarding
7707 else if (p
->count
!= 0)
7709 srel
= elf_section_data (p
->sec
)->sreloc
;
7710 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
7711 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
7712 info
->flags
|= DF_TEXTREL
;
7717 locals
= elf_aarch64_locals (ibfd
);
7721 symtab_hdr
= &elf_symtab_hdr (ibfd
);
7722 srel
= htab
->root
.srelgot
;
7723 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
7725 locals
[i
].got_offset
= (bfd_vma
) - 1;
7726 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
7727 if (locals
[i
].got_refcount
> 0)
7729 unsigned got_type
= locals
[i
].got_type
;
7730 if (got_type
& GOT_TLSDESC_GD
)
7732 locals
[i
].tlsdesc_got_jump_table_offset
=
7733 (htab
->root
.sgotplt
->size
7734 - aarch64_compute_jump_table_size (htab
));
7735 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
7736 locals
[i
].got_offset
= (bfd_vma
) - 2;
7739 if (got_type
& GOT_TLS_GD
)
7741 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
7742 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
7745 if (got_type
& GOT_TLS_IE
7746 || got_type
& GOT_NORMAL
)
7748 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
7749 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7752 if (got_type
== GOT_UNKNOWN
)
7758 if (got_type
& GOT_TLSDESC_GD
)
7760 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7761 /* Note RELOC_COUNT not incremented here! */
7762 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
7765 if (got_type
& GOT_TLS_GD
)
7766 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
7768 if (got_type
& GOT_TLS_IE
7769 || got_type
& GOT_NORMAL
)
7770 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7775 locals
[i
].got_refcount
= (bfd_vma
) - 1;
7781 /* Allocate global sym .plt and .got entries, and space for global
7782 sym dynamic relocs. */
7783 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
7786 /* Allocate global ifunc sym .plt and .got entries, and space for global
7787 ifunc sym dynamic relocs. */
7788 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
7791 /* Allocate .plt and .got entries, and space for local symbols. */
7792 htab_traverse (htab
->loc_hash_table
,
7793 elfNN_aarch64_allocate_local_dynrelocs
,
7796 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
7797 htab_traverse (htab
->loc_hash_table
,
7798 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
7801 /* For every jump slot reserved in the sgotplt, reloc_count is
7802 incremented. However, when we reserve space for TLS descriptors,
7803 it's not incremented, so in order to compute the space reserved
7804 for them, it suffices to multiply the reloc count by the jump
7807 if (htab
->root
.srelplt
)
7808 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
7810 if (htab
->tlsdesc_plt
)
7812 if (htab
->root
.splt
->size
== 0)
7813 htab
->root
.splt
->size
+= PLT_ENTRY_SIZE
;
7815 htab
->tlsdesc_plt
= htab
->root
.splt
->size
;
7816 htab
->root
.splt
->size
+= PLT_TLSDESC_ENTRY_SIZE
;
7818 /* If we're not using lazy TLS relocations, don't generate the
7819 GOT entry required. */
7820 if (!(info
->flags
& DF_BIND_NOW
))
7822 htab
->dt_tlsdesc_got
= htab
->root
.sgot
->size
;
7823 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7827 /* Init mapping symbols information to use later to distingush between
7828 code and data while scanning for errata. */
7829 if (htab
->fix_erratum_835769
|| htab
->fix_erratum_843419
)
7830 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
7832 if (!is_aarch64_elf (ibfd
))
7834 bfd_elfNN_aarch64_init_maps (ibfd
);
7837 /* We now have determined the sizes of the various dynamic sections.
7838 Allocate memory for them. */
7840 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
7842 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
7845 if (s
== htab
->root
.splt
7846 || s
== htab
->root
.sgot
7847 || s
== htab
->root
.sgotplt
7848 || s
== htab
->root
.iplt
7849 || s
== htab
->root
.igotplt
|| s
== htab
->sdynbss
)
7851 /* Strip this section if we don't need it; see the
7854 else if (CONST_STRNEQ (bfd_get_section_name (dynobj
, s
), ".rela"))
7856 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
7859 /* We use the reloc_count field as a counter if we need
7860 to copy relocs into the output file. */
7861 if (s
!= htab
->root
.srelplt
)
7866 /* It's not one of our sections, so don't allocate space. */
7872 /* If we don't need this section, strip it from the
7873 output file. This is mostly to handle .rela.bss and
7874 .rela.plt. We must create both sections in
7875 create_dynamic_sections, because they must be created
7876 before the linker maps input sections to output
7877 sections. The linker does that before
7878 adjust_dynamic_symbol is called, and it is that
7879 function which decides whether anything needs to go
7880 into these sections. */
7882 s
->flags
|= SEC_EXCLUDE
;
7886 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
7889 /* Allocate memory for the section contents. We use bfd_zalloc
7890 here in case unused entries are not reclaimed before the
7891 section's contents are written out. This should not happen,
7892 but this way if it does, we get a R_AARCH64_NONE reloc instead
7894 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
7895 if (s
->contents
== NULL
)
7899 if (htab
->root
.dynamic_sections_created
)
7901 /* Add some entries to the .dynamic section. We fill in the
7902 values later, in elfNN_aarch64_finish_dynamic_sections, but we
7903 must add the entries now so that we get the correct size for
7904 the .dynamic section. The DT_DEBUG entry is filled in by the
7905 dynamic linker and used by the debugger. */
7906 #define add_dynamic_entry(TAG, VAL) \
7907 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
7909 if (info
->executable
)
7911 if (!add_dynamic_entry (DT_DEBUG
, 0))
7915 if (htab
->root
.splt
->size
!= 0)
7917 if (!add_dynamic_entry (DT_PLTGOT
, 0)
7918 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
7919 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
7920 || !add_dynamic_entry (DT_JMPREL
, 0))
7923 if (htab
->tlsdesc_plt
7924 && (!add_dynamic_entry (DT_TLSDESC_PLT
, 0)
7925 || !add_dynamic_entry (DT_TLSDESC_GOT
, 0)))
7931 if (!add_dynamic_entry (DT_RELA
, 0)
7932 || !add_dynamic_entry (DT_RELASZ
, 0)
7933 || !add_dynamic_entry (DT_RELAENT
, RELOC_SIZE (htab
)))
7936 /* If any dynamic relocs apply to a read-only section,
7937 then we need a DT_TEXTREL entry. */
7938 if ((info
->flags
& DF_TEXTREL
) == 0)
7939 elf_link_hash_traverse (& htab
->root
, aarch64_readonly_dynrelocs
,
7942 if ((info
->flags
& DF_TEXTREL
) != 0)
7944 if (!add_dynamic_entry (DT_TEXTREL
, 0))
7949 #undef add_dynamic_entry
7955 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
7956 bfd_reloc_code_real_type r_type
,
7957 bfd_byte
*plt_entry
, bfd_vma value
)
7959 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
7961 _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
7965 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
7966 struct elf_aarch64_link_hash_table
7967 *htab
, bfd
*output_bfd
,
7968 struct bfd_link_info
*info
)
7970 bfd_byte
*plt_entry
;
7973 bfd_vma gotplt_entry_address
;
7974 bfd_vma plt_entry_address
;
7975 Elf_Internal_Rela rela
;
7977 asection
*plt
, *gotplt
, *relplt
;
7979 /* When building a static executable, use .iplt, .igot.plt and
7980 .rela.iplt sections for STT_GNU_IFUNC symbols. */
7981 if (htab
->root
.splt
!= NULL
)
7983 plt
= htab
->root
.splt
;
7984 gotplt
= htab
->root
.sgotplt
;
7985 relplt
= htab
->root
.srelplt
;
7989 plt
= htab
->root
.iplt
;
7990 gotplt
= htab
->root
.igotplt
;
7991 relplt
= htab
->root
.irelplt
;
7994 /* Get the index in the procedure linkage table which
7995 corresponds to this symbol. This is the index of this symbol
7996 in all the symbols for which we are making plt entries. The
7997 first entry in the procedure linkage table is reserved.
7999 Get the offset into the .got table of the entry that
8000 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
8001 bytes. The first three are reserved for the dynamic linker.
8003 For static executables, we don't reserve anything. */
8005 if (plt
== htab
->root
.splt
)
8007 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
8008 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
8012 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
8013 got_offset
= plt_index
* GOT_ENTRY_SIZE
;
8016 plt_entry
= plt
->contents
+ h
->plt
.offset
;
8017 plt_entry_address
= plt
->output_section
->vma
8018 + plt
->output_offset
+ h
->plt
.offset
;
8019 gotplt_entry_address
= gotplt
->output_section
->vma
+
8020 gotplt
->output_offset
+ got_offset
;
8022 /* Copy in the boiler-plate for the PLTn entry. */
8023 memcpy (plt_entry
, elfNN_aarch64_small_plt_entry
, PLT_SMALL_ENTRY_SIZE
);
8025 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8026 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8027 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8029 PG (gotplt_entry_address
) -
8030 PG (plt_entry_address
));
8032 /* Fill in the lo12 bits for the load from the pltgot. */
8033 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
8035 PG_OFFSET (gotplt_entry_address
));
8037 /* Fill in the lo12 bits for the add from the pltgot entry. */
8038 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
8040 PG_OFFSET (gotplt_entry_address
));
8042 /* All the GOTPLT Entries are essentially initialized to PLT0. */
8043 bfd_put_NN (output_bfd
,
8044 plt
->output_section
->vma
+ plt
->output_offset
,
8045 gotplt
->contents
+ got_offset
);
8047 rela
.r_offset
= gotplt_entry_address
;
8049 if (h
->dynindx
== -1
8050 || ((info
->executable
8051 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
8053 && h
->type
== STT_GNU_IFUNC
))
8055 /* If an STT_GNU_IFUNC symbol is locally defined, generate
8056 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
8057 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
8058 rela
.r_addend
= (h
->root
.u
.def
.value
8059 + h
->root
.u
.def
.section
->output_section
->vma
8060 + h
->root
.u
.def
.section
->output_offset
);
8064 /* Fill in the entry in the .rela.plt section. */
8065 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
));
8069 /* Compute the relocation entry to used based on PLT index and do
8070 not adjust reloc_count. The reloc_count has already been adjusted
8071 to account for this entry. */
8072 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
8073 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8076 /* Size sections even though they're not dynamic. We use it to setup
8077 _TLS_MODULE_BASE_, if needed. */
8080 elfNN_aarch64_always_size_sections (bfd
*output_bfd
,
8081 struct bfd_link_info
*info
)
8085 if (info
->relocatable
)
8088 tls_sec
= elf_hash_table (info
)->tls_sec
;
8092 struct elf_link_hash_entry
*tlsbase
;
8094 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
8095 "_TLS_MODULE_BASE_", TRUE
, TRUE
, FALSE
);
8099 struct bfd_link_hash_entry
*h
= NULL
;
8100 const struct elf_backend_data
*bed
=
8101 get_elf_backend_data (output_bfd
);
8103 if (!(_bfd_generic_link_add_one_symbol
8104 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
8105 tls_sec
, 0, NULL
, FALSE
, bed
->collect
, &h
)))
8108 tlsbase
->type
= STT_TLS
;
8109 tlsbase
= (struct elf_link_hash_entry
*) h
;
8110 tlsbase
->def_regular
= 1;
8111 tlsbase
->other
= STV_HIDDEN
;
8112 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, TRUE
);
8119 /* Finish up dynamic symbol handling. We set the contents of various
8120 dynamic sections here. */
8122 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
8123 struct bfd_link_info
*info
,
8124 struct elf_link_hash_entry
*h
,
8125 Elf_Internal_Sym
*sym
)
8127 struct elf_aarch64_link_hash_table
*htab
;
8128 htab
= elf_aarch64_hash_table (info
);
8130 if (h
->plt
.offset
!= (bfd_vma
) - 1)
8132 asection
*plt
, *gotplt
, *relplt
;
8134 /* This symbol has an entry in the procedure linkage table. Set
8137 /* When building a static executable, use .iplt, .igot.plt and
8138 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8139 if (htab
->root
.splt
!= NULL
)
8141 plt
= htab
->root
.splt
;
8142 gotplt
= htab
->root
.sgotplt
;
8143 relplt
= htab
->root
.srelplt
;
8147 plt
= htab
->root
.iplt
;
8148 gotplt
= htab
->root
.igotplt
;
8149 relplt
= htab
->root
.irelplt
;
8152 /* This symbol has an entry in the procedure linkage table. Set
8154 if ((h
->dynindx
== -1
8155 && !((h
->forced_local
|| info
->executable
)
8157 && h
->type
== STT_GNU_IFUNC
))
8163 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
8164 if (!h
->def_regular
)
8166 /* Mark the symbol as undefined, rather than as defined in
8167 the .plt section. */
8168 sym
->st_shndx
= SHN_UNDEF
;
8169 /* If the symbol is weak we need to clear the value.
8170 Otherwise, the PLT entry would provide a definition for
8171 the symbol even if the symbol wasn't defined anywhere,
8172 and so the symbol would never be NULL. Leave the value if
8173 there were any relocations where pointer equality matters
8174 (this is a clue for the dynamic linker, to make function
8175 pointer comparisons work between an application and shared
8177 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
8182 if (h
->got
.offset
!= (bfd_vma
) - 1
8183 && elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
)
8185 Elf_Internal_Rela rela
;
8188 /* This symbol has an entry in the global offset table. Set it
8190 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
8193 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
8194 + htab
->root
.sgot
->output_offset
8195 + (h
->got
.offset
& ~(bfd_vma
) 1));
8198 && h
->type
== STT_GNU_IFUNC
)
8202 /* Generate R_AARCH64_GLOB_DAT. */
8209 if (!h
->pointer_equality_needed
)
8212 /* For non-shared object, we can't use .got.plt, which
8213 contains the real function address if we need pointer
8214 equality. We load the GOT entry with the PLT entry. */
8215 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
8216 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
8217 + plt
->output_offset
8219 htab
->root
.sgot
->contents
8220 + (h
->got
.offset
& ~(bfd_vma
) 1));
8224 else if (info
->shared
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
8226 if (!h
->def_regular
)
8229 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
8230 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
8231 rela
.r_addend
= (h
->root
.u
.def
.value
8232 + h
->root
.u
.def
.section
->output_section
->vma
8233 + h
->root
.u
.def
.section
->output_offset
);
8238 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
8239 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8240 htab
->root
.sgot
->contents
+ h
->got
.offset
);
8241 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (GLOB_DAT
));
8245 loc
= htab
->root
.srelgot
->contents
;
8246 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
8247 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8252 Elf_Internal_Rela rela
;
8255 /* This symbol needs a copy reloc. Set it up. */
8257 if (h
->dynindx
== -1
8258 || (h
->root
.type
!= bfd_link_hash_defined
8259 && h
->root
.type
!= bfd_link_hash_defweak
)
8260 || htab
->srelbss
== NULL
)
8263 rela
.r_offset
= (h
->root
.u
.def
.value
8264 + h
->root
.u
.def
.section
->output_section
->vma
8265 + h
->root
.u
.def
.section
->output_offset
);
8266 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
8268 loc
= htab
->srelbss
->contents
;
8269 loc
+= htab
->srelbss
->reloc_count
++ * RELOC_SIZE (htab
);
8270 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8273 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
8274 be NULL for local symbols. */
8276 && (h
== elf_hash_table (info
)->hdynamic
8277 || h
== elf_hash_table (info
)->hgot
))
8278 sym
->st_shndx
= SHN_ABS
;
8283 /* Finish up local dynamic symbol handling. We set the contents of
8284 various dynamic sections here. */
8287 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
8289 struct elf_link_hash_entry
*h
8290 = (struct elf_link_hash_entry
*) *slot
;
8291 struct bfd_link_info
*info
8292 = (struct bfd_link_info
*) inf
;
8294 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
8299 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
8300 struct elf_aarch64_link_hash_table
8303 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
8304 small and large plts and at the minute just generates
8307 /* PLT0 of the small PLT looks like this in ELF64 -
8308 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
8309 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
8310 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
8312 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
8313 // GOTPLT entry for this.
8315 PLT0 will be slightly different in ELF32 due to different got entry
8318 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
8322 memcpy (htab
->root
.splt
->contents
, elfNN_aarch64_small_plt0_entry
,
8324 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
=
8327 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
8328 + htab
->root
.sgotplt
->output_offset
8329 + GOT_ENTRY_SIZE
* 2);
8331 plt_base
= htab
->root
.splt
->output_section
->vma
+
8332 htab
->root
.splt
->output_offset
;
8334 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8335 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8336 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8337 htab
->root
.splt
->contents
+ 4,
8338 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
8340 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
8341 htab
->root
.splt
->contents
+ 8,
8342 PG_OFFSET (plt_got_2nd_ent
));
8344 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
8345 htab
->root
.splt
->contents
+ 12,
8346 PG_OFFSET (plt_got_2nd_ent
));
8350 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
8351 struct bfd_link_info
*info
)
8353 struct elf_aarch64_link_hash_table
*htab
;
8357 htab
= elf_aarch64_hash_table (info
);
8358 dynobj
= htab
->root
.dynobj
;
8359 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
8361 if (htab
->root
.dynamic_sections_created
)
8363 ElfNN_External_Dyn
*dyncon
, *dynconend
;
8365 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
8368 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
8369 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
8370 for (; dyncon
< dynconend
; dyncon
++)
8372 Elf_Internal_Dyn dyn
;
8375 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
8383 s
= htab
->root
.sgotplt
;
8384 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
8388 dyn
.d_un
.d_ptr
= htab
->root
.srelplt
->output_section
->vma
;
8392 s
= htab
->root
.srelplt
;
8393 dyn
.d_un
.d_val
= s
->size
;
8397 /* The procedure linkage table relocs (DT_JMPREL) should
8398 not be included in the overall relocs (DT_RELA).
8399 Therefore, we override the DT_RELASZ entry here to
8400 make it not include the JMPREL relocs. Since the
8401 linker script arranges for .rela.plt to follow all
8402 other relocation sections, we don't have to worry
8403 about changing the DT_RELA entry. */
8404 if (htab
->root
.srelplt
!= NULL
)
8406 s
= htab
->root
.srelplt
;
8407 dyn
.d_un
.d_val
-= s
->size
;
8411 case DT_TLSDESC_PLT
:
8412 s
= htab
->root
.splt
;
8413 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
8414 + htab
->tlsdesc_plt
;
8417 case DT_TLSDESC_GOT
:
8418 s
= htab
->root
.sgot
;
8419 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
8420 + htab
->dt_tlsdesc_got
;
8424 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
8429 /* Fill in the special first entry in the procedure linkage table. */
8430 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
8432 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
8434 elf_section_data (htab
->root
.splt
->output_section
)->
8435 this_hdr
.sh_entsize
= htab
->plt_entry_size
;
8438 if (htab
->tlsdesc_plt
)
8440 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8441 htab
->root
.sgot
->contents
+ htab
->dt_tlsdesc_got
);
8443 memcpy (htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
,
8444 elfNN_aarch64_tlsdesc_small_plt_entry
,
8445 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry
));
8448 bfd_vma adrp1_addr
=
8449 htab
->root
.splt
->output_section
->vma
8450 + htab
->root
.splt
->output_offset
+ htab
->tlsdesc_plt
+ 4;
8452 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
8455 htab
->root
.sgot
->output_section
->vma
8456 + htab
->root
.sgot
->output_offset
;
8458 bfd_vma pltgot_addr
=
8459 htab
->root
.sgotplt
->output_section
->vma
8460 + htab
->root
.sgotplt
->output_offset
;
8462 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->dt_tlsdesc_got
;
8464 bfd_byte
*plt_entry
=
8465 htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
;
8467 /* adrp x2, DT_TLSDESC_GOT */
8468 elf_aarch64_update_plt_entry (output_bfd
,
8469 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8471 (PG (dt_tlsdesc_got
)
8472 - PG (adrp1_addr
)));
8475 elf_aarch64_update_plt_entry (output_bfd
,
8476 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8479 - PG (adrp2_addr
)));
8481 /* ldr x2, [x2, #0] */
8482 elf_aarch64_update_plt_entry (output_bfd
,
8483 BFD_RELOC_AARCH64_LDSTNN_LO12
,
8485 PG_OFFSET (dt_tlsdesc_got
));
8488 elf_aarch64_update_plt_entry (output_bfd
,
8489 BFD_RELOC_AARCH64_ADD_LO12
,
8491 PG_OFFSET (pltgot_addr
));
8496 if (htab
->root
.sgotplt
)
8498 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
8500 (*_bfd_error_handler
)
8501 (_("discarded output section: `%A'"), htab
->root
.sgotplt
);
8505 /* Fill in the first three entries in the global offset table. */
8506 if (htab
->root
.sgotplt
->size
> 0)
8508 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
8510 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
8511 bfd_put_NN (output_bfd
,
8513 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
8514 bfd_put_NN (output_bfd
,
8516 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
* 2);
8519 if (htab
->root
.sgot
)
8521 if (htab
->root
.sgot
->size
> 0)
8524 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
8525 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
8529 elf_section_data (htab
->root
.sgotplt
->output_section
)->
8530 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
8533 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
8534 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
8537 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
8538 htab_traverse (htab
->loc_hash_table
,
8539 elfNN_aarch64_finish_local_dynamic_symbol
,
8545 /* Return address for Ith PLT stub in section PLT, for relocation REL
8546 or (bfd_vma) -1 if it should not be included. */
8549 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
8550 const arelent
*rel ATTRIBUTE_UNUSED
)
8552 return plt
->vma
+ PLT_ENTRY_SIZE
+ i
* PLT_SMALL_ENTRY_SIZE
;
8556 /* We use this so we can override certain functions
8557 (though currently we don't). */
8559 const struct elf_size_info elfNN_aarch64_size_info
=
8561 sizeof (ElfNN_External_Ehdr
),
8562 sizeof (ElfNN_External_Phdr
),
8563 sizeof (ElfNN_External_Shdr
),
8564 sizeof (ElfNN_External_Rel
),
8565 sizeof (ElfNN_External_Rela
),
8566 sizeof (ElfNN_External_Sym
),
8567 sizeof (ElfNN_External_Dyn
),
8568 sizeof (Elf_External_Note
),
8569 4, /* Hash table entry size. */
8570 1, /* Internal relocs per external relocs. */
8571 ARCH_SIZE
, /* Arch size. */
8572 LOG_FILE_ALIGN
, /* Log_file_align. */
8573 ELFCLASSNN
, EV_CURRENT
,
8574 bfd_elfNN_write_out_phdrs
,
8575 bfd_elfNN_write_shdrs_and_ehdr
,
8576 bfd_elfNN_checksum_contents
,
8577 bfd_elfNN_write_relocs
,
8578 bfd_elfNN_swap_symbol_in
,
8579 bfd_elfNN_swap_symbol_out
,
8580 bfd_elfNN_slurp_reloc_table
,
8581 bfd_elfNN_slurp_symbol_table
,
8582 bfd_elfNN_swap_dyn_in
,
8583 bfd_elfNN_swap_dyn_out
,
8584 bfd_elfNN_swap_reloc_in
,
8585 bfd_elfNN_swap_reloc_out
,
8586 bfd_elfNN_swap_reloca_in
,
8587 bfd_elfNN_swap_reloca_out
8590 #define ELF_ARCH bfd_arch_aarch64
8591 #define ELF_MACHINE_CODE EM_AARCH64
8592 #define ELF_MAXPAGESIZE 0x10000
8593 #define ELF_MINPAGESIZE 0x1000
8594 #define ELF_COMMONPAGESIZE 0x1000
8596 #define bfd_elfNN_close_and_cleanup \
8597 elfNN_aarch64_close_and_cleanup
8599 #define bfd_elfNN_bfd_free_cached_info \
8600 elfNN_aarch64_bfd_free_cached_info
8602 #define bfd_elfNN_bfd_is_target_special_symbol \
8603 elfNN_aarch64_is_target_special_symbol
8605 #define bfd_elfNN_bfd_link_hash_table_create \
8606 elfNN_aarch64_link_hash_table_create
8608 #define bfd_elfNN_bfd_merge_private_bfd_data \
8609 elfNN_aarch64_merge_private_bfd_data
8611 #define bfd_elfNN_bfd_print_private_bfd_data \
8612 elfNN_aarch64_print_private_bfd_data
8614 #define bfd_elfNN_bfd_reloc_type_lookup \
8615 elfNN_aarch64_reloc_type_lookup
8617 #define bfd_elfNN_bfd_reloc_name_lookup \
8618 elfNN_aarch64_reloc_name_lookup
8620 #define bfd_elfNN_bfd_set_private_flags \
8621 elfNN_aarch64_set_private_flags
8623 #define bfd_elfNN_find_inliner_info \
8624 elfNN_aarch64_find_inliner_info
8626 #define bfd_elfNN_find_nearest_line \
8627 elfNN_aarch64_find_nearest_line
8629 #define bfd_elfNN_mkobject \
8630 elfNN_aarch64_mkobject
8632 #define bfd_elfNN_new_section_hook \
8633 elfNN_aarch64_new_section_hook
8635 #define elf_backend_adjust_dynamic_symbol \
8636 elfNN_aarch64_adjust_dynamic_symbol
8638 #define elf_backend_always_size_sections \
8639 elfNN_aarch64_always_size_sections
8641 #define elf_backend_check_relocs \
8642 elfNN_aarch64_check_relocs
8644 #define elf_backend_copy_indirect_symbol \
8645 elfNN_aarch64_copy_indirect_symbol
8647 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
8648 to them in our hash. */
8649 #define elf_backend_create_dynamic_sections \
8650 elfNN_aarch64_create_dynamic_sections
8652 #define elf_backend_init_index_section \
8653 _bfd_elf_init_2_index_sections
8655 #define elf_backend_finish_dynamic_sections \
8656 elfNN_aarch64_finish_dynamic_sections
8658 #define elf_backend_finish_dynamic_symbol \
8659 elfNN_aarch64_finish_dynamic_symbol
8661 #define elf_backend_gc_sweep_hook \
8662 elfNN_aarch64_gc_sweep_hook
8664 #define elf_backend_object_p \
8665 elfNN_aarch64_object_p
8667 #define elf_backend_output_arch_local_syms \
8668 elfNN_aarch64_output_arch_local_syms
8670 #define elf_backend_plt_sym_val \
8671 elfNN_aarch64_plt_sym_val
8673 #define elf_backend_post_process_headers \
8674 elfNN_aarch64_post_process_headers
8676 #define elf_backend_relocate_section \
8677 elfNN_aarch64_relocate_section
8679 #define elf_backend_reloc_type_class \
8680 elfNN_aarch64_reloc_type_class
8682 #define elf_backend_section_from_shdr \
8683 elfNN_aarch64_section_from_shdr
8685 #define elf_backend_size_dynamic_sections \
8686 elfNN_aarch64_size_dynamic_sections
8688 #define elf_backend_size_info \
8689 elfNN_aarch64_size_info
8691 #define elf_backend_write_section \
8692 elfNN_aarch64_write_section
8694 #define elf_backend_can_refcount 1
8695 #define elf_backend_can_gc_sections 1
8696 #define elf_backend_plt_readonly 1
8697 #define elf_backend_want_got_plt 1
8698 #define elf_backend_want_plt_sym 0
8699 #define elf_backend_may_use_rel_p 0
8700 #define elf_backend_may_use_rela_p 1
8701 #define elf_backend_default_use_rela_p 1
8702 #define elf_backend_rela_normal 1
8703 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
8704 #define elf_backend_default_execstack 0
8705 #define elf_backend_extern_protected_data 1
8707 #undef elf_backend_obj_attrs_section
8708 #define elf_backend_obj_attrs_section ".ARM.attributes"
8710 #include "elfNN-target.h"