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_ADR_PAGE21 \
169 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
170 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
171 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_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_TLS_DTPMOD \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
188 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
190 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
191 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC)
204 #define ELIMINATE_COPY_RELOCS 0
206 /* Return size of a relocation entry. HTAB is the bfd's
207 elf_aarch64_link_hash_entry. */
208 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
210 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
211 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
212 #define PLT_ENTRY_SIZE (32)
213 #define PLT_SMALL_ENTRY_SIZE (16)
214 #define PLT_TLSDESC_ENTRY_SIZE (32)
216 /* Encoding of the nop instruction */
217 #define INSN_NOP 0xd503201f
219 #define aarch64_compute_jump_table_size(htab) \
220 (((htab)->root.srelplt == NULL) ? 0 \
221 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
223 /* The first entry in a procedure linkage table looks like this
224 if the distance between the PLTGOT and the PLT is < 4GB use
225 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
226 in x16 and needs to work out PLTGOT[1] by using an address of
227 [x16,#-GOT_ENTRY_SIZE]. */
228 static const bfd_byte elfNN_aarch64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
230 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
231 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
233 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
234 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
236 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
237 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
239 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
240 0x1f, 0x20, 0x03, 0xd5, /* nop */
241 0x1f, 0x20, 0x03, 0xd5, /* nop */
242 0x1f, 0x20, 0x03, 0xd5, /* nop */
245 /* Per function entry in a procedure linkage table looks like this
246 if the distance between the PLTGOT and the PLT is < 4GB use
247 these PLT entries. */
248 static const bfd_byte elfNN_aarch64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
250 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
252 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
253 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
255 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
256 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
258 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
261 static const bfd_byte
262 elfNN_aarch64_tlsdesc_small_plt_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
264 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
265 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
266 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
268 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
269 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
271 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
272 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
274 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
275 0x1f, 0x20, 0x03, 0xd5, /* nop */
276 0x1f, 0x20, 0x03, 0xd5, /* nop */
279 #define elf_info_to_howto elfNN_aarch64_info_to_howto
280 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
282 #define AARCH64_ELF_ABI_VERSION 0
284 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
285 #define ALL_ONES (~ (bfd_vma) 0)
287 /* Indexed by the bfd interal reloc enumerators.
288 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
291 static reloc_howto_type elfNN_aarch64_howto_table
[] =
295 /* Basic data relocations. */
298 HOWTO (R_AARCH64_NULL
, /* type */
300 3, /* size (0 = byte, 1 = short, 2 = long) */
302 FALSE
, /* pc_relative */
304 complain_overflow_dont
, /* complain_on_overflow */
305 bfd_elf_generic_reloc
, /* special_function */
306 "R_AARCH64_NULL", /* name */
307 FALSE
, /* partial_inplace */
310 FALSE
), /* pcrel_offset */
312 HOWTO (R_AARCH64_NONE
, /* type */
314 3, /* size (0 = byte, 1 = short, 2 = long) */
316 FALSE
, /* pc_relative */
318 complain_overflow_dont
, /* complain_on_overflow */
319 bfd_elf_generic_reloc
, /* special_function */
320 "R_AARCH64_NONE", /* name */
321 FALSE
, /* partial_inplace */
324 FALSE
), /* pcrel_offset */
328 HOWTO64 (AARCH64_R (ABS64
), /* type */
330 4, /* size (4 = long long) */
332 FALSE
, /* pc_relative */
334 complain_overflow_unsigned
, /* complain_on_overflow */
335 bfd_elf_generic_reloc
, /* special_function */
336 AARCH64_R_STR (ABS64
), /* name */
337 FALSE
, /* partial_inplace */
338 ALL_ONES
, /* src_mask */
339 ALL_ONES
, /* dst_mask */
340 FALSE
), /* pcrel_offset */
343 HOWTO (AARCH64_R (ABS32
), /* type */
345 2, /* size (0 = byte, 1 = short, 2 = long) */
347 FALSE
, /* pc_relative */
349 complain_overflow_unsigned
, /* complain_on_overflow */
350 bfd_elf_generic_reloc
, /* special_function */
351 AARCH64_R_STR (ABS32
), /* name */
352 FALSE
, /* partial_inplace */
353 0xffffffff, /* src_mask */
354 0xffffffff, /* dst_mask */
355 FALSE
), /* pcrel_offset */
358 HOWTO (AARCH64_R (ABS16
), /* type */
360 1, /* size (0 = byte, 1 = short, 2 = long) */
362 FALSE
, /* pc_relative */
364 complain_overflow_unsigned
, /* complain_on_overflow */
365 bfd_elf_generic_reloc
, /* special_function */
366 AARCH64_R_STR (ABS16
), /* name */
367 FALSE
, /* partial_inplace */
368 0xffff, /* src_mask */
369 0xffff, /* dst_mask */
370 FALSE
), /* pcrel_offset */
372 /* .xword: (S+A-P) */
373 HOWTO64 (AARCH64_R (PREL64
), /* type */
375 4, /* size (4 = long long) */
377 TRUE
, /* pc_relative */
379 complain_overflow_signed
, /* complain_on_overflow */
380 bfd_elf_generic_reloc
, /* special_function */
381 AARCH64_R_STR (PREL64
), /* name */
382 FALSE
, /* partial_inplace */
383 ALL_ONES
, /* src_mask */
384 ALL_ONES
, /* dst_mask */
385 TRUE
), /* pcrel_offset */
388 HOWTO (AARCH64_R (PREL32
), /* type */
390 2, /* size (0 = byte, 1 = short, 2 = long) */
392 TRUE
, /* pc_relative */
394 complain_overflow_signed
, /* complain_on_overflow */
395 bfd_elf_generic_reloc
, /* special_function */
396 AARCH64_R_STR (PREL32
), /* name */
397 FALSE
, /* partial_inplace */
398 0xffffffff, /* src_mask */
399 0xffffffff, /* dst_mask */
400 TRUE
), /* pcrel_offset */
403 HOWTO (AARCH64_R (PREL16
), /* type */
405 1, /* size (0 = byte, 1 = short, 2 = long) */
407 TRUE
, /* pc_relative */
409 complain_overflow_signed
, /* complain_on_overflow */
410 bfd_elf_generic_reloc
, /* special_function */
411 AARCH64_R_STR (PREL16
), /* name */
412 FALSE
, /* partial_inplace */
413 0xffff, /* src_mask */
414 0xffff, /* dst_mask */
415 TRUE
), /* pcrel_offset */
417 /* Group relocations to create a 16, 32, 48 or 64 bit
418 unsigned data or abs address inline. */
420 /* MOVZ: ((S+A) >> 0) & 0xffff */
421 HOWTO (AARCH64_R (MOVW_UABS_G0
), /* type */
423 2, /* size (0 = byte, 1 = short, 2 = long) */
425 FALSE
, /* pc_relative */
427 complain_overflow_unsigned
, /* complain_on_overflow */
428 bfd_elf_generic_reloc
, /* special_function */
429 AARCH64_R_STR (MOVW_UABS_G0
), /* name */
430 FALSE
, /* partial_inplace */
431 0xffff, /* src_mask */
432 0xffff, /* dst_mask */
433 FALSE
), /* pcrel_offset */
435 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
436 HOWTO (AARCH64_R (MOVW_UABS_G0_NC
), /* type */
438 2, /* size (0 = byte, 1 = short, 2 = long) */
440 FALSE
, /* pc_relative */
442 complain_overflow_dont
, /* complain_on_overflow */
443 bfd_elf_generic_reloc
, /* special_function */
444 AARCH64_R_STR (MOVW_UABS_G0_NC
), /* name */
445 FALSE
, /* partial_inplace */
446 0xffff, /* src_mask */
447 0xffff, /* dst_mask */
448 FALSE
), /* pcrel_offset */
450 /* MOVZ: ((S+A) >> 16) & 0xffff */
451 HOWTO (AARCH64_R (MOVW_UABS_G1
), /* type */
453 2, /* size (0 = byte, 1 = short, 2 = long) */
455 FALSE
, /* pc_relative */
457 complain_overflow_unsigned
, /* complain_on_overflow */
458 bfd_elf_generic_reloc
, /* special_function */
459 AARCH64_R_STR (MOVW_UABS_G1
), /* name */
460 FALSE
, /* partial_inplace */
461 0xffff, /* src_mask */
462 0xffff, /* dst_mask */
463 FALSE
), /* pcrel_offset */
465 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
466 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC
), /* type */
468 2, /* size (0 = byte, 1 = short, 2 = long) */
470 FALSE
, /* pc_relative */
472 complain_overflow_dont
, /* complain_on_overflow */
473 bfd_elf_generic_reloc
, /* special_function */
474 AARCH64_R_STR (MOVW_UABS_G1_NC
), /* name */
475 FALSE
, /* partial_inplace */
476 0xffff, /* src_mask */
477 0xffff, /* dst_mask */
478 FALSE
), /* pcrel_offset */
480 /* MOVZ: ((S+A) >> 32) & 0xffff */
481 HOWTO64 (AARCH64_R (MOVW_UABS_G2
), /* type */
483 2, /* size (0 = byte, 1 = short, 2 = long) */
485 FALSE
, /* pc_relative */
487 complain_overflow_unsigned
, /* complain_on_overflow */
488 bfd_elf_generic_reloc
, /* special_function */
489 AARCH64_R_STR (MOVW_UABS_G2
), /* name */
490 FALSE
, /* partial_inplace */
491 0xffff, /* src_mask */
492 0xffff, /* dst_mask */
493 FALSE
), /* pcrel_offset */
495 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
496 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC
), /* type */
498 2, /* size (0 = byte, 1 = short, 2 = long) */
500 FALSE
, /* pc_relative */
502 complain_overflow_dont
, /* complain_on_overflow */
503 bfd_elf_generic_reloc
, /* special_function */
504 AARCH64_R_STR (MOVW_UABS_G2_NC
), /* name */
505 FALSE
, /* partial_inplace */
506 0xffff, /* src_mask */
507 0xffff, /* dst_mask */
508 FALSE
), /* pcrel_offset */
510 /* MOVZ: ((S+A) >> 48) & 0xffff */
511 HOWTO64 (AARCH64_R (MOVW_UABS_G3
), /* type */
513 2, /* size (0 = byte, 1 = short, 2 = long) */
515 FALSE
, /* pc_relative */
517 complain_overflow_unsigned
, /* complain_on_overflow */
518 bfd_elf_generic_reloc
, /* special_function */
519 AARCH64_R_STR (MOVW_UABS_G3
), /* name */
520 FALSE
, /* partial_inplace */
521 0xffff, /* src_mask */
522 0xffff, /* dst_mask */
523 FALSE
), /* pcrel_offset */
525 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
526 signed data or abs address inline. Will change instruction
527 to MOVN or MOVZ depending on sign of calculated value. */
529 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
530 HOWTO (AARCH64_R (MOVW_SABS_G0
), /* type */
532 2, /* size (0 = byte, 1 = short, 2 = long) */
534 FALSE
, /* pc_relative */
536 complain_overflow_signed
, /* complain_on_overflow */
537 bfd_elf_generic_reloc
, /* special_function */
538 AARCH64_R_STR (MOVW_SABS_G0
), /* name */
539 FALSE
, /* partial_inplace */
540 0xffff, /* src_mask */
541 0xffff, /* dst_mask */
542 FALSE
), /* pcrel_offset */
544 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
545 HOWTO64 (AARCH64_R (MOVW_SABS_G1
), /* type */
547 2, /* size (0 = byte, 1 = short, 2 = long) */
549 FALSE
, /* pc_relative */
551 complain_overflow_signed
, /* complain_on_overflow */
552 bfd_elf_generic_reloc
, /* special_function */
553 AARCH64_R_STR (MOVW_SABS_G1
), /* name */
554 FALSE
, /* partial_inplace */
555 0xffff, /* src_mask */
556 0xffff, /* dst_mask */
557 FALSE
), /* pcrel_offset */
559 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
560 HOWTO64 (AARCH64_R (MOVW_SABS_G2
), /* type */
562 2, /* size (0 = byte, 1 = short, 2 = long) */
564 FALSE
, /* pc_relative */
566 complain_overflow_signed
, /* complain_on_overflow */
567 bfd_elf_generic_reloc
, /* special_function */
568 AARCH64_R_STR (MOVW_SABS_G2
), /* name */
569 FALSE
, /* partial_inplace */
570 0xffff, /* src_mask */
571 0xffff, /* dst_mask */
572 FALSE
), /* pcrel_offset */
574 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
575 addresses: PG(x) is (x & ~0xfff). */
577 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
578 HOWTO (AARCH64_R (LD_PREL_LO19
), /* type */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
582 TRUE
, /* pc_relative */
584 complain_overflow_signed
, /* complain_on_overflow */
585 bfd_elf_generic_reloc
, /* special_function */
586 AARCH64_R_STR (LD_PREL_LO19
), /* name */
587 FALSE
, /* partial_inplace */
588 0x7ffff, /* src_mask */
589 0x7ffff, /* dst_mask */
590 TRUE
), /* pcrel_offset */
592 /* ADR: (S+A-P) & 0x1fffff */
593 HOWTO (AARCH64_R (ADR_PREL_LO21
), /* type */
595 2, /* size (0 = byte, 1 = short, 2 = long) */
597 TRUE
, /* pc_relative */
599 complain_overflow_signed
, /* complain_on_overflow */
600 bfd_elf_generic_reloc
, /* special_function */
601 AARCH64_R_STR (ADR_PREL_LO21
), /* name */
602 FALSE
, /* partial_inplace */
603 0x1fffff, /* src_mask */
604 0x1fffff, /* dst_mask */
605 TRUE
), /* pcrel_offset */
607 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
608 HOWTO (AARCH64_R (ADR_PREL_PG_HI21
), /* type */
610 2, /* size (0 = byte, 1 = short, 2 = long) */
612 TRUE
, /* pc_relative */
614 complain_overflow_signed
, /* complain_on_overflow */
615 bfd_elf_generic_reloc
, /* special_function */
616 AARCH64_R_STR (ADR_PREL_PG_HI21
), /* name */
617 FALSE
, /* partial_inplace */
618 0x1fffff, /* src_mask */
619 0x1fffff, /* dst_mask */
620 TRUE
), /* pcrel_offset */
622 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
623 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC
), /* type */
625 2, /* size (0 = byte, 1 = short, 2 = long) */
627 TRUE
, /* pc_relative */
629 complain_overflow_dont
, /* complain_on_overflow */
630 bfd_elf_generic_reloc
, /* special_function */
631 AARCH64_R_STR (ADR_PREL_PG_HI21_NC
), /* name */
632 FALSE
, /* partial_inplace */
633 0x1fffff, /* src_mask */
634 0x1fffff, /* dst_mask */
635 TRUE
), /* pcrel_offset */
637 /* ADD: (S+A) & 0xfff [no overflow check] */
638 HOWTO (AARCH64_R (ADD_ABS_LO12_NC
), /* type */
640 2, /* size (0 = byte, 1 = short, 2 = long) */
642 FALSE
, /* pc_relative */
644 complain_overflow_dont
, /* complain_on_overflow */
645 bfd_elf_generic_reloc
, /* special_function */
646 AARCH64_R_STR (ADD_ABS_LO12_NC
), /* name */
647 FALSE
, /* partial_inplace */
648 0x3ffc00, /* src_mask */
649 0x3ffc00, /* dst_mask */
650 FALSE
), /* pcrel_offset */
652 /* LD/ST8: (S+A) & 0xfff */
653 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC
), /* type */
655 2, /* size (0 = byte, 1 = short, 2 = long) */
657 FALSE
, /* pc_relative */
659 complain_overflow_dont
, /* complain_on_overflow */
660 bfd_elf_generic_reloc
, /* special_function */
661 AARCH64_R_STR (LDST8_ABS_LO12_NC
), /* name */
662 FALSE
, /* partial_inplace */
663 0xfff, /* src_mask */
664 0xfff, /* dst_mask */
665 FALSE
), /* pcrel_offset */
667 /* Relocations for control-flow instructions. */
669 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
670 HOWTO (AARCH64_R (TSTBR14
), /* type */
672 2, /* size (0 = byte, 1 = short, 2 = long) */
674 TRUE
, /* pc_relative */
676 complain_overflow_signed
, /* complain_on_overflow */
677 bfd_elf_generic_reloc
, /* special_function */
678 AARCH64_R_STR (TSTBR14
), /* name */
679 FALSE
, /* partial_inplace */
680 0x3fff, /* src_mask */
681 0x3fff, /* dst_mask */
682 TRUE
), /* pcrel_offset */
684 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
685 HOWTO (AARCH64_R (CONDBR19
), /* type */
687 2, /* size (0 = byte, 1 = short, 2 = long) */
689 TRUE
, /* pc_relative */
691 complain_overflow_signed
, /* complain_on_overflow */
692 bfd_elf_generic_reloc
, /* special_function */
693 AARCH64_R_STR (CONDBR19
), /* name */
694 FALSE
, /* partial_inplace */
695 0x7ffff, /* src_mask */
696 0x7ffff, /* dst_mask */
697 TRUE
), /* pcrel_offset */
699 /* B: ((S+A-P) >> 2) & 0x3ffffff */
700 HOWTO (AARCH64_R (JUMP26
), /* type */
702 2, /* size (0 = byte, 1 = short, 2 = long) */
704 TRUE
, /* pc_relative */
706 complain_overflow_signed
, /* complain_on_overflow */
707 bfd_elf_generic_reloc
, /* special_function */
708 AARCH64_R_STR (JUMP26
), /* name */
709 FALSE
, /* partial_inplace */
710 0x3ffffff, /* src_mask */
711 0x3ffffff, /* dst_mask */
712 TRUE
), /* pcrel_offset */
714 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
715 HOWTO (AARCH64_R (CALL26
), /* type */
717 2, /* size (0 = byte, 1 = short, 2 = long) */
719 TRUE
, /* pc_relative */
721 complain_overflow_signed
, /* complain_on_overflow */
722 bfd_elf_generic_reloc
, /* special_function */
723 AARCH64_R_STR (CALL26
), /* name */
724 FALSE
, /* partial_inplace */
725 0x3ffffff, /* src_mask */
726 0x3ffffff, /* dst_mask */
727 TRUE
), /* pcrel_offset */
729 /* LD/ST16: (S+A) & 0xffe */
730 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC
), /* type */
732 2, /* size (0 = byte, 1 = short, 2 = long) */
734 FALSE
, /* pc_relative */
736 complain_overflow_dont
, /* complain_on_overflow */
737 bfd_elf_generic_reloc
, /* special_function */
738 AARCH64_R_STR (LDST16_ABS_LO12_NC
), /* name */
739 FALSE
, /* partial_inplace */
740 0xffe, /* src_mask */
741 0xffe, /* dst_mask */
742 FALSE
), /* pcrel_offset */
744 /* LD/ST32: (S+A) & 0xffc */
745 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC
), /* type */
747 2, /* size (0 = byte, 1 = short, 2 = long) */
749 FALSE
, /* pc_relative */
751 complain_overflow_dont
, /* complain_on_overflow */
752 bfd_elf_generic_reloc
, /* special_function */
753 AARCH64_R_STR (LDST32_ABS_LO12_NC
), /* name */
754 FALSE
, /* partial_inplace */
755 0xffc, /* src_mask */
756 0xffc, /* dst_mask */
757 FALSE
), /* pcrel_offset */
759 /* LD/ST64: (S+A) & 0xff8 */
760 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC
), /* type */
762 2, /* size (0 = byte, 1 = short, 2 = long) */
764 FALSE
, /* pc_relative */
766 complain_overflow_dont
, /* complain_on_overflow */
767 bfd_elf_generic_reloc
, /* special_function */
768 AARCH64_R_STR (LDST64_ABS_LO12_NC
), /* name */
769 FALSE
, /* partial_inplace */
770 0xff8, /* src_mask */
771 0xff8, /* dst_mask */
772 FALSE
), /* pcrel_offset */
774 /* LD/ST128: (S+A) & 0xff0 */
775 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC
), /* type */
777 2, /* size (0 = byte, 1 = short, 2 = long) */
779 FALSE
, /* pc_relative */
781 complain_overflow_dont
, /* complain_on_overflow */
782 bfd_elf_generic_reloc
, /* special_function */
783 AARCH64_R_STR (LDST128_ABS_LO12_NC
), /* name */
784 FALSE
, /* partial_inplace */
785 0xff0, /* src_mask */
786 0xff0, /* dst_mask */
787 FALSE
), /* pcrel_offset */
789 /* Set a load-literal immediate field to bits
790 0x1FFFFC of G(S)-P */
791 HOWTO (AARCH64_R (GOT_LD_PREL19
), /* type */
793 2, /* size (0 = byte,1 = short,2 = long) */
795 TRUE
, /* pc_relative */
797 complain_overflow_signed
, /* complain_on_overflow */
798 bfd_elf_generic_reloc
, /* special_function */
799 AARCH64_R_STR (GOT_LD_PREL19
), /* name */
800 FALSE
, /* partial_inplace */
801 0xffffe0, /* src_mask */
802 0xffffe0, /* dst_mask */
803 TRUE
), /* pcrel_offset */
805 /* Get to the page for the GOT entry for the symbol
806 (G(S) - P) using an ADRP instruction. */
807 HOWTO (AARCH64_R (ADR_GOT_PAGE
), /* type */
809 2, /* size (0 = byte, 1 = short, 2 = long) */
811 TRUE
, /* pc_relative */
813 complain_overflow_dont
, /* complain_on_overflow */
814 bfd_elf_generic_reloc
, /* special_function */
815 AARCH64_R_STR (ADR_GOT_PAGE
), /* name */
816 FALSE
, /* partial_inplace */
817 0x1fffff, /* src_mask */
818 0x1fffff, /* dst_mask */
819 TRUE
), /* pcrel_offset */
821 /* LD64: GOT offset G(S) & 0xff8 */
822 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC
), /* type */
824 2, /* size (0 = byte, 1 = short, 2 = long) */
826 FALSE
, /* pc_relative */
828 complain_overflow_dont
, /* complain_on_overflow */
829 bfd_elf_generic_reloc
, /* special_function */
830 AARCH64_R_STR (LD64_GOT_LO12_NC
), /* name */
831 FALSE
, /* partial_inplace */
832 0xff8, /* src_mask */
833 0xff8, /* dst_mask */
834 FALSE
), /* pcrel_offset */
836 /* LD32: GOT offset G(S) & 0xffc */
837 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC
), /* type */
839 2, /* size (0 = byte, 1 = short, 2 = long) */
841 FALSE
, /* pc_relative */
843 complain_overflow_dont
, /* complain_on_overflow */
844 bfd_elf_generic_reloc
, /* special_function */
845 AARCH64_R_STR (LD32_GOT_LO12_NC
), /* name */
846 FALSE
, /* partial_inplace */
847 0xffc, /* src_mask */
848 0xffc, /* dst_mask */
849 FALSE
), /* pcrel_offset */
851 /* Get to the page for the GOT entry for the symbol
852 (G(S) - P) using an ADRP instruction. */
853 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21
), /* type */
855 2, /* size (0 = byte, 1 = short, 2 = long) */
857 TRUE
, /* pc_relative */
859 complain_overflow_dont
, /* complain_on_overflow */
860 bfd_elf_generic_reloc
, /* special_function */
861 AARCH64_R_STR (TLSGD_ADR_PAGE21
), /* name */
862 FALSE
, /* partial_inplace */
863 0x1fffff, /* src_mask */
864 0x1fffff, /* dst_mask */
865 TRUE
), /* pcrel_offset */
867 HOWTO (AARCH64_R (TLSGD_ADR_PREL21
), /* type */
869 2, /* size (0 = byte, 1 = short, 2 = long) */
871 TRUE
, /* pc_relative */
873 complain_overflow_dont
, /* complain_on_overflow */
874 bfd_elf_generic_reloc
, /* special_function */
875 AARCH64_R_STR (TLSGD_ADR_PREL21
), /* name */
876 FALSE
, /* partial_inplace */
877 0x1fffff, /* src_mask */
878 0x1fffff, /* dst_mask */
879 TRUE
), /* pcrel_offset */
881 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
882 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC
), /* type */
884 2, /* size (0 = byte, 1 = short, 2 = long) */
886 FALSE
, /* pc_relative */
888 complain_overflow_dont
, /* complain_on_overflow */
889 bfd_elf_generic_reloc
, /* special_function */
890 AARCH64_R_STR (TLSGD_ADD_LO12_NC
), /* name */
891 FALSE
, /* partial_inplace */
892 0xfff, /* src_mask */
893 0xfff, /* dst_mask */
894 FALSE
), /* pcrel_offset */
896 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1
), /* type */
898 2, /* size (0 = byte, 1 = short, 2 = long) */
900 FALSE
, /* pc_relative */
902 complain_overflow_dont
, /* complain_on_overflow */
903 bfd_elf_generic_reloc
, /* special_function */
904 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1
), /* name */
905 FALSE
, /* partial_inplace */
906 0xffff, /* src_mask */
907 0xffff, /* dst_mask */
908 FALSE
), /* pcrel_offset */
910 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC
), /* type */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
914 FALSE
, /* pc_relative */
916 complain_overflow_dont
, /* complain_on_overflow */
917 bfd_elf_generic_reloc
, /* special_function */
918 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC
), /* name */
919 FALSE
, /* partial_inplace */
920 0xffff, /* src_mask */
921 0xffff, /* dst_mask */
922 FALSE
), /* pcrel_offset */
924 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21
), /* type */
926 2, /* size (0 = byte, 1 = short, 2 = long) */
928 FALSE
, /* pc_relative */
930 complain_overflow_dont
, /* complain_on_overflow */
931 bfd_elf_generic_reloc
, /* special_function */
932 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21
), /* name */
933 FALSE
, /* partial_inplace */
934 0x1fffff, /* src_mask */
935 0x1fffff, /* dst_mask */
936 FALSE
), /* pcrel_offset */
938 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC
), /* type */
940 2, /* size (0 = byte, 1 = short, 2 = long) */
942 FALSE
, /* pc_relative */
944 complain_overflow_dont
, /* complain_on_overflow */
945 bfd_elf_generic_reloc
, /* special_function */
946 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC
), /* name */
947 FALSE
, /* partial_inplace */
948 0xff8, /* src_mask */
949 0xff8, /* dst_mask */
950 FALSE
), /* pcrel_offset */
952 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC
), /* type */
954 2, /* size (0 = byte, 1 = short, 2 = long) */
956 FALSE
, /* pc_relative */
958 complain_overflow_dont
, /* complain_on_overflow */
959 bfd_elf_generic_reloc
, /* special_function */
960 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC
), /* name */
961 FALSE
, /* partial_inplace */
962 0xffc, /* src_mask */
963 0xffc, /* dst_mask */
964 FALSE
), /* pcrel_offset */
966 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19
), /* type */
968 2, /* size (0 = byte, 1 = short, 2 = long) */
970 FALSE
, /* pc_relative */
972 complain_overflow_dont
, /* complain_on_overflow */
973 bfd_elf_generic_reloc
, /* special_function */
974 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19
), /* name */
975 FALSE
, /* partial_inplace */
976 0x1ffffc, /* src_mask */
977 0x1ffffc, /* dst_mask */
978 FALSE
), /* pcrel_offset */
980 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2
), /* type */
982 2, /* size (0 = byte, 1 = short, 2 = long) */
984 FALSE
, /* pc_relative */
986 complain_overflow_unsigned
, /* complain_on_overflow */
987 bfd_elf_generic_reloc
, /* special_function */
988 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2
), /* name */
989 FALSE
, /* partial_inplace */
990 0xffff, /* src_mask */
991 0xffff, /* dst_mask */
992 FALSE
), /* pcrel_offset */
994 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1
), /* type */
996 2, /* size (0 = byte, 1 = short, 2 = long) */
998 FALSE
, /* pc_relative */
1000 complain_overflow_dont
, /* complain_on_overflow */
1001 bfd_elf_generic_reloc
, /* special_function */
1002 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1
), /* name */
1003 FALSE
, /* partial_inplace */
1004 0xffff, /* src_mask */
1005 0xffff, /* dst_mask */
1006 FALSE
), /* pcrel_offset */
1008 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC
), /* type */
1009 16, /* rightshift */
1010 2, /* size (0 = byte, 1 = short, 2 = long) */
1012 FALSE
, /* pc_relative */
1014 complain_overflow_dont
, /* complain_on_overflow */
1015 bfd_elf_generic_reloc
, /* special_function */
1016 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC
), /* name */
1017 FALSE
, /* partial_inplace */
1018 0xffff, /* src_mask */
1019 0xffff, /* dst_mask */
1020 FALSE
), /* pcrel_offset */
1022 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0
), /* type */
1024 2, /* size (0 = byte, 1 = short, 2 = long) */
1026 FALSE
, /* pc_relative */
1028 complain_overflow_dont
, /* complain_on_overflow */
1029 bfd_elf_generic_reloc
, /* special_function */
1030 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0
), /* name */
1031 FALSE
, /* partial_inplace */
1032 0xffff, /* src_mask */
1033 0xffff, /* dst_mask */
1034 FALSE
), /* pcrel_offset */
1036 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
), /* type */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1040 FALSE
, /* pc_relative */
1042 complain_overflow_dont
, /* complain_on_overflow */
1043 bfd_elf_generic_reloc
, /* special_function */
1044 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC
), /* name */
1045 FALSE
, /* partial_inplace */
1046 0xffff, /* src_mask */
1047 0xffff, /* dst_mask */
1048 FALSE
), /* pcrel_offset */
1050 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12
), /* type */
1051 12, /* rightshift */
1052 2, /* size (0 = byte, 1 = short, 2 = long) */
1054 FALSE
, /* pc_relative */
1056 complain_overflow_unsigned
, /* complain_on_overflow */
1057 bfd_elf_generic_reloc
, /* special_function */
1058 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12
), /* name */
1059 FALSE
, /* partial_inplace */
1060 0xfff, /* src_mask */
1061 0xfff, /* dst_mask */
1062 FALSE
), /* pcrel_offset */
1064 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12
), /* type */
1066 2, /* size (0 = byte, 1 = short, 2 = long) */
1068 FALSE
, /* pc_relative */
1070 complain_overflow_dont
, /* complain_on_overflow */
1071 bfd_elf_generic_reloc
, /* special_function */
1072 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12
), /* name */
1073 FALSE
, /* partial_inplace */
1074 0xfff, /* src_mask */
1075 0xfff, /* dst_mask */
1076 FALSE
), /* pcrel_offset */
1078 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
), /* type */
1080 2, /* size (0 = byte, 1 = short, 2 = long) */
1082 FALSE
, /* pc_relative */
1084 complain_overflow_dont
, /* complain_on_overflow */
1085 bfd_elf_generic_reloc
, /* special_function */
1086 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC
), /* name */
1087 FALSE
, /* partial_inplace */
1088 0xfff, /* src_mask */
1089 0xfff, /* dst_mask */
1090 FALSE
), /* pcrel_offset */
1092 HOWTO (AARCH64_R (TLSDESC_LD_PREL19
), /* type */
1094 2, /* size (0 = byte, 1 = short, 2 = long) */
1096 TRUE
, /* pc_relative */
1098 complain_overflow_dont
, /* complain_on_overflow */
1099 bfd_elf_generic_reloc
, /* special_function */
1100 AARCH64_R_STR (TLSDESC_LD_PREL19
), /* name */
1101 FALSE
, /* partial_inplace */
1102 0x1ffffc, /* src_mask */
1103 0x1ffffc, /* dst_mask */
1104 TRUE
), /* pcrel_offset */
1106 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21
), /* type */
1108 2, /* size (0 = byte, 1 = short, 2 = long) */
1110 TRUE
, /* pc_relative */
1112 complain_overflow_dont
, /* complain_on_overflow */
1113 bfd_elf_generic_reloc
, /* special_function */
1114 AARCH64_R_STR (TLSDESC_ADR_PREL21
), /* name */
1115 FALSE
, /* partial_inplace */
1116 0x1fffff, /* src_mask */
1117 0x1fffff, /* dst_mask */
1118 TRUE
), /* pcrel_offset */
1120 /* Get to the page for the GOT entry for the symbol
1121 (G(S) - P) using an ADRP instruction. */
1122 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21
), /* type */
1123 12, /* rightshift */
1124 2, /* size (0 = byte, 1 = short, 2 = long) */
1126 TRUE
, /* pc_relative */
1128 complain_overflow_dont
, /* complain_on_overflow */
1129 bfd_elf_generic_reloc
, /* special_function */
1130 AARCH64_R_STR (TLSDESC_ADR_PAGE21
), /* name */
1131 FALSE
, /* partial_inplace */
1132 0x1fffff, /* src_mask */
1133 0x1fffff, /* dst_mask */
1134 TRUE
), /* pcrel_offset */
1136 /* LD64: GOT offset G(S) & 0xff8. */
1137 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC
), /* type */
1139 2, /* size (0 = byte, 1 = short, 2 = long) */
1141 FALSE
, /* pc_relative */
1143 complain_overflow_dont
, /* complain_on_overflow */
1144 bfd_elf_generic_reloc
, /* special_function */
1145 AARCH64_R_STR (TLSDESC_LD64_LO12_NC
), /* name */
1146 FALSE
, /* partial_inplace */
1147 0xff8, /* src_mask */
1148 0xff8, /* dst_mask */
1149 FALSE
), /* pcrel_offset */
1151 /* LD32: GOT offset G(S) & 0xffc. */
1152 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC
), /* type */
1154 2, /* size (0 = byte, 1 = short, 2 = long) */
1156 FALSE
, /* pc_relative */
1158 complain_overflow_dont
, /* complain_on_overflow */
1159 bfd_elf_generic_reloc
, /* special_function */
1160 AARCH64_R_STR (TLSDESC_LD32_LO12_NC
), /* name */
1161 FALSE
, /* partial_inplace */
1162 0xffc, /* src_mask */
1163 0xffc, /* dst_mask */
1164 FALSE
), /* pcrel_offset */
1166 /* ADD: GOT offset G(S) & 0xfff. */
1167 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC
), /* type */
1169 2, /* size (0 = byte, 1 = short, 2 = long) */
1171 FALSE
, /* pc_relative */
1173 complain_overflow_dont
, /* complain_on_overflow */
1174 bfd_elf_generic_reloc
, /* special_function */
1175 AARCH64_R_STR (TLSDESC_ADD_LO12_NC
), /* name */
1176 FALSE
, /* partial_inplace */
1177 0xfff, /* src_mask */
1178 0xfff, /* dst_mask */
1179 FALSE
), /* pcrel_offset */
1181 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1
), /* type */
1182 16, /* rightshift */
1183 2, /* size (0 = byte, 1 = short, 2 = long) */
1185 FALSE
, /* pc_relative */
1187 complain_overflow_dont
, /* complain_on_overflow */
1188 bfd_elf_generic_reloc
, /* special_function */
1189 AARCH64_R_STR (TLSDESC_OFF_G1
), /* name */
1190 FALSE
, /* partial_inplace */
1191 0xffff, /* src_mask */
1192 0xffff, /* dst_mask */
1193 FALSE
), /* pcrel_offset */
1195 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC
), /* type */
1197 2, /* size (0 = byte, 1 = short, 2 = long) */
1199 FALSE
, /* pc_relative */
1201 complain_overflow_dont
, /* complain_on_overflow */
1202 bfd_elf_generic_reloc
, /* special_function */
1203 AARCH64_R_STR (TLSDESC_OFF_G0_NC
), /* name */
1204 FALSE
, /* partial_inplace */
1205 0xffff, /* src_mask */
1206 0xffff, /* dst_mask */
1207 FALSE
), /* pcrel_offset */
1209 HOWTO64 (AARCH64_R (TLSDESC_LDR
), /* type */
1211 2, /* size (0 = byte, 1 = short, 2 = long) */
1213 FALSE
, /* pc_relative */
1215 complain_overflow_dont
, /* complain_on_overflow */
1216 bfd_elf_generic_reloc
, /* special_function */
1217 AARCH64_R_STR (TLSDESC_LDR
), /* name */
1218 FALSE
, /* partial_inplace */
1221 FALSE
), /* pcrel_offset */
1223 HOWTO64 (AARCH64_R (TLSDESC_ADD
), /* type */
1225 2, /* size (0 = byte, 1 = short, 2 = long) */
1227 FALSE
, /* pc_relative */
1229 complain_overflow_dont
, /* complain_on_overflow */
1230 bfd_elf_generic_reloc
, /* special_function */
1231 AARCH64_R_STR (TLSDESC_ADD
), /* name */
1232 FALSE
, /* partial_inplace */
1235 FALSE
), /* pcrel_offset */
1237 HOWTO (AARCH64_R (TLSDESC_CALL
), /* type */
1239 2, /* size (0 = byte, 1 = short, 2 = long) */
1241 FALSE
, /* pc_relative */
1243 complain_overflow_dont
, /* complain_on_overflow */
1244 bfd_elf_generic_reloc
, /* special_function */
1245 AARCH64_R_STR (TLSDESC_CALL
), /* name */
1246 FALSE
, /* partial_inplace */
1249 FALSE
), /* pcrel_offset */
1251 HOWTO (AARCH64_R (COPY
), /* type */
1253 2, /* size (0 = byte, 1 = short, 2 = long) */
1255 FALSE
, /* pc_relative */
1257 complain_overflow_bitfield
, /* complain_on_overflow */
1258 bfd_elf_generic_reloc
, /* special_function */
1259 AARCH64_R_STR (COPY
), /* name */
1260 TRUE
, /* partial_inplace */
1261 0xffffffff, /* src_mask */
1262 0xffffffff, /* dst_mask */
1263 FALSE
), /* pcrel_offset */
1265 HOWTO (AARCH64_R (GLOB_DAT
), /* type */
1267 2, /* size (0 = byte, 1 = short, 2 = long) */
1269 FALSE
, /* pc_relative */
1271 complain_overflow_bitfield
, /* complain_on_overflow */
1272 bfd_elf_generic_reloc
, /* special_function */
1273 AARCH64_R_STR (GLOB_DAT
), /* name */
1274 TRUE
, /* partial_inplace */
1275 0xffffffff, /* src_mask */
1276 0xffffffff, /* dst_mask */
1277 FALSE
), /* pcrel_offset */
1279 HOWTO (AARCH64_R (JUMP_SLOT
), /* type */
1281 2, /* size (0 = byte, 1 = short, 2 = long) */
1283 FALSE
, /* pc_relative */
1285 complain_overflow_bitfield
, /* complain_on_overflow */
1286 bfd_elf_generic_reloc
, /* special_function */
1287 AARCH64_R_STR (JUMP_SLOT
), /* name */
1288 TRUE
, /* partial_inplace */
1289 0xffffffff, /* src_mask */
1290 0xffffffff, /* dst_mask */
1291 FALSE
), /* pcrel_offset */
1293 HOWTO (AARCH64_R (RELATIVE
), /* type */
1295 2, /* size (0 = byte, 1 = short, 2 = long) */
1297 FALSE
, /* pc_relative */
1299 complain_overflow_bitfield
, /* complain_on_overflow */
1300 bfd_elf_generic_reloc
, /* special_function */
1301 AARCH64_R_STR (RELATIVE
), /* name */
1302 TRUE
, /* partial_inplace */
1303 ALL_ONES
, /* src_mask */
1304 ALL_ONES
, /* dst_mask */
1305 FALSE
), /* pcrel_offset */
1307 HOWTO (AARCH64_R (TLS_DTPMOD
), /* type */
1309 2, /* size (0 = byte, 1 = short, 2 = long) */
1311 FALSE
, /* pc_relative */
1313 complain_overflow_dont
, /* complain_on_overflow */
1314 bfd_elf_generic_reloc
, /* special_function */
1316 AARCH64_R_STR (TLS_DTPMOD64
), /* name */
1318 AARCH64_R_STR (TLS_DTPMOD
), /* name */
1320 FALSE
, /* partial_inplace */
1322 ALL_ONES
, /* dst_mask */
1323 FALSE
), /* pc_reloffset */
1325 HOWTO (AARCH64_R (TLS_DTPREL
), /* type */
1327 2, /* size (0 = byte, 1 = short, 2 = long) */
1329 FALSE
, /* pc_relative */
1331 complain_overflow_dont
, /* complain_on_overflow */
1332 bfd_elf_generic_reloc
, /* special_function */
1334 AARCH64_R_STR (TLS_DTPREL64
), /* name */
1336 AARCH64_R_STR (TLS_DTPREL
), /* name */
1338 FALSE
, /* partial_inplace */
1340 ALL_ONES
, /* dst_mask */
1341 FALSE
), /* pcrel_offset */
1343 HOWTO (AARCH64_R (TLS_TPREL
), /* type */
1345 2, /* size (0 = byte, 1 = short, 2 = long) */
1347 FALSE
, /* pc_relative */
1349 complain_overflow_dont
, /* complain_on_overflow */
1350 bfd_elf_generic_reloc
, /* special_function */
1352 AARCH64_R_STR (TLS_TPREL64
), /* name */
1354 AARCH64_R_STR (TLS_TPREL
), /* name */
1356 FALSE
, /* partial_inplace */
1358 ALL_ONES
, /* dst_mask */
1359 FALSE
), /* pcrel_offset */
1361 HOWTO (AARCH64_R (TLSDESC
), /* type */
1363 2, /* size (0 = byte, 1 = short, 2 = long) */
1365 FALSE
, /* pc_relative */
1367 complain_overflow_dont
, /* complain_on_overflow */
1368 bfd_elf_generic_reloc
, /* special_function */
1369 AARCH64_R_STR (TLSDESC
), /* name */
1370 FALSE
, /* partial_inplace */
1372 ALL_ONES
, /* dst_mask */
1373 FALSE
), /* pcrel_offset */
1375 HOWTO (AARCH64_R (IRELATIVE
), /* type */
1377 2, /* size (0 = byte, 1 = short, 2 = long) */
1379 FALSE
, /* pc_relative */
1381 complain_overflow_bitfield
, /* complain_on_overflow */
1382 bfd_elf_generic_reloc
, /* special_function */
1383 AARCH64_R_STR (IRELATIVE
), /* name */
1384 FALSE
, /* partial_inplace */
1386 ALL_ONES
, /* dst_mask */
1387 FALSE
), /* pcrel_offset */
1392 static reloc_howto_type elfNN_aarch64_howto_none
=
1393 HOWTO (R_AARCH64_NONE
, /* type */
1395 3, /* size (0 = byte, 1 = short, 2 = long) */
1397 FALSE
, /* pc_relative */
1399 complain_overflow_dont
,/* complain_on_overflow */
1400 bfd_elf_generic_reloc
, /* special_function */
1401 "R_AARCH64_NONE", /* name */
1402 FALSE
, /* partial_inplace */
1405 FALSE
); /* pcrel_offset */
1407 /* Given HOWTO, return the bfd internal relocation enumerator. */
1409 static bfd_reloc_code_real_type
1410 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type
*howto
)
1413 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table
);
1414 const ptrdiff_t offset
1415 = howto
- elfNN_aarch64_howto_table
;
1417 if (offset
> 0 && offset
< size
- 1)
1418 return BFD_RELOC_AARCH64_RELOC_START
+ offset
;
1420 if (howto
== &elfNN_aarch64_howto_none
)
1421 return BFD_RELOC_AARCH64_NONE
;
1423 return BFD_RELOC_AARCH64_RELOC_START
;
1426 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1428 static bfd_reloc_code_real_type
1429 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type
)
1431 static bfd_boolean initialized_p
= FALSE
;
1432 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1433 static unsigned int offsets
[R_AARCH64_end
];
1435 if (initialized_p
== FALSE
)
1439 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1440 if (elfNN_aarch64_howto_table
[i
].type
!= 0)
1441 offsets
[elfNN_aarch64_howto_table
[i
].type
] = i
;
1443 initialized_p
= TRUE
;
1446 if (r_type
== R_AARCH64_NONE
|| r_type
== R_AARCH64_NULL
)
1447 return BFD_RELOC_AARCH64_NONE
;
1449 /* PR 17512: file: b371e70a. */
1450 if (r_type
>= R_AARCH64_end
)
1452 _bfd_error_handler (_("Invalid AArch64 reloc number: %d"), r_type
);
1453 bfd_set_error (bfd_error_bad_value
);
1454 return BFD_RELOC_AARCH64_NONE
;
1457 return BFD_RELOC_AARCH64_RELOC_START
+ offsets
[r_type
];
1460 struct elf_aarch64_reloc_map
1462 bfd_reloc_code_real_type from
;
1463 bfd_reloc_code_real_type to
;
1466 /* Map bfd generic reloc to AArch64-specific reloc. */
1467 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map
[] =
1469 {BFD_RELOC_NONE
, BFD_RELOC_AARCH64_NONE
},
1471 /* Basic data relocations. */
1472 {BFD_RELOC_CTOR
, BFD_RELOC_AARCH64_NN
},
1473 {BFD_RELOC_64
, BFD_RELOC_AARCH64_64
},
1474 {BFD_RELOC_32
, BFD_RELOC_AARCH64_32
},
1475 {BFD_RELOC_16
, BFD_RELOC_AARCH64_16
},
1476 {BFD_RELOC_64_PCREL
, BFD_RELOC_AARCH64_64_PCREL
},
1477 {BFD_RELOC_32_PCREL
, BFD_RELOC_AARCH64_32_PCREL
},
1478 {BFD_RELOC_16_PCREL
, BFD_RELOC_AARCH64_16_PCREL
},
1481 /* Given the bfd internal relocation enumerator in CODE, return the
1482 corresponding howto entry. */
1484 static reloc_howto_type
*
1485 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code
)
1489 /* Convert bfd generic reloc to AArch64-specific reloc. */
1490 if (code
< BFD_RELOC_AARCH64_RELOC_START
1491 || code
> BFD_RELOC_AARCH64_RELOC_END
)
1492 for (i
= 0; i
< ARRAY_SIZE (elf_aarch64_reloc_map
); i
++)
1493 if (elf_aarch64_reloc_map
[i
].from
== code
)
1495 code
= elf_aarch64_reloc_map
[i
].to
;
1499 if (code
> BFD_RELOC_AARCH64_RELOC_START
1500 && code
< BFD_RELOC_AARCH64_RELOC_END
)
1501 if (elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
].type
)
1502 return &elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
];
1504 if (code
== BFD_RELOC_AARCH64_NONE
)
1505 return &elfNN_aarch64_howto_none
;
1510 static reloc_howto_type
*
1511 elfNN_aarch64_howto_from_type (unsigned int r_type
)
1513 bfd_reloc_code_real_type val
;
1514 reloc_howto_type
*howto
;
1519 bfd_set_error (bfd_error_bad_value
);
1524 if (r_type
== R_AARCH64_NONE
)
1525 return &elfNN_aarch64_howto_none
;
1527 val
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
1528 howto
= elfNN_aarch64_howto_from_bfd_reloc (val
);
1533 bfd_set_error (bfd_error_bad_value
);
1538 elfNN_aarch64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*bfd_reloc
,
1539 Elf_Internal_Rela
*elf_reloc
)
1541 unsigned int r_type
;
1543 r_type
= ELFNN_R_TYPE (elf_reloc
->r_info
);
1544 bfd_reloc
->howto
= elfNN_aarch64_howto_from_type (r_type
);
1547 static reloc_howto_type
*
1548 elfNN_aarch64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1549 bfd_reloc_code_real_type code
)
1551 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (code
);
1556 bfd_set_error (bfd_error_bad_value
);
1560 static reloc_howto_type
*
1561 elfNN_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1566 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1567 if (elfNN_aarch64_howto_table
[i
].name
!= NULL
1568 && strcasecmp (elfNN_aarch64_howto_table
[i
].name
, r_name
) == 0)
1569 return &elfNN_aarch64_howto_table
[i
];
1574 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
1575 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1576 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
1577 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1579 /* The linker script knows the section names for placement.
1580 The entry_names are used to do simple name mangling on the stubs.
1581 Given a function name, and its type, the stub can be found. The
1582 name can be changed. The only requirement is the %s be present. */
1583 #define STUB_ENTRY_NAME "__%s_veneer"
1585 /* The name of the dynamic interpreter. This is put in the .interp
1587 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1589 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1590 (((1 << 25) - 1) << 2)
1591 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1594 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1595 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1598 aarch64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
1600 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
1601 return offset
<= AARCH64_MAX_ADRP_IMM
&& offset
>= AARCH64_MIN_ADRP_IMM
;
1605 aarch64_valid_branch_p (bfd_vma value
, bfd_vma place
)
1607 bfd_signed_vma offset
= (bfd_signed_vma
) (value
- place
);
1608 return (offset
<= AARCH64_MAX_FWD_BRANCH_OFFSET
1609 && offset
>= AARCH64_MAX_BWD_BRANCH_OFFSET
);
1612 static const uint32_t aarch64_adrp_branch_stub
[] =
1614 0x90000010, /* adrp ip0, X */
1615 /* R_AARCH64_ADR_HI21_PCREL(X) */
1616 0x91000210, /* add ip0, ip0, :lo12:X */
1617 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
1618 0xd61f0200, /* br ip0 */
1621 static const uint32_t aarch64_long_branch_stub
[] =
1624 0x58000090, /* ldr ip0, 1f */
1626 0x18000090, /* ldr wip0, 1f */
1628 0x10000011, /* adr ip1, #0 */
1629 0x8b110210, /* add ip0, ip0, ip1 */
1630 0xd61f0200, /* br ip0 */
1631 0x00000000, /* 1: .xword or .word
1632 R_AARCH64_PRELNN(X) + 12
1637 static const uint32_t aarch64_erratum_835769_stub
[] =
1639 0x00000000, /* Placeholder for multiply accumulate. */
1640 0x14000000, /* b <label> */
1643 /* Section name for stubs is the associated section name plus this
1645 #define STUB_SUFFIX ".stub"
1647 enum elf_aarch64_stub_type
1650 aarch64_stub_adrp_branch
,
1651 aarch64_stub_long_branch
,
1652 aarch64_stub_erratum_835769_veneer
,
1655 struct elf_aarch64_stub_hash_entry
1657 /* Base hash table entry structure. */
1658 struct bfd_hash_entry root
;
1660 /* The stub section. */
1663 /* Offset within stub_sec of the beginning of this stub. */
1664 bfd_vma stub_offset
;
1666 /* Given the symbol's value and its section we can determine its final
1667 value when building the stubs (so the stub knows where to jump). */
1668 bfd_vma target_value
;
1669 asection
*target_section
;
1671 enum elf_aarch64_stub_type stub_type
;
1673 /* The symbol table entry, if any, that this was derived from. */
1674 struct elf_aarch64_link_hash_entry
*h
;
1676 /* Destination symbol type */
1677 unsigned char st_type
;
1679 /* Where this stub is being called from, or, in the case of combined
1680 stub sections, the first input section in the group. */
1683 /* The name for the local symbol at the start of this stub. The
1684 stub name in the hash table has to be unique; this does not, so
1685 it can be friendlier. */
1688 /* The instruction which caused this stub to be generated (only valid for
1689 erratum 835769 workaround stubs at present). */
1690 uint32_t veneered_insn
;
1693 /* Used to build a map of a section. This is required for mixed-endian
1696 typedef struct elf_elf_section_map
1701 elf_aarch64_section_map
;
1704 typedef struct _aarch64_elf_section_data
1706 struct bfd_elf_section_data elf
;
1707 unsigned int mapcount
;
1708 unsigned int mapsize
;
1709 elf_aarch64_section_map
*map
;
1711 _aarch64_elf_section_data
;
1713 #define elf_aarch64_section_data(sec) \
1714 ((_aarch64_elf_section_data *) elf_section_data (sec))
1716 /* A fix-descriptor for erratum 835769. */
1717 struct aarch64_erratum_835769_fix
1722 uint32_t veneered_insn
;
1724 enum elf_aarch64_stub_type stub_type
;
1727 /* The size of the thread control block which is defined to be two pointers. */
1728 #define TCB_SIZE (ARCH_SIZE/8)*2
1730 struct elf_aarch64_local_symbol
1732 unsigned int got_type
;
1733 bfd_signed_vma got_refcount
;
1736 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
1737 offset is from the end of the jump table and reserved entries
1740 The magic value (bfd_vma) -1 indicates that an offset has not be
1742 bfd_vma tlsdesc_got_jump_table_offset
;
1745 struct elf_aarch64_obj_tdata
1747 struct elf_obj_tdata root
;
1749 /* local symbol descriptors */
1750 struct elf_aarch64_local_symbol
*locals
;
1752 /* Zero to warn when linking objects with incompatible enum sizes. */
1753 int no_enum_size_warning
;
1755 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
1756 int no_wchar_size_warning
;
1759 #define elf_aarch64_tdata(bfd) \
1760 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
1762 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
1764 #define is_aarch64_elf(bfd) \
1765 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
1766 && elf_tdata (bfd) != NULL \
1767 && elf_object_id (bfd) == AARCH64_ELF_DATA)
1770 elfNN_aarch64_mkobject (bfd
*abfd
)
1772 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
),
1776 #define elf_aarch64_hash_entry(ent) \
1777 ((struct elf_aarch64_link_hash_entry *)(ent))
1779 #define GOT_UNKNOWN 0
1780 #define GOT_NORMAL 1
1781 #define GOT_TLS_GD 2
1782 #define GOT_TLS_IE 4
1783 #define GOT_TLSDESC_GD 8
1785 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
1787 /* AArch64 ELF linker hash entry. */
1788 struct elf_aarch64_link_hash_entry
1790 struct elf_link_hash_entry root
;
1792 /* Track dynamic relocs copied for this symbol. */
1793 struct elf_dyn_relocs
*dyn_relocs
;
1795 /* Since PLT entries have variable size, we need to record the
1796 index into .got.plt instead of recomputing it from the PLT
1798 bfd_signed_vma plt_got_offset
;
1800 /* Bit mask representing the type of GOT entry(s) if any required by
1802 unsigned int got_type
;
1804 /* A pointer to the most recently used stub hash entry against this
1806 struct elf_aarch64_stub_hash_entry
*stub_cache
;
1808 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
1809 is from the end of the jump table and reserved entries within the PLTGOT.
1811 The magic value (bfd_vma) -1 indicates that an offset has not
1813 bfd_vma tlsdesc_got_jump_table_offset
;
1817 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
1819 unsigned long r_symndx
)
1822 return elf_aarch64_hash_entry (h
)->got_type
;
1824 if (! elf_aarch64_locals (abfd
))
1827 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
1830 /* Get the AArch64 elf linker hash table from a link_info structure. */
1831 #define elf_aarch64_hash_table(info) \
1832 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
1834 #define aarch64_stub_hash_lookup(table, string, create, copy) \
1835 ((struct elf_aarch64_stub_hash_entry *) \
1836 bfd_hash_lookup ((table), (string), (create), (copy)))
1838 /* AArch64 ELF linker hash table. */
1839 struct elf_aarch64_link_hash_table
1841 /* The main hash table. */
1842 struct elf_link_hash_table root
;
1844 /* Nonzero to force PIC branch veneers. */
1847 /* Fix erratum 835769. */
1848 int fix_erratum_835769
;
1850 /* A table of fix locations for erratum 835769. This holds erratum
1851 fix locations between elfNN_aarch64_size_stubs() and
1852 elfNN_aarch64_write_section(). */
1853 struct aarch64_erratum_835769_fix
*aarch64_erratum_835769_fixes
;
1854 unsigned int num_aarch64_erratum_835769_fixes
;
1856 /* The number of bytes in the initial entry in the PLT. */
1857 bfd_size_type plt_header_size
;
1859 /* The number of bytes in the subsequent PLT etries. */
1860 bfd_size_type plt_entry_size
;
1862 /* Short-cuts to get to dynamic linker sections. */
1866 /* Small local sym cache. */
1867 struct sym_cache sym_cache
;
1869 /* For convenience in allocate_dynrelocs. */
1872 /* The amount of space used by the reserved portion of the sgotplt
1873 section, plus whatever space is used by the jump slots. */
1874 bfd_vma sgotplt_jump_table_size
;
1876 /* The stub hash table. */
1877 struct bfd_hash_table stub_hash_table
;
1879 /* Linker stub bfd. */
1882 /* Linker call-backs. */
1883 asection
*(*add_stub_section
) (const char *, asection
*);
1884 void (*layout_sections_again
) (void);
1886 /* Array to keep track of which stub sections have been created, and
1887 information on stub grouping. */
1890 /* This is the section to which stubs in the group will be
1893 /* The stub section. */
1897 /* Assorted information used by elfNN_aarch64_size_stubs. */
1898 unsigned int bfd_count
;
1900 asection
**input_list
;
1902 /* The offset into splt of the PLT entry for the TLS descriptor
1903 resolver. Special values are 0, if not necessary (or not found
1904 to be necessary yet), and -1 if needed but not determined
1906 bfd_vma tlsdesc_plt
;
1908 /* The GOT offset for the lazy trampoline. Communicated to the
1909 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
1910 indicates an offset is not allocated. */
1911 bfd_vma dt_tlsdesc_got
;
1913 /* Used by local STT_GNU_IFUNC symbols. */
1914 htab_t loc_hash_table
;
1915 void * loc_hash_memory
;
1918 /* Create an entry in an AArch64 ELF linker hash table. */
1920 static struct bfd_hash_entry
*
1921 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
1922 struct bfd_hash_table
*table
,
1925 struct elf_aarch64_link_hash_entry
*ret
=
1926 (struct elf_aarch64_link_hash_entry
*) entry
;
1928 /* Allocate the structure if it has not already been allocated by a
1931 ret
= bfd_hash_allocate (table
,
1932 sizeof (struct elf_aarch64_link_hash_entry
));
1934 return (struct bfd_hash_entry
*) ret
;
1936 /* Call the allocation method of the superclass. */
1937 ret
= ((struct elf_aarch64_link_hash_entry
*)
1938 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
1942 ret
->dyn_relocs
= NULL
;
1943 ret
->got_type
= GOT_UNKNOWN
;
1944 ret
->plt_got_offset
= (bfd_vma
) - 1;
1945 ret
->stub_cache
= NULL
;
1946 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
1949 return (struct bfd_hash_entry
*) ret
;
1952 /* Initialize an entry in the stub hash table. */
1954 static struct bfd_hash_entry
*
1955 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
1956 struct bfd_hash_table
*table
, const char *string
)
1958 /* Allocate the structure if it has not already been allocated by a
1962 entry
= bfd_hash_allocate (table
,
1964 elf_aarch64_stub_hash_entry
));
1969 /* Call the allocation method of the superclass. */
1970 entry
= bfd_hash_newfunc (entry
, table
, string
);
1973 struct elf_aarch64_stub_hash_entry
*eh
;
1975 /* Initialize the local fields. */
1976 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
1977 eh
->stub_sec
= NULL
;
1978 eh
->stub_offset
= 0;
1979 eh
->target_value
= 0;
1980 eh
->target_section
= NULL
;
1981 eh
->stub_type
= aarch64_stub_none
;
1989 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
1990 for local symbol so that we can handle local STT_GNU_IFUNC symbols
1991 as global symbol. We reuse indx and dynstr_index for local symbol
1992 hash since they aren't used by global symbols in this backend. */
1995 elfNN_aarch64_local_htab_hash (const void *ptr
)
1997 struct elf_link_hash_entry
*h
1998 = (struct elf_link_hash_entry
*) ptr
;
1999 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
2002 /* Compare local hash entries. */
2005 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
2007 struct elf_link_hash_entry
*h1
2008 = (struct elf_link_hash_entry
*) ptr1
;
2009 struct elf_link_hash_entry
*h2
2010 = (struct elf_link_hash_entry
*) ptr2
;
2012 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
2015 /* Find and/or create a hash entry for local symbol. */
2017 static struct elf_link_hash_entry
*
2018 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
2019 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2022 struct elf_aarch64_link_hash_entry e
, *ret
;
2023 asection
*sec
= abfd
->sections
;
2024 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
2025 ELFNN_R_SYM (rel
->r_info
));
2028 e
.root
.indx
= sec
->id
;
2029 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2030 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
2031 create
? INSERT
: NO_INSERT
);
2038 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
2042 ret
= (struct elf_aarch64_link_hash_entry
*)
2043 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
2044 sizeof (struct elf_aarch64_link_hash_entry
));
2047 memset (ret
, 0, sizeof (*ret
));
2048 ret
->root
.indx
= sec
->id
;
2049 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2050 ret
->root
.dynindx
= -1;
2056 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2059 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
2060 struct elf_link_hash_entry
*dir
,
2061 struct elf_link_hash_entry
*ind
)
2063 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
2065 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
2066 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
2068 if (eind
->dyn_relocs
!= NULL
)
2070 if (edir
->dyn_relocs
!= NULL
)
2072 struct elf_dyn_relocs
**pp
;
2073 struct elf_dyn_relocs
*p
;
2075 /* Add reloc counts against the indirect sym to the direct sym
2076 list. Merge any entries against the same section. */
2077 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
2079 struct elf_dyn_relocs
*q
;
2081 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
2082 if (q
->sec
== p
->sec
)
2084 q
->pc_count
+= p
->pc_count
;
2085 q
->count
+= p
->count
;
2092 *pp
= edir
->dyn_relocs
;
2095 edir
->dyn_relocs
= eind
->dyn_relocs
;
2096 eind
->dyn_relocs
= NULL
;
2099 if (ind
->root
.type
== bfd_link_hash_indirect
)
2101 /* Copy over PLT info. */
2102 if (dir
->got
.refcount
<= 0)
2104 edir
->got_type
= eind
->got_type
;
2105 eind
->got_type
= GOT_UNKNOWN
;
2109 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2112 /* Destroy an AArch64 elf linker hash table. */
2115 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
2117 struct elf_aarch64_link_hash_table
*ret
2118 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
2120 if (ret
->loc_hash_table
)
2121 htab_delete (ret
->loc_hash_table
);
2122 if (ret
->loc_hash_memory
)
2123 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
2125 bfd_hash_table_free (&ret
->stub_hash_table
);
2126 _bfd_elf_link_hash_table_free (obfd
);
2129 /* Create an AArch64 elf linker hash table. */
2131 static struct bfd_link_hash_table
*
2132 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
2134 struct elf_aarch64_link_hash_table
*ret
;
2135 bfd_size_type amt
= sizeof (struct elf_aarch64_link_hash_table
);
2137 ret
= bfd_zmalloc (amt
);
2141 if (!_bfd_elf_link_hash_table_init
2142 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
2143 sizeof (struct elf_aarch64_link_hash_entry
), AARCH64_ELF_DATA
))
2149 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
2150 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
2152 ret
->dt_tlsdesc_got
= (bfd_vma
) - 1;
2154 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
2155 sizeof (struct elf_aarch64_stub_hash_entry
)))
2157 _bfd_elf_link_hash_table_free (abfd
);
2161 ret
->loc_hash_table
= htab_try_create (1024,
2162 elfNN_aarch64_local_htab_hash
,
2163 elfNN_aarch64_local_htab_eq
,
2165 ret
->loc_hash_memory
= objalloc_create ();
2166 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
2168 elfNN_aarch64_link_hash_table_free (abfd
);
2171 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
2173 return &ret
->root
.root
;
2177 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
2178 bfd_vma offset
, bfd_vma value
)
2180 reloc_howto_type
*howto
;
2183 howto
= elfNN_aarch64_howto_from_type (r_type
);
2184 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
2187 r_type
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
2188 value
= _bfd_aarch64_elf_resolve_relocation (r_type
, place
, value
, 0, FALSE
);
2189 return _bfd_aarch64_elf_put_addend (input_bfd
,
2190 input_section
->contents
+ offset
, r_type
,
2194 static enum elf_aarch64_stub_type
2195 aarch64_select_branch_stub (bfd_vma value
, bfd_vma place
)
2197 if (aarch64_valid_for_adrp_p (value
, place
))
2198 return aarch64_stub_adrp_branch
;
2199 return aarch64_stub_long_branch
;
2202 /* Determine the type of stub needed, if any, for a call. */
2204 static enum elf_aarch64_stub_type
2205 aarch64_type_of_stub (struct bfd_link_info
*info
,
2206 asection
*input_sec
,
2207 const Elf_Internal_Rela
*rel
,
2208 unsigned char st_type
,
2209 struct elf_aarch64_link_hash_entry
*hash
,
2210 bfd_vma destination
)
2213 bfd_signed_vma branch_offset
;
2214 unsigned int r_type
;
2215 struct elf_aarch64_link_hash_table
*globals
;
2216 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
2217 bfd_boolean via_plt_p
;
2219 if (st_type
!= STT_FUNC
)
2222 globals
= elf_aarch64_hash_table (info
);
2223 via_plt_p
= (globals
->root
.splt
!= NULL
&& hash
!= NULL
2224 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1);
2229 /* Determine where the call point is. */
2230 location
= (input_sec
->output_offset
2231 + input_sec
->output_section
->vma
+ rel
->r_offset
);
2233 branch_offset
= (bfd_signed_vma
) (destination
- location
);
2235 r_type
= ELFNN_R_TYPE (rel
->r_info
);
2237 /* We don't want to redirect any old unconditional jump in this way,
2238 only one which is being used for a sibcall, where it is
2239 acceptable for the IP0 and IP1 registers to be clobbered. */
2240 if ((r_type
== AARCH64_R (CALL26
) || r_type
== AARCH64_R (JUMP26
))
2241 && (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
2242 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
))
2244 stub_type
= aarch64_stub_long_branch
;
2250 /* Build a name for an entry in the stub hash table. */
2253 elfNN_aarch64_stub_name (const asection
*input_section
,
2254 const asection
*sym_sec
,
2255 const struct elf_aarch64_link_hash_entry
*hash
,
2256 const Elf_Internal_Rela
*rel
)
2263 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
2264 stub_name
= bfd_malloc (len
);
2265 if (stub_name
!= NULL
)
2266 snprintf (stub_name
, len
, "%08x_%s+%" BFD_VMA_FMT
"x",
2267 (unsigned int) input_section
->id
,
2268 hash
->root
.root
.root
.string
,
2273 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2274 stub_name
= bfd_malloc (len
);
2275 if (stub_name
!= NULL
)
2276 snprintf (stub_name
, len
, "%08x_%x:%x+%" BFD_VMA_FMT
"x",
2277 (unsigned int) input_section
->id
,
2278 (unsigned int) sym_sec
->id
,
2279 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
2286 /* Look up an entry in the stub hash. Stub entries are cached because
2287 creating the stub name takes a bit of time. */
2289 static struct elf_aarch64_stub_hash_entry
*
2290 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
2291 const asection
*sym_sec
,
2292 struct elf_link_hash_entry
*hash
,
2293 const Elf_Internal_Rela
*rel
,
2294 struct elf_aarch64_link_hash_table
*htab
)
2296 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2297 struct elf_aarch64_link_hash_entry
*h
=
2298 (struct elf_aarch64_link_hash_entry
*) hash
;
2299 const asection
*id_sec
;
2301 if ((input_section
->flags
& SEC_CODE
) == 0)
2304 /* If this input section is part of a group of sections sharing one
2305 stub section, then use the id of the first section in the group.
2306 Stub names need to include a section id, as there may well be
2307 more than one stub used to reach say, printf, and we need to
2308 distinguish between them. */
2309 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
2311 if (h
!= NULL
&& h
->stub_cache
!= NULL
2312 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
2314 stub_entry
= h
->stub_cache
;
2320 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
);
2321 if (stub_name
== NULL
)
2324 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
2325 stub_name
, FALSE
, FALSE
);
2327 h
->stub_cache
= stub_entry
;
2335 /* Add a new stub entry to the stub hash. Not all fields of the new
2336 stub entry are initialised. */
2338 static struct elf_aarch64_stub_hash_entry
*
2339 elfNN_aarch64_add_stub (const char *stub_name
,
2341 struct elf_aarch64_link_hash_table
*htab
)
2345 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2347 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2348 stub_sec
= htab
->stub_group
[section
->id
].stub_sec
;
2349 if (stub_sec
== NULL
)
2351 stub_sec
= htab
->stub_group
[link_sec
->id
].stub_sec
;
2352 if (stub_sec
== NULL
)
2358 namelen
= strlen (link_sec
->name
);
2359 len
= namelen
+ sizeof (STUB_SUFFIX
);
2360 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
2364 memcpy (s_name
, link_sec
->name
, namelen
);
2365 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
2366 stub_sec
= (*htab
->add_stub_section
) (s_name
, link_sec
);
2367 if (stub_sec
== NULL
)
2369 htab
->stub_group
[link_sec
->id
].stub_sec
= stub_sec
;
2371 htab
->stub_group
[section
->id
].stub_sec
= stub_sec
;
2374 /* Enter this entry into the linker stub hash table. */
2375 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2377 if (stub_entry
== NULL
)
2379 (*_bfd_error_handler
) (_("%s: cannot create stub entry %s"),
2380 section
->owner
, stub_name
);
2384 stub_entry
->stub_sec
= stub_sec
;
2385 stub_entry
->stub_offset
= 0;
2386 stub_entry
->id_sec
= link_sec
;
2392 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
2393 void *in_arg ATTRIBUTE_UNUSED
)
2395 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2400 bfd_vma veneered_insn_loc
;
2401 bfd_vma veneer_entry_loc
;
2402 bfd_signed_vma branch_offset
= 0;
2403 unsigned int template_size
;
2404 const uint32_t *template;
2407 /* Massage our args to the form they really have. */
2408 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2410 stub_sec
= stub_entry
->stub_sec
;
2412 /* Make a note of the offset within the stubs for this entry. */
2413 stub_entry
->stub_offset
= stub_sec
->size
;
2414 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
2416 stub_bfd
= stub_sec
->owner
;
2418 /* This is the address of the stub destination. */
2419 sym_value
= (stub_entry
->target_value
2420 + stub_entry
->target_section
->output_offset
2421 + stub_entry
->target_section
->output_section
->vma
);
2423 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
2425 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
2426 + stub_sec
->output_offset
);
2428 /* See if we can relax the stub. */
2429 if (aarch64_valid_for_adrp_p (sym_value
, place
))
2430 stub_entry
->stub_type
= aarch64_select_branch_stub (sym_value
, place
);
2433 switch (stub_entry
->stub_type
)
2435 case aarch64_stub_adrp_branch
:
2436 template = aarch64_adrp_branch_stub
;
2437 template_size
= sizeof (aarch64_adrp_branch_stub
);
2439 case aarch64_stub_long_branch
:
2440 template = aarch64_long_branch_stub
;
2441 template_size
= sizeof (aarch64_long_branch_stub
);
2443 case aarch64_stub_erratum_835769_veneer
:
2444 template = aarch64_erratum_835769_stub
;
2445 template_size
= sizeof (aarch64_erratum_835769_stub
);
2452 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
2454 bfd_putl32 (template[i
], loc
);
2458 template_size
= (template_size
+ 7) & ~7;
2459 stub_sec
->size
+= template_size
;
2461 switch (stub_entry
->stub_type
)
2463 case aarch64_stub_adrp_branch
:
2464 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
2465 stub_entry
->stub_offset
, sym_value
))
2466 /* The stub would not have been relaxed if the offset was out
2470 _bfd_final_link_relocate
2471 (elfNN_aarch64_howto_from_type (AARCH64_R (ADD_ABS_LO12_NC
)),
2475 stub_entry
->stub_offset
+ 4,
2480 case aarch64_stub_long_branch
:
2481 /* We want the value relative to the address 12 bytes back from the
2483 _bfd_final_link_relocate (elfNN_aarch64_howto_from_type
2484 (AARCH64_R (PRELNN
)), stub_bfd
, stub_sec
,
2486 stub_entry
->stub_offset
+ 16,
2490 case aarch64_stub_erratum_835769_veneer
:
2491 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
2492 + stub_entry
->target_section
->output_offset
2493 + stub_entry
->target_value
;
2494 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
2495 + stub_entry
->stub_sec
->output_offset
2496 + stub_entry
->stub_offset
;
2497 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
2498 branch_offset
>>= 2;
2499 branch_offset
&= 0x3ffffff;
2500 bfd_putl32 (stub_entry
->veneered_insn
,
2501 stub_sec
->contents
+ stub_entry
->stub_offset
);
2502 bfd_putl32 (template[1] | branch_offset
,
2503 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
2513 /* As above, but don't actually build the stub. Just bump offset so
2514 we know stub section sizes. */
2517 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
,
2518 void *in_arg ATTRIBUTE_UNUSED
)
2520 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2523 /* Massage our args to the form they really have. */
2524 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2526 switch (stub_entry
->stub_type
)
2528 case aarch64_stub_adrp_branch
:
2529 size
= sizeof (aarch64_adrp_branch_stub
);
2531 case aarch64_stub_long_branch
:
2532 size
= sizeof (aarch64_long_branch_stub
);
2534 case aarch64_stub_erratum_835769_veneer
:
2535 size
= sizeof (aarch64_erratum_835769_stub
);
2543 size
= (size
+ 7) & ~7;
2544 stub_entry
->stub_sec
->size
+= size
;
2548 /* External entry points for sizing and building linker stubs. */
2550 /* Set up various things so that we can make a list of input sections
2551 for each output section included in the link. Returns -1 on error,
2552 0 when no stubs will be needed, and 1 on success. */
2555 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
2556 struct bfd_link_info
*info
)
2559 unsigned int bfd_count
;
2560 int top_id
, top_index
;
2562 asection
**input_list
, **list
;
2564 struct elf_aarch64_link_hash_table
*htab
=
2565 elf_aarch64_hash_table (info
);
2567 if (!is_elf_hash_table (htab
))
2570 /* Count the number of input BFDs and find the top input section id. */
2571 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
2572 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
2575 for (section
= input_bfd
->sections
;
2576 section
!= NULL
; section
= section
->next
)
2578 if (top_id
< section
->id
)
2579 top_id
= section
->id
;
2582 htab
->bfd_count
= bfd_count
;
2584 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
2585 htab
->stub_group
= bfd_zmalloc (amt
);
2586 if (htab
->stub_group
== NULL
)
2589 /* We can't use output_bfd->section_count here to find the top output
2590 section index as some sections may have been removed, and
2591 _bfd_strip_section_from_output doesn't renumber the indices. */
2592 for (section
= output_bfd
->sections
, top_index
= 0;
2593 section
!= NULL
; section
= section
->next
)
2595 if (top_index
< section
->index
)
2596 top_index
= section
->index
;
2599 htab
->top_index
= top_index
;
2600 amt
= sizeof (asection
*) * (top_index
+ 1);
2601 input_list
= bfd_malloc (amt
);
2602 htab
->input_list
= input_list
;
2603 if (input_list
== NULL
)
2606 /* For sections we aren't interested in, mark their entries with a
2607 value we can check later. */
2608 list
= input_list
+ top_index
;
2610 *list
= bfd_abs_section_ptr
;
2611 while (list
-- != input_list
);
2613 for (section
= output_bfd
->sections
;
2614 section
!= NULL
; section
= section
->next
)
2616 if ((section
->flags
& SEC_CODE
) != 0)
2617 input_list
[section
->index
] = NULL
;
2623 /* Used by elfNN_aarch64_next_input_section and group_sections. */
2624 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
2626 /* The linker repeatedly calls this function for each input section,
2627 in the order that input sections are linked into output sections.
2628 Build lists of input sections to determine groupings between which
2629 we may insert linker stubs. */
2632 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
2634 struct elf_aarch64_link_hash_table
*htab
=
2635 elf_aarch64_hash_table (info
);
2637 if (isec
->output_section
->index
<= htab
->top_index
)
2639 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
2641 if (*list
!= bfd_abs_section_ptr
)
2643 /* Steal the link_sec pointer for our list. */
2644 /* This happens to make the list in reverse order,
2645 which is what we want. */
2646 PREV_SEC (isec
) = *list
;
2652 /* See whether we can group stub sections together. Grouping stub
2653 sections may result in fewer stubs. More importantly, we need to
2654 put all .init* and .fini* stubs at the beginning of the .init or
2655 .fini output sections respectively, because glibc splits the
2656 _init and _fini functions into multiple parts. Putting a stub in
2657 the middle of a function is not a good idea. */
2660 group_sections (struct elf_aarch64_link_hash_table
*htab
,
2661 bfd_size_type stub_group_size
,
2662 bfd_boolean stubs_always_before_branch
)
2664 asection
**list
= htab
->input_list
+ htab
->top_index
;
2668 asection
*tail
= *list
;
2670 if (tail
== bfd_abs_section_ptr
)
2673 while (tail
!= NULL
)
2677 bfd_size_type total
;
2681 while ((prev
= PREV_SEC (curr
)) != NULL
2682 && ((total
+= curr
->output_offset
- prev
->output_offset
)
2686 /* OK, the size from the start of CURR to the end is less
2687 than stub_group_size and thus can be handled by one stub
2688 section. (Or the tail section is itself larger than
2689 stub_group_size, in which case we may be toast.)
2690 We should really be keeping track of the total size of
2691 stubs added here, as stubs contribute to the final output
2695 prev
= PREV_SEC (tail
);
2696 /* Set up this stub group. */
2697 htab
->stub_group
[tail
->id
].link_sec
= curr
;
2699 while (tail
!= curr
&& (tail
= prev
) != NULL
);
2701 /* But wait, there's more! Input sections up to stub_group_size
2702 bytes before the stub section can be handled by it too. */
2703 if (!stubs_always_before_branch
)
2707 && ((total
+= tail
->output_offset
- prev
->output_offset
)
2711 prev
= PREV_SEC (tail
);
2712 htab
->stub_group
[tail
->id
].link_sec
= curr
;
2718 while (list
-- != htab
->input_list
);
2720 free (htab
->input_list
);
2725 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
2727 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
2728 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
2729 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
2730 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
2731 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
2732 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
2734 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
2735 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
2736 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
2737 #define AARCH64_ZR 0x1f
2739 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
2740 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
2742 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
2743 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
2744 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
2745 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
2746 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
2747 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
2748 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
2749 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
2750 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
2751 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
2752 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
2753 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
2754 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
2755 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
2756 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
2757 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
2758 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
2759 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
2761 /* Classify an INSN if it is indeed a load/store. Return TRUE if INSN
2762 is a load/store along with the Rt and Rtn. Return FALSE if not a
2766 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rtn
,
2767 bfd_boolean
*pair
, bfd_boolean
*load
)
2775 /* Bail out quickly if INSN doesn't fall into the the load-store
2777 if (!AARCH64_LDST (insn
))
2782 if (AARCH64_LDST_EX (insn
))
2784 *rt
= AARCH64_RT (insn
);
2786 if (AARCH64_BIT (insn
, 21) == 1)
2789 *rtn
= AARCH64_RT2 (insn
);
2791 *load
= AARCH64_LD (insn
);
2794 else if (AARCH64_LDST_NAP (insn
)
2795 || AARCH64_LDSTP_PI (insn
)
2796 || AARCH64_LDSTP_O (insn
)
2797 || AARCH64_LDSTP_PRE (insn
))
2800 *rt
= AARCH64_RT (insn
);
2801 *rtn
= AARCH64_RT2 (insn
);
2802 *load
= AARCH64_LD (insn
);
2805 else if (AARCH64_LDST_PCREL (insn
)
2806 || AARCH64_LDST_UI (insn
)
2807 || AARCH64_LDST_PIIMM (insn
)
2808 || AARCH64_LDST_U (insn
)
2809 || AARCH64_LDST_PREIMM (insn
)
2810 || AARCH64_LDST_RO (insn
)
2811 || AARCH64_LDST_UIMM (insn
))
2813 *rt
= AARCH64_RT (insn
);
2815 if (AARCH64_LDST_PCREL (insn
))
2817 opc
= AARCH64_BITS (insn
, 22, 2);
2818 v
= AARCH64_BIT (insn
, 26);
2819 opc_v
= opc
| (v
<< 2);
2820 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
2821 || opc_v
== 5 || opc_v
== 7);
2824 else if (AARCH64_LDST_SIMD_M (insn
)
2825 || AARCH64_LDST_SIMD_M_PI (insn
))
2827 *rt
= AARCH64_RT (insn
);
2828 *load
= AARCH64_BIT (insn
, 22);
2829 opcode
= (insn
>> 12) & 0xf;
2856 else if (AARCH64_LDST_SIMD_S (insn
)
2857 || AARCH64_LDST_SIMD_S_PI (insn
))
2859 *rt
= AARCH64_RT (insn
);
2860 r
= (insn
>> 21) & 1;
2861 *load
= AARCH64_BIT (insn
, 22);
2862 opcode
= (insn
>> 13) & 0x7;
2874 *rtn
= *rt
+ (r
== 0 ? 2 : 3);
2882 *rtn
= *rt
+ (r
== 0 ? 2 : 3);
2894 /* Return TRUE if INSN is multiply-accumulate. */
2897 aarch64_mlxl_p (uint32_t insn
)
2899 uint32_t op31
= AARCH64_OP31 (insn
);
2901 if (AARCH64_MAC (insn
)
2902 && (op31
== 0 || op31
== 1 || op31
== 5)
2903 /* Exclude MUL instructions which are encoded as a multiple accumulate
2905 && AARCH64_RA (insn
) != AARCH64_ZR
)
2911 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
2912 it is possible for a 64-bit multiply-accumulate instruction to generate an
2913 incorrect result. The details are quite complex and hard to
2914 determine statically, since branches in the code may exist in some
2915 circumstances, but all cases end with a memory (load, store, or
2916 prefetch) instruction followed immediately by the multiply-accumulate
2917 operation. We employ a linker patching technique, by moving the potentially
2918 affected multiply-accumulate instruction into a patch region and replacing
2919 the original instruction with a branch to the patch. This function checks
2920 if INSN_1 is the memory operation followed by a multiply-accumulate
2921 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
2922 if INSN_1 and INSN_2 are safe. */
2925 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
2935 if (aarch64_mlxl_p (insn_2
)
2936 && aarch64_mem_op_p (insn_1
, &rt
, &rtn
, &pair
, &load
))
2938 /* Any SIMD memory op is independent of the subsequent MLA
2939 by definition of the erratum. */
2940 if (AARCH64_BIT (insn_1
, 26))
2943 /* If not SIMD, check for integer memory ops and MLA relationship. */
2944 rn
= AARCH64_RN (insn_2
);
2945 ra
= AARCH64_RA (insn_2
);
2946 rm
= AARCH64_RM (insn_2
);
2948 /* If this is a load and there's a true(RAW) dependency, we are safe
2949 and this is not an erratum sequence. */
2951 (rt
== rn
|| rt
== rm
|| rt
== ra
2952 || (pair
&& (rtn
== rn
|| rtn
== rm
|| rtn
== ra
))))
2955 /* We conservatively put out stubs for all other cases (including
2963 /* Used to order a list of mapping symbols by address. */
2966 elf_aarch64_compare_mapping (const void *a
, const void *b
)
2968 const elf_aarch64_section_map
*amap
= (const elf_aarch64_section_map
*) a
;
2969 const elf_aarch64_section_map
*bmap
= (const elf_aarch64_section_map
*) b
;
2971 if (amap
->vma
> bmap
->vma
)
2973 else if (amap
->vma
< bmap
->vma
)
2975 else if (amap
->type
> bmap
->type
)
2976 /* Ensure results do not depend on the host qsort for objects with
2977 multiple mapping symbols at the same address by sorting on type
2980 else if (amap
->type
< bmap
->type
)
2987 erratum_835769_scan (bfd
*input_bfd
,
2988 struct bfd_link_info
*info
,
2989 struct aarch64_erratum_835769_fix
**fixes_p
,
2990 unsigned int *num_fixes_p
,
2991 unsigned int *fix_table_size_p
)
2994 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
2995 struct aarch64_erratum_835769_fix
*fixes
= *fixes_p
;
2996 unsigned int num_fixes
= *num_fixes_p
;
2997 unsigned int fix_table_size
= *fix_table_size_p
;
3002 for (section
= input_bfd
->sections
;
3004 section
= section
->next
)
3006 bfd_byte
*contents
= NULL
;
3007 struct _aarch64_elf_section_data
*sec_data
;
3010 if (elf_section_type (section
) != SHT_PROGBITS
3011 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3012 || (section
->flags
& SEC_EXCLUDE
) != 0
3013 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3014 || (section
->output_section
== bfd_abs_section_ptr
))
3017 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3018 contents
= elf_section_data (section
)->this_hdr
.contents
;
3019 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3022 sec_data
= elf_aarch64_section_data (section
);
3024 qsort (sec_data
->map
, sec_data
->mapcount
,
3025 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3027 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3029 unsigned int span_start
= sec_data
->map
[span
].vma
;
3030 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3031 ? sec_data
->map
[0].vma
+ section
->size
3032 : sec_data
->map
[span
+ 1].vma
);
3034 char span_type
= sec_data
->map
[span
].type
;
3036 if (span_type
== 'd')
3039 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
3041 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3042 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3044 if (aarch64_erratum_sequence (insn_1
, insn_2
))
3046 char *stub_name
= NULL
;
3047 stub_name
= (char *) bfd_malloc
3048 (strlen ("__erratum_835769_veneer_") + 16);
3049 if (stub_name
!= NULL
)
3051 (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
3055 if (num_fixes
== fix_table_size
)
3057 fix_table_size
*= 2;
3059 (struct aarch64_erratum_835769_fix
*)
3061 sizeof (struct aarch64_erratum_835769_fix
)
3067 fixes
[num_fixes
].input_bfd
= input_bfd
;
3068 fixes
[num_fixes
].section
= section
;
3069 fixes
[num_fixes
].offset
= i
+ 4;
3070 fixes
[num_fixes
].veneered_insn
= insn_2
;
3071 fixes
[num_fixes
].stub_name
= stub_name
;
3072 fixes
[num_fixes
].stub_type
= aarch64_stub_erratum_835769_veneer
;
3077 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3082 *num_fixes_p
= num_fixes
;
3083 *fix_table_size_p
= fix_table_size
;
3087 /* Find or create a stub section. Returns a pointer to the stub section, and
3088 the section to which the stub section will be attached (in *LINK_SEC_P).
3089 LINK_SEC_P may be NULL. */
3092 elf_aarch64_create_or_find_stub_sec (asection
**link_sec_p
, asection
*section
,
3093 struct elf_aarch64_link_hash_table
*htab
)
3098 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3099 BFD_ASSERT (link_sec
!= NULL
);
3100 stub_sec
= htab
->stub_group
[section
->id
].stub_sec
;
3102 if (stub_sec
== NULL
)
3104 stub_sec
= htab
->stub_group
[link_sec
->id
].stub_sec
;
3105 if (stub_sec
== NULL
)
3111 namelen
= strlen (link_sec
->name
);
3112 len
= namelen
+ sizeof (STUB_SUFFIX
);
3113 s_name
= (char *) bfd_alloc (htab
->stub_bfd
, len
);
3117 memcpy (s_name
, link_sec
->name
, namelen
);
3118 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
3119 stub_sec
= (*htab
->add_stub_section
) (s_name
, link_sec
);
3121 if (stub_sec
== NULL
)
3123 htab
->stub_group
[link_sec
->id
].stub_sec
= stub_sec
;
3125 htab
->stub_group
[section
->id
].stub_sec
= stub_sec
;
3129 *link_sec_p
= link_sec
;
3134 /* Determine and set the size of the stub section for a final link.
3136 The basic idea here is to examine all the relocations looking for
3137 PC-relative calls to a target that is unreachable with a "bl"
3141 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
3143 struct bfd_link_info
*info
,
3144 bfd_signed_vma group_size
,
3145 asection
* (*add_stub_section
) (const char *,
3147 void (*layout_sections_again
) (void))
3149 bfd_size_type stub_group_size
;
3150 bfd_boolean stubs_always_before_branch
;
3151 bfd_boolean stub_changed
= 0;
3152 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3153 struct aarch64_erratum_835769_fix
*erratum_835769_fixes
= NULL
;
3154 unsigned int num_erratum_835769_fixes
= 0;
3155 unsigned int erratum_835769_fix_table_size
= 10;
3158 if (htab
->fix_erratum_835769
)
3160 erratum_835769_fixes
3161 = (struct aarch64_erratum_835769_fix
*)
3163 (sizeof (struct aarch64_erratum_835769_fix
) *
3164 erratum_835769_fix_table_size
);
3165 if (erratum_835769_fixes
== NULL
)
3166 goto error_ret_free_local
;
3169 /* Propagate mach to stub bfd, because it may not have been
3170 finalized when we created stub_bfd. */
3171 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
3172 bfd_get_mach (output_bfd
));
3174 /* Stash our params away. */
3175 htab
->stub_bfd
= stub_bfd
;
3176 htab
->add_stub_section
= add_stub_section
;
3177 htab
->layout_sections_again
= layout_sections_again
;
3178 stubs_always_before_branch
= group_size
< 0;
3180 stub_group_size
= -group_size
;
3182 stub_group_size
= group_size
;
3184 if (stub_group_size
== 1)
3186 /* Default values. */
3187 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
3188 stub_group_size
= 127 * 1024 * 1024;
3191 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
3196 unsigned int bfd_indx
;
3198 unsigned prev_num_erratum_835769_fixes
= num_erratum_835769_fixes
;
3200 num_erratum_835769_fixes
= 0;
3201 for (input_bfd
= info
->input_bfds
, bfd_indx
= 0;
3202 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
, bfd_indx
++)
3204 Elf_Internal_Shdr
*symtab_hdr
;
3206 Elf_Internal_Sym
*local_syms
= NULL
;
3208 /* We'll need the symbol table in a second. */
3209 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3210 if (symtab_hdr
->sh_info
== 0)
3213 /* Walk over each section attached to the input bfd. */
3214 for (section
= input_bfd
->sections
;
3215 section
!= NULL
; section
= section
->next
)
3217 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
3219 /* If there aren't any relocs, then there's nothing more
3221 if ((section
->flags
& SEC_RELOC
) == 0
3222 || section
->reloc_count
== 0
3223 || (section
->flags
& SEC_CODE
) == 0)
3226 /* If this section is a link-once section that will be
3227 discarded, then don't create any stubs. */
3228 if (section
->output_section
== NULL
3229 || section
->output_section
->owner
!= output_bfd
)
3232 /* Get the relocs. */
3234 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
3235 NULL
, info
->keep_memory
);
3236 if (internal_relocs
== NULL
)
3237 goto error_ret_free_local
;
3239 /* Now examine each relocation. */
3240 irela
= internal_relocs
;
3241 irelaend
= irela
+ section
->reloc_count
;
3242 for (; irela
< irelaend
; irela
++)
3244 unsigned int r_type
, r_indx
;
3245 enum elf_aarch64_stub_type stub_type
;
3246 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3249 bfd_vma destination
;
3250 struct elf_aarch64_link_hash_entry
*hash
;
3251 const char *sym_name
;
3253 const asection
*id_sec
;
3254 unsigned char st_type
;
3257 r_type
= ELFNN_R_TYPE (irela
->r_info
);
3258 r_indx
= ELFNN_R_SYM (irela
->r_info
);
3260 if (r_type
>= (unsigned int) R_AARCH64_end
)
3262 bfd_set_error (bfd_error_bad_value
);
3263 error_ret_free_internal
:
3264 if (elf_section_data (section
)->relocs
== NULL
)
3265 free (internal_relocs
);
3266 goto error_ret_free_local
;
3269 /* Only look for stubs on unconditional branch and
3270 branch and link instructions. */
3271 if (r_type
!= (unsigned int) AARCH64_R (CALL26
)
3272 && r_type
!= (unsigned int) AARCH64_R (JUMP26
))
3275 /* Now determine the call target, its name, value,
3282 if (r_indx
< symtab_hdr
->sh_info
)
3284 /* It's a local symbol. */
3285 Elf_Internal_Sym
*sym
;
3286 Elf_Internal_Shdr
*hdr
;
3288 if (local_syms
== NULL
)
3291 = (Elf_Internal_Sym
*) symtab_hdr
->contents
;
3292 if (local_syms
== NULL
)
3294 = bfd_elf_get_elf_syms (input_bfd
, symtab_hdr
,
3295 symtab_hdr
->sh_info
, 0,
3297 if (local_syms
== NULL
)
3298 goto error_ret_free_internal
;
3301 sym
= local_syms
+ r_indx
;
3302 hdr
= elf_elfsections (input_bfd
)[sym
->st_shndx
];
3303 sym_sec
= hdr
->bfd_section
;
3305 /* This is an undefined symbol. It can never
3309 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
3310 sym_value
= sym
->st_value
;
3311 destination
= (sym_value
+ irela
->r_addend
3312 + sym_sec
->output_offset
3313 + sym_sec
->output_section
->vma
);
3314 st_type
= ELF_ST_TYPE (sym
->st_info
);
3316 = bfd_elf_string_from_elf_section (input_bfd
,
3317 symtab_hdr
->sh_link
,
3324 e_indx
= r_indx
- symtab_hdr
->sh_info
;
3325 hash
= ((struct elf_aarch64_link_hash_entry
*)
3326 elf_sym_hashes (input_bfd
)[e_indx
]);
3328 while (hash
->root
.root
.type
== bfd_link_hash_indirect
3329 || hash
->root
.root
.type
== bfd_link_hash_warning
)
3330 hash
= ((struct elf_aarch64_link_hash_entry
*)
3331 hash
->root
.root
.u
.i
.link
);
3333 if (hash
->root
.root
.type
== bfd_link_hash_defined
3334 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
3336 struct elf_aarch64_link_hash_table
*globals
=
3337 elf_aarch64_hash_table (info
);
3338 sym_sec
= hash
->root
.root
.u
.def
.section
;
3339 sym_value
= hash
->root
.root
.u
.def
.value
;
3340 /* For a destination in a shared library,
3341 use the PLT stub as target address to
3342 decide whether a branch stub is
3344 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
3345 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
3347 sym_sec
= globals
->root
.splt
;
3348 sym_value
= hash
->root
.plt
.offset
;
3349 if (sym_sec
->output_section
!= NULL
)
3350 destination
= (sym_value
3351 + sym_sec
->output_offset
3353 sym_sec
->output_section
->vma
);
3355 else if (sym_sec
->output_section
!= NULL
)
3356 destination
= (sym_value
+ irela
->r_addend
3357 + sym_sec
->output_offset
3358 + sym_sec
->output_section
->vma
);
3360 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
3361 || (hash
->root
.root
.type
3362 == bfd_link_hash_undefweak
))
3364 /* For a shared library, use the PLT stub as
3365 target address to decide whether a long
3366 branch stub is needed.
3367 For absolute code, they cannot be handled. */
3368 struct elf_aarch64_link_hash_table
*globals
=
3369 elf_aarch64_hash_table (info
);
3371 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
3372 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
3374 sym_sec
= globals
->root
.splt
;
3375 sym_value
= hash
->root
.plt
.offset
;
3376 if (sym_sec
->output_section
!= NULL
)
3377 destination
= (sym_value
3378 + sym_sec
->output_offset
3380 sym_sec
->output_section
->vma
);
3387 bfd_set_error (bfd_error_bad_value
);
3388 goto error_ret_free_internal
;
3390 st_type
= ELF_ST_TYPE (hash
->root
.type
);
3391 sym_name
= hash
->root
.root
.root
.string
;
3394 /* Determine what (if any) linker stub is needed. */
3395 stub_type
= aarch64_type_of_stub
3396 (info
, section
, irela
, st_type
, hash
, destination
);
3397 if (stub_type
== aarch64_stub_none
)
3400 /* Support for grouping stub sections. */
3401 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
3403 /* Get the name of this stub. */
3404 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
3407 goto error_ret_free_internal
;
3410 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
3411 stub_name
, FALSE
, FALSE
);
3412 if (stub_entry
!= NULL
)
3414 /* The proper stub has already been created. */
3419 stub_entry
= elfNN_aarch64_add_stub (stub_name
, section
,
3421 if (stub_entry
== NULL
)
3424 goto error_ret_free_internal
;
3427 stub_entry
->target_value
= sym_value
;
3428 stub_entry
->target_section
= sym_sec
;
3429 stub_entry
->stub_type
= stub_type
;
3430 stub_entry
->h
= hash
;
3431 stub_entry
->st_type
= st_type
;
3433 if (sym_name
== NULL
)
3434 sym_name
= "unnamed";
3435 len
= sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
);
3436 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
3437 if (stub_entry
->output_name
== NULL
)
3440 goto error_ret_free_internal
;
3443 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
3446 stub_changed
= TRUE
;
3449 /* We're done with the internal relocs, free them. */
3450 if (elf_section_data (section
)->relocs
== NULL
)
3451 free (internal_relocs
);
3454 if (htab
->fix_erratum_835769
)
3456 /* Scan for sequences which might trigger erratum 835769. */
3457 if (erratum_835769_scan (input_bfd
, info
, &erratum_835769_fixes
,
3458 &num_erratum_835769_fixes
,
3459 &erratum_835769_fix_table_size
) != 0)
3460 goto error_ret_free_local
;
3464 if (prev_num_erratum_835769_fixes
!= num_erratum_835769_fixes
)
3465 stub_changed
= TRUE
;
3470 /* OK, we've added some stubs. Find out the new size of the
3472 for (stub_sec
= htab
->stub_bfd
->sections
;
3473 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
3475 /* Ignore non-stub sections. */
3476 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
3481 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
3483 /* Add erratum 835769 veneers to stub section sizes too. */
3484 if (htab
->fix_erratum_835769
)
3485 for (i
= 0; i
< num_erratum_835769_fixes
; i
++)
3487 stub_sec
= elf_aarch64_create_or_find_stub_sec (NULL
,
3488 erratum_835769_fixes
[i
].section
, htab
);
3490 if (stub_sec
== NULL
)
3491 goto error_ret_free_local
;
3493 stub_sec
->size
+= 8;
3496 /* Ask the linker to do its stuff. */
3497 (*htab
->layout_sections_again
) ();
3498 stub_changed
= FALSE
;
3501 /* Add stubs for erratum 835769 fixes now. */
3502 if (htab
->fix_erratum_835769
)
3504 for (i
= 0; i
< num_erratum_835769_fixes
; i
++)
3506 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3507 char *stub_name
= erratum_835769_fixes
[i
].stub_name
;
3508 asection
*section
= erratum_835769_fixes
[i
].section
;
3509 unsigned int section_id
= erratum_835769_fixes
[i
].section
->id
;
3510 asection
*link_sec
= htab
->stub_group
[section_id
].link_sec
;
3511 asection
*stub_sec
= htab
->stub_group
[section_id
].stub_sec
;
3513 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
3514 stub_name
, TRUE
, FALSE
);
3515 if (stub_entry
== NULL
)
3517 (*_bfd_error_handler
) (_("%s: cannot create stub entry %s"),
3523 stub_entry
->stub_sec
= stub_sec
;
3524 stub_entry
->stub_offset
= 0;
3525 stub_entry
->id_sec
= link_sec
;
3526 stub_entry
->stub_type
= erratum_835769_fixes
[i
].stub_type
;
3527 stub_entry
->target_section
= section
;
3528 stub_entry
->target_value
= erratum_835769_fixes
[i
].offset
;
3529 stub_entry
->veneered_insn
= erratum_835769_fixes
[i
].veneered_insn
;
3530 stub_entry
->output_name
= erratum_835769_fixes
[i
].stub_name
;
3533 /* Stash the erratum 835769 fix array for use later in
3534 elfNN_aarch64_write_section(). */
3535 htab
->aarch64_erratum_835769_fixes
= erratum_835769_fixes
;
3536 htab
->num_aarch64_erratum_835769_fixes
= num_erratum_835769_fixes
;
3540 htab
->aarch64_erratum_835769_fixes
= NULL
;
3541 htab
->num_aarch64_erratum_835769_fixes
= 0;
3546 error_ret_free_local
:
3550 /* Build all the stubs associated with the current output file. The
3551 stubs are kept in a hash table attached to the main linker hash
3552 table. We also set up the .plt entries for statically linked PIC
3553 functions here. This function is called via aarch64_elf_finish in the
3557 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
3560 struct bfd_hash_table
*table
;
3561 struct elf_aarch64_link_hash_table
*htab
;
3563 htab
= elf_aarch64_hash_table (info
);
3565 for (stub_sec
= htab
->stub_bfd
->sections
;
3566 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
3570 /* Ignore non-stub sections. */
3571 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
3574 /* Allocate memory to hold the linker stubs. */
3575 size
= stub_sec
->size
;
3576 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
3577 if (stub_sec
->contents
== NULL
&& size
!= 0)
3582 /* Build the stubs as directed by the stub hash table. */
3583 table
= &htab
->stub_hash_table
;
3584 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
3590 /* Add an entry to the code/data map for section SEC. */
3593 elfNN_aarch64_section_map_add (asection
*sec
, char type
, bfd_vma vma
)
3595 struct _aarch64_elf_section_data
*sec_data
=
3596 elf_aarch64_section_data (sec
);
3597 unsigned int newidx
;
3599 if (sec_data
->map
== NULL
)
3601 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
3602 sec_data
->mapcount
= 0;
3603 sec_data
->mapsize
= 1;
3606 newidx
= sec_data
->mapcount
++;
3608 if (sec_data
->mapcount
> sec_data
->mapsize
)
3610 sec_data
->mapsize
*= 2;
3611 sec_data
->map
= bfd_realloc_or_free
3612 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
3617 sec_data
->map
[newidx
].vma
= vma
;
3618 sec_data
->map
[newidx
].type
= type
;
3623 /* Initialise maps of insn/data for input BFDs. */
3625 bfd_elfNN_aarch64_init_maps (bfd
*abfd
)
3627 Elf_Internal_Sym
*isymbuf
;
3628 Elf_Internal_Shdr
*hdr
;
3629 unsigned int i
, localsyms
;
3631 /* Make sure that we are dealing with an AArch64 elf binary. */
3632 if (!is_aarch64_elf (abfd
))
3635 if ((abfd
->flags
& DYNAMIC
) != 0)
3638 hdr
= &elf_symtab_hdr (abfd
);
3639 localsyms
= hdr
->sh_info
;
3641 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
3642 should contain the number of local symbols, which should come before any
3643 global symbols. Mapping symbols are always local. */
3644 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
3646 /* No internal symbols read? Skip this BFD. */
3647 if (isymbuf
== NULL
)
3650 for (i
= 0; i
< localsyms
; i
++)
3652 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
3653 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
3656 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
3658 name
= bfd_elf_string_from_elf_section (abfd
,
3662 if (bfd_is_aarch64_special_symbol_name
3663 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
3664 elfNN_aarch64_section_map_add (sec
, name
[1], isym
->st_value
);
3669 /* Set option values needed during linking. */
3671 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
3672 struct bfd_link_info
*link_info
,
3674 int no_wchar_warn
, int pic_veneer
,
3675 int fix_erratum_835769
)
3677 struct elf_aarch64_link_hash_table
*globals
;
3679 globals
= elf_aarch64_hash_table (link_info
);
3680 globals
->pic_veneer
= pic_veneer
;
3681 globals
->fix_erratum_835769
= fix_erratum_835769
;
3683 BFD_ASSERT (is_aarch64_elf (output_bfd
));
3684 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
3685 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
3689 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
3690 struct elf_aarch64_link_hash_table
3691 *globals
, struct bfd_link_info
*info
,
3692 bfd_vma value
, bfd
*output_bfd
,
3693 bfd_boolean
*unresolved_reloc_p
)
3695 bfd_vma off
= (bfd_vma
) - 1;
3696 asection
*basegot
= globals
->root
.sgot
;
3697 bfd_boolean dyn
= globals
->root
.dynamic_sections_created
;
3701 BFD_ASSERT (basegot
!= NULL
);
3702 off
= h
->got
.offset
;
3703 BFD_ASSERT (off
!= (bfd_vma
) - 1);
3704 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, info
->shared
, h
)
3706 && SYMBOL_REFERENCES_LOCAL (info
, h
))
3707 || (ELF_ST_VISIBILITY (h
->other
)
3708 && h
->root
.type
== bfd_link_hash_undefweak
))
3710 /* This is actually a static link, or it is a -Bsymbolic link
3711 and the symbol is defined locally. We must initialize this
3712 entry in the global offset table. Since the offset must
3713 always be a multiple of 8 (4 in the case of ILP32), we use
3714 the least significant bit to record whether we have
3715 initialized it already.
3716 When doing a dynamic link, we create a .rel(a).got relocation
3717 entry to initialize the value. This is done in the
3718 finish_dynamic_symbol routine. */
3723 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
3728 *unresolved_reloc_p
= FALSE
;
3730 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
3736 /* Change R_TYPE to a more efficient access model where possible,
3737 return the new reloc type. */
3739 static bfd_reloc_code_real_type
3740 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
3741 struct elf_link_hash_entry
*h
)
3743 bfd_boolean is_local
= h
== NULL
;
3747 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
3748 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
3750 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
3751 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
3753 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
3754 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
3756 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
3757 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
3759 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
3760 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
3762 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
3763 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
3765 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
3768 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
3770 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
3771 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
3773 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
3774 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
3775 /* Instructions with these relocations will become NOPs. */
3776 return BFD_RELOC_AARCH64_NONE
;
3786 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
3790 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
3791 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
3792 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
3793 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
3796 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
3797 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
3798 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
3801 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
3802 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
3803 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
3804 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
3805 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
3806 return GOT_TLSDESC_GD
;
3808 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
3809 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
3810 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
3811 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
3814 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
3815 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
3816 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
3817 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
3818 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
3819 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
3820 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
3821 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
3831 aarch64_can_relax_tls (bfd
*input_bfd
,
3832 struct bfd_link_info
*info
,
3833 bfd_reloc_code_real_type r_type
,
3834 struct elf_link_hash_entry
*h
,
3835 unsigned long r_symndx
)
3837 unsigned int symbol_got_type
;
3838 unsigned int reloc_got_type
;
3840 if (! IS_AARCH64_TLS_RELOC (r_type
))
3843 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
3844 reloc_got_type
= aarch64_reloc_got_type (r_type
);
3846 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
3852 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
3858 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
3861 static bfd_reloc_code_real_type
3862 aarch64_tls_transition (bfd
*input_bfd
,
3863 struct bfd_link_info
*info
,
3864 unsigned int r_type
,
3865 struct elf_link_hash_entry
*h
,
3866 unsigned long r_symndx
)
3868 bfd_reloc_code_real_type bfd_r_type
3869 = elfNN_aarch64_bfd_reloc_from_type (r_type
);
3871 if (! aarch64_can_relax_tls (input_bfd
, info
, bfd_r_type
, h
, r_symndx
))
3874 return aarch64_tls_transition_without_check (bfd_r_type
, h
);
3877 /* Return the base VMA address which should be subtracted from real addresses
3878 when resolving R_AARCH64_TLS_DTPREL relocation. */
3881 dtpoff_base (struct bfd_link_info
*info
)
3883 /* If tls_sec is NULL, we should have signalled an error already. */
3884 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
3885 return elf_hash_table (info
)->tls_sec
->vma
;
3888 /* Return the base VMA address which should be subtracted from real addresses
3889 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
3892 tpoff_base (struct bfd_link_info
*info
)
3894 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
3896 /* If tls_sec is NULL, we should have signalled an error already. */
3897 BFD_ASSERT (htab
->tls_sec
!= NULL
);
3899 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE
,
3900 htab
->tls_sec
->alignment_power
);
3901 return htab
->tls_sec
->vma
- base
;
3905 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3906 unsigned long r_symndx
)
3908 /* Calculate the address of the GOT entry for symbol
3909 referred to in h. */
3911 return &h
->got
.offset
;
3915 struct elf_aarch64_local_symbol
*l
;
3917 l
= elf_aarch64_locals (input_bfd
);
3918 return &l
[r_symndx
].got_offset
;
3923 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3924 unsigned long r_symndx
)
3927 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
3932 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3933 unsigned long r_symndx
)
3936 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
3941 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3942 unsigned long r_symndx
)
3945 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
3951 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3952 unsigned long r_symndx
)
3954 /* Calculate the address of the GOT entry for symbol
3955 referred to in h. */
3958 struct elf_aarch64_link_hash_entry
*eh
;
3959 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
3960 return &eh
->tlsdesc_got_jump_table_offset
;
3965 struct elf_aarch64_local_symbol
*l
;
3967 l
= elf_aarch64_locals (input_bfd
);
3968 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
3973 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3974 unsigned long r_symndx
)
3977 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
3982 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
3983 struct elf_link_hash_entry
*h
,
3984 unsigned long r_symndx
)
3987 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
3992 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
3993 unsigned long r_symndx
)
3996 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4001 /* Data for make_branch_to_erratum_835769_stub(). */
4003 struct erratum_835769_branch_to_stub_data
4005 asection
*output_section
;
4009 /* Helper to insert branches to erratum 835769 stubs in the right
4010 places for a particular section. */
4013 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
4016 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4017 struct erratum_835769_branch_to_stub_data
*data
;
4019 unsigned long branch_insn
= 0;
4020 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
4021 bfd_signed_vma branch_offset
;
4022 unsigned int target
;
4025 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4026 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4028 if (stub_entry
->target_section
!= data
->output_section
4029 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
4032 contents
= data
->contents
;
4033 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4034 + stub_entry
->target_section
->output_offset
4035 + stub_entry
->target_value
;
4036 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4037 + stub_entry
->stub_sec
->output_offset
4038 + stub_entry
->stub_offset
;
4039 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4041 abfd
= stub_entry
->target_section
->owner
;
4042 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4043 (*_bfd_error_handler
)
4044 (_("%B: error: Erratum 835769 stub out "
4045 "of range (input file too large)"), abfd
);
4047 target
= stub_entry
->target_value
;
4048 branch_insn
= 0x14000000;
4049 branch_offset
>>= 2;
4050 branch_offset
&= 0x3ffffff;
4051 branch_insn
|= branch_offset
;
4052 bfd_putl32 (branch_insn
, &contents
[target
]);
4058 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4059 struct bfd_link_info
*link_info
,
4064 struct elf_aarch64_link_hash_table
*globals
=
4065 elf_aarch64_hash_table (link_info
);
4067 if (globals
== NULL
)
4070 /* Fix code to point to erratum 835769 stubs. */
4071 if (globals
->fix_erratum_835769
)
4073 struct erratum_835769_branch_to_stub_data data
;
4075 data
.output_section
= sec
;
4076 data
.contents
= contents
;
4077 bfd_hash_traverse (&globals
->stub_hash_table
,
4078 make_branch_to_erratum_835769_stub
, &data
);
4084 /* Perform a relocation as part of a final link. */
4085 static bfd_reloc_status_type
4086 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
4089 asection
*input_section
,
4091 Elf_Internal_Rela
*rel
,
4093 struct bfd_link_info
*info
,
4095 struct elf_link_hash_entry
*h
,
4096 bfd_boolean
*unresolved_reloc_p
,
4097 bfd_boolean save_addend
,
4098 bfd_vma
*saved_addend
,
4099 Elf_Internal_Sym
*sym
)
4101 Elf_Internal_Shdr
*symtab_hdr
;
4102 unsigned int r_type
= howto
->type
;
4103 bfd_reloc_code_real_type bfd_r_type
4104 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
4105 bfd_reloc_code_real_type new_bfd_r_type
;
4106 unsigned long r_symndx
;
4107 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
4109 bfd_signed_vma signed_addend
;
4110 struct elf_aarch64_link_hash_table
*globals
;
4111 bfd_boolean weak_undef_p
;
4113 globals
= elf_aarch64_hash_table (info
);
4115 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
4117 BFD_ASSERT (is_aarch64_elf (input_bfd
));
4119 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4121 /* It is possible to have linker relaxations on some TLS access
4122 models. Update our information here. */
4123 new_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
, h
, r_symndx
);
4124 if (new_bfd_r_type
!= bfd_r_type
)
4126 bfd_r_type
= new_bfd_r_type
;
4127 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
4128 BFD_ASSERT (howto
!= NULL
);
4129 r_type
= howto
->type
;
4132 place
= input_section
->output_section
->vma
4133 + input_section
->output_offset
+ rel
->r_offset
;
4135 /* Get addend, accumulating the addend for consecutive relocs
4136 which refer to the same offset. */
4137 signed_addend
= saved_addend
? *saved_addend
: 0;
4138 signed_addend
+= rel
->r_addend
;
4140 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
4141 : bfd_is_und_section (sym_sec
));
4143 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
4144 it here if it is defined in a non-shared object. */
4146 && h
->type
== STT_GNU_IFUNC
4154 if ((input_section
->flags
& SEC_ALLOC
) == 0
4155 || h
->plt
.offset
== (bfd_vma
) -1)
4158 /* STT_GNU_IFUNC symbol must go through PLT. */
4159 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
4160 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
4165 if (h
->root
.root
.string
)
4166 name
= h
->root
.root
.string
;
4168 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4170 (*_bfd_error_handler
)
4171 (_("%B: relocation %s against STT_GNU_IFUNC "
4172 "symbol `%s' isn't handled by %s"), input_bfd
,
4173 howto
->name
, name
, __FUNCTION__
);
4174 bfd_set_error (bfd_error_bad_value
);
4177 case BFD_RELOC_AARCH64_NN
:
4178 if (rel
->r_addend
!= 0)
4180 if (h
->root
.root
.string
)
4181 name
= h
->root
.root
.string
;
4183 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
4185 (*_bfd_error_handler
)
4186 (_("%B: relocation %s against STT_GNU_IFUNC "
4187 "symbol `%s' has non-zero addend: %d"),
4188 input_bfd
, howto
->name
, name
, rel
->r_addend
);
4189 bfd_set_error (bfd_error_bad_value
);
4193 /* Generate dynamic relocation only when there is a
4194 non-GOT reference in a shared object. */
4195 if (info
->shared
&& h
->non_got_ref
)
4197 Elf_Internal_Rela outrel
;
4200 /* Need a dynamic relocation to get the real function
4202 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
4206 if (outrel
.r_offset
== (bfd_vma
) -1
4207 || outrel
.r_offset
== (bfd_vma
) -2)
4210 outrel
.r_offset
+= (input_section
->output_section
->vma
4211 + input_section
->output_offset
);
4213 if (h
->dynindx
== -1
4215 || info
->executable
)
4217 /* This symbol is resolved locally. */
4218 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
4219 outrel
.r_addend
= (h
->root
.u
.def
.value
4220 + h
->root
.u
.def
.section
->output_section
->vma
4221 + h
->root
.u
.def
.section
->output_offset
);
4225 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
4226 outrel
.r_addend
= 0;
4229 sreloc
= globals
->root
.irelifunc
;
4230 elf_append_rela (output_bfd
, sreloc
, &outrel
);
4232 /* If this reloc is against an external symbol, we
4233 do not want to fiddle with the addend. Otherwise,
4234 we need to include the symbol value so that it
4235 becomes an addend for the dynamic reloc. For an
4236 internal symbol, we have updated addend. */
4237 return bfd_reloc_ok
;
4240 case BFD_RELOC_AARCH64_JUMP26
:
4241 case BFD_RELOC_AARCH64_CALL26
:
4242 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4245 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
4247 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4248 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4249 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4250 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4251 base_got
= globals
->root
.sgot
;
4252 off
= h
->got
.offset
;
4254 if (base_got
== NULL
)
4257 if (off
== (bfd_vma
) -1)
4261 /* We can't use h->got.offset here to save state, or
4262 even just remember the offset, as finish_dynamic_symbol
4263 would use that as offset into .got. */
4265 if (globals
->root
.splt
!= NULL
)
4267 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
4268 globals
->plt_entry_size
);
4269 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
4270 base_got
= globals
->root
.sgotplt
;
4274 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
4275 off
= plt_index
* GOT_ENTRY_SIZE
;
4276 base_got
= globals
->root
.igotplt
;
4279 if (h
->dynindx
== -1
4283 /* This references the local definition. We must
4284 initialize this entry in the global offset table.
4285 Since the offset must always be a multiple of 8,
4286 we use the least significant bit to record
4287 whether we have initialized it already.
4289 When doing a dynamic link, we create a .rela.got
4290 relocation entry to initialize the value. This
4291 is done in the finish_dynamic_symbol routine. */
4296 bfd_put_NN (output_bfd
, value
,
4297 base_got
->contents
+ off
);
4298 /* Note that this is harmless as -1 | 1 still is -1. */
4302 value
= (base_got
->output_section
->vma
4303 + base_got
->output_offset
+ off
);
4306 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
4308 unresolved_reloc_p
);
4309 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4311 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
4312 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
4313 case BFD_RELOC_AARCH64_ADD_LO12
:
4320 case BFD_RELOC_AARCH64_NONE
:
4321 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4322 *unresolved_reloc_p
= FALSE
;
4323 return bfd_reloc_ok
;
4325 case BFD_RELOC_AARCH64_NN
:
4327 /* When generating a shared object or relocatable executable, these
4328 relocations are copied into the output file to be resolved at
4330 if (((info
->shared
== TRUE
) || globals
->root
.is_relocatable_executable
)
4331 && (input_section
->flags
& SEC_ALLOC
)
4333 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
4334 || h
->root
.type
!= bfd_link_hash_undefweak
))
4336 Elf_Internal_Rela outrel
;
4338 bfd_boolean skip
, relocate
;
4341 *unresolved_reloc_p
= FALSE
;
4346 outrel
.r_addend
= signed_addend
;
4348 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
4350 if (outrel
.r_offset
== (bfd_vma
) - 1)
4352 else if (outrel
.r_offset
== (bfd_vma
) - 2)
4358 outrel
.r_offset
+= (input_section
->output_section
->vma
4359 + input_section
->output_offset
);
4362 memset (&outrel
, 0, sizeof outrel
);
4365 && (!info
->shared
|| !SYMBOLIC_BIND (info
, h
) || !h
->def_regular
))
4366 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
4371 /* On SVR4-ish systems, the dynamic loader cannot
4372 relocate the text and data segments independently,
4373 so the symbol does not matter. */
4375 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
4376 outrel
.r_addend
+= value
;
4379 sreloc
= elf_section_data (input_section
)->sreloc
;
4380 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
4381 return bfd_reloc_notsupported
;
4383 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
4384 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
4386 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
4388 /* Sanity to check that we have previously allocated
4389 sufficient space in the relocation section for the
4390 number of relocations we actually want to emit. */
4394 /* If this reloc is against an external symbol, we do not want to
4395 fiddle with the addend. Otherwise, we need to include the symbol
4396 value so that it becomes an addend for the dynamic reloc. */
4398 return bfd_reloc_ok
;
4400 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
4401 contents
, rel
->r_offset
, value
,
4405 value
+= signed_addend
;
4408 case BFD_RELOC_AARCH64_JUMP26
:
4409 case BFD_RELOC_AARCH64_CALL26
:
4411 asection
*splt
= globals
->root
.splt
;
4412 bfd_boolean via_plt_p
=
4413 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
4415 /* A call to an undefined weak symbol is converted to a jump to
4416 the next instruction unless a PLT entry will be created.
4417 The jump to the next instruction is optimized as a NOP.
4418 Do the same for local undefined symbols. */
4419 if (weak_undef_p
&& ! via_plt_p
)
4421 bfd_putl32 (INSN_NOP
, hit_data
);
4422 return bfd_reloc_ok
;
4425 /* If the call goes through a PLT entry, make sure to
4426 check distance to the right destination address. */
4429 value
= (splt
->output_section
->vma
4430 + splt
->output_offset
+ h
->plt
.offset
);
4431 *unresolved_reloc_p
= FALSE
;
4434 /* If the target symbol is global and marked as a function the
4435 relocation applies a function call or a tail call. In this
4436 situation we can veneer out of range branches. The veneers
4437 use IP0 and IP1 hence cannot be used arbitrary out of range
4438 branches that occur within the body of a function. */
4439 if (h
&& h
->type
== STT_FUNC
)
4441 /* Check if a stub has to be inserted because the destination
4443 if (! aarch64_valid_branch_p (value
, place
))
4445 /* The target is out of reach, so redirect the branch to
4446 the local stub for this function. */
4447 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4448 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
,
4451 if (stub_entry
!= NULL
)
4452 value
= (stub_entry
->stub_offset
4453 + stub_entry
->stub_sec
->output_offset
4454 + stub_entry
->stub_sec
->output_section
->vma
);
4458 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4459 signed_addend
, weak_undef_p
);
4462 case BFD_RELOC_AARCH64_16
:
4464 case BFD_RELOC_AARCH64_32
:
4466 case BFD_RELOC_AARCH64_ADD_LO12
:
4467 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
4468 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
4469 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
4470 case BFD_RELOC_AARCH64_BRANCH19
:
4471 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
4472 case BFD_RELOC_AARCH64_LDST8_LO12
:
4473 case BFD_RELOC_AARCH64_LDST16_LO12
:
4474 case BFD_RELOC_AARCH64_LDST32_LO12
:
4475 case BFD_RELOC_AARCH64_LDST64_LO12
:
4476 case BFD_RELOC_AARCH64_LDST128_LO12
:
4477 case BFD_RELOC_AARCH64_MOVW_G0_S
:
4478 case BFD_RELOC_AARCH64_MOVW_G1_S
:
4479 case BFD_RELOC_AARCH64_MOVW_G2_S
:
4480 case BFD_RELOC_AARCH64_MOVW_G0
:
4481 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
4482 case BFD_RELOC_AARCH64_MOVW_G1
:
4483 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
4484 case BFD_RELOC_AARCH64_MOVW_G2
:
4485 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
4486 case BFD_RELOC_AARCH64_MOVW_G3
:
4487 case BFD_RELOC_AARCH64_16_PCREL
:
4488 case BFD_RELOC_AARCH64_32_PCREL
:
4489 case BFD_RELOC_AARCH64_64_PCREL
:
4490 case BFD_RELOC_AARCH64_TSTBR14
:
4491 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4492 signed_addend
, weak_undef_p
);
4495 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4496 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4497 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4498 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4499 if (globals
->root
.sgot
== NULL
)
4500 BFD_ASSERT (h
!= NULL
);
4504 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
, value
,
4506 unresolved_reloc_p
);
4507 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4512 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4513 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4514 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4515 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4516 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
4517 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
4518 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4519 if (globals
->root
.sgot
== NULL
)
4520 return bfd_reloc_notsupported
;
4522 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
4523 + globals
->root
.sgot
->output_section
->vma
4524 + globals
->root
.sgot
->output_offset
);
4526 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4528 *unresolved_reloc_p
= FALSE
;
4531 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
4532 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
4533 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
4534 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
4535 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
4536 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
4537 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
4538 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
4539 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4540 signed_addend
- tpoff_base (info
),
4542 *unresolved_reloc_p
= FALSE
;
4545 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
4546 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4547 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4548 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
4549 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
4550 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
4551 if (globals
->root
.sgot
== NULL
)
4552 return bfd_reloc_notsupported
;
4553 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
4554 + globals
->root
.sgotplt
->output_section
->vma
4555 + globals
->root
.sgotplt
->output_offset
4556 + globals
->sgotplt_jump_table_size
);
4558 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4560 *unresolved_reloc_p
= FALSE
;
4564 return bfd_reloc_notsupported
;
4568 *saved_addend
= value
;
4570 /* Only apply the final relocation in a sequence. */
4572 return bfd_reloc_continue
;
4574 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
4578 /* Handle TLS relaxations. Relaxing is possible for symbols that use
4579 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
4582 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
4583 is to then call final_link_relocate. Return other values in the
4586 static bfd_reloc_status_type
4587 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table
*globals
,
4588 bfd
*input_bfd
, bfd_byte
*contents
,
4589 Elf_Internal_Rela
*rel
, struct elf_link_hash_entry
*h
)
4591 bfd_boolean is_local
= h
== NULL
;
4592 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
4595 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
4597 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
4599 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4600 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4603 /* GD->LE relaxation:
4604 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
4606 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
4608 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
4609 return bfd_reloc_continue
;
4613 /* GD->IE relaxation:
4614 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
4616 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
4618 return bfd_reloc_continue
;
4621 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4624 /* Tiny GD->LE relaxation:
4625 adr x0, :tlsgd:var => mrs x1, tpidr_el0
4626 bl __tls_get_addr => add x0, x1, #:tprel_hi12:x, lsl #12
4627 nop => add x0, x0, #:tprel_lo12_nc:x
4630 /* First kill the tls_get_addr reloc on the bl instruction. */
4631 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
4633 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
4634 bfd_putl32 (0x91400020, contents
+ rel
->r_offset
+ 4);
4635 bfd_putl32 (0x91000000, contents
+ rel
->r_offset
+ 8);
4637 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
4638 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
4639 rel
[1].r_offset
= rel
->r_offset
+ 8;
4641 /* Move the current relocation to the second instruction in
4644 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
4645 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
4646 return bfd_reloc_continue
;
4650 /* Tiny GD->IE relaxation:
4651 adr x0, :tlsgd:var => ldr x0, :gottprel:var
4652 bl __tls_get_addr => mrs x1, tpidr_el0
4653 nop => add x0, x0, x1
4656 /* First kill the tls_get_addr reloc on the bl instruction. */
4657 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
4658 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
4660 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
4661 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
4662 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
4663 return bfd_reloc_continue
;
4666 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4667 return bfd_reloc_continue
;
4669 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
4672 /* GD->LE relaxation:
4673 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
4675 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
4676 return bfd_reloc_continue
;
4680 /* GD->IE relaxation:
4681 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
4683 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4685 bfd_putl32 (insn
, contents
+ rel
->r_offset
);
4686 return bfd_reloc_continue
;
4689 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4692 /* GD->LE relaxation
4693 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
4694 bl __tls_get_addr => mrs x1, tpidr_el0
4695 nop => add x0, x1, x0
4698 /* First kill the tls_get_addr reloc on the bl instruction. */
4699 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
4700 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
4702 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
4703 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
4704 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
4705 return bfd_reloc_continue
;
4709 /* GD->IE relaxation
4710 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
4711 BL __tls_get_addr => mrs x1, tpidr_el0
4713 NOP => add x0, x1, x0
4716 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
4718 /* Remove the relocation on the BL instruction. */
4719 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
4721 bfd_putl32 (0xf9400000, contents
+ rel
->r_offset
);
4723 /* We choose to fixup the BL and NOP instructions using the
4724 offset from the second relocation to allow flexibility in
4725 scheduling instructions between the ADD and BL. */
4726 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
4727 bfd_putl32 (0x8b000020, contents
+ rel
[1].r_offset
+ 4);
4728 return bfd_reloc_continue
;
4731 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4732 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4733 /* GD->IE/LE relaxation:
4734 add x0, x0, #:tlsdesc_lo12:var => nop
4737 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
4738 return bfd_reloc_ok
;
4740 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4741 /* IE->LE relaxation:
4742 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
4746 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4747 bfd_putl32 (0xd2a00000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
4749 return bfd_reloc_continue
;
4751 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
4752 /* IE->LE relaxation:
4753 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
4757 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
4758 bfd_putl32 (0xf2800000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
4760 return bfd_reloc_continue
;
4763 return bfd_reloc_continue
;
4766 return bfd_reloc_ok
;
4769 /* Relocate an AArch64 ELF section. */
4772 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
4773 struct bfd_link_info
*info
,
4775 asection
*input_section
,
4777 Elf_Internal_Rela
*relocs
,
4778 Elf_Internal_Sym
*local_syms
,
4779 asection
**local_sections
)
4781 Elf_Internal_Shdr
*symtab_hdr
;
4782 struct elf_link_hash_entry
**sym_hashes
;
4783 Elf_Internal_Rela
*rel
;
4784 Elf_Internal_Rela
*relend
;
4786 struct elf_aarch64_link_hash_table
*globals
;
4787 bfd_boolean save_addend
= FALSE
;
4790 globals
= elf_aarch64_hash_table (info
);
4792 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
4793 sym_hashes
= elf_sym_hashes (input_bfd
);
4796 relend
= relocs
+ input_section
->reloc_count
;
4797 for (; rel
< relend
; rel
++)
4799 unsigned int r_type
;
4800 bfd_reloc_code_real_type bfd_r_type
;
4801 bfd_reloc_code_real_type relaxed_bfd_r_type
;
4802 reloc_howto_type
*howto
;
4803 unsigned long r_symndx
;
4804 Elf_Internal_Sym
*sym
;
4806 struct elf_link_hash_entry
*h
;
4808 bfd_reloc_status_type r
;
4811 bfd_boolean unresolved_reloc
= FALSE
;
4812 char *error_message
= NULL
;
4814 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4815 r_type
= ELFNN_R_TYPE (rel
->r_info
);
4817 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (r_type
);
4818 howto
= bfd_reloc
.howto
;
4822 (*_bfd_error_handler
)
4823 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
4824 input_bfd
, input_section
, r_type
);
4827 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
4833 if (r_symndx
< symtab_hdr
->sh_info
)
4835 sym
= local_syms
+ r_symndx
;
4836 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
4837 sec
= local_sections
[r_symndx
];
4839 /* An object file might have a reference to a local
4840 undefined symbol. This is a daft object file, but we
4841 should at least do something about it. */
4842 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
4843 && bfd_is_und_section (sec
)
4844 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
4846 if (!info
->callbacks
->undefined_symbol
4847 (info
, bfd_elf_string_from_elf_section
4848 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
4849 input_bfd
, input_section
, rel
->r_offset
, TRUE
))
4853 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
4855 /* Relocate against local STT_GNU_IFUNC symbol. */
4856 if (!info
->relocatable
4857 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
4859 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
4864 /* Set STT_GNU_IFUNC symbol value. */
4865 h
->root
.u
.def
.value
= sym
->st_value
;
4866 h
->root
.u
.def
.section
= sec
;
4871 bfd_boolean warned
, ignored
;
4873 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
4874 r_symndx
, symtab_hdr
, sym_hashes
,
4876 unresolved_reloc
, warned
, ignored
);
4881 if (sec
!= NULL
&& discarded_section (sec
))
4882 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
4883 rel
, 1, relend
, howto
, 0, contents
);
4885 if (info
->relocatable
)
4889 name
= h
->root
.root
.string
;
4892 name
= (bfd_elf_string_from_elf_section
4893 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
4894 if (name
== NULL
|| *name
== '\0')
4895 name
= bfd_section_name (input_bfd
, sec
);
4899 && r_type
!= R_AARCH64_NONE
4900 && r_type
!= R_AARCH64_NULL
4902 || h
->root
.type
== bfd_link_hash_defined
4903 || h
->root
.type
== bfd_link_hash_defweak
)
4904 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
4906 (*_bfd_error_handler
)
4907 ((sym_type
== STT_TLS
4908 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
4909 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
4911 input_section
, (long) rel
->r_offset
, howto
->name
, name
);
4914 /* We relax only if we can see that there can be a valid transition
4915 from a reloc type to another.
4916 We call elfNN_aarch64_final_link_relocate unless we're completely
4917 done, i.e., the relaxation produced the final output we want. */
4919 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
,
4921 if (relaxed_bfd_r_type
!= bfd_r_type
)
4923 bfd_r_type
= relaxed_bfd_r_type
;
4924 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
4925 BFD_ASSERT (howto
!= NULL
);
4926 r_type
= howto
->type
;
4927 r
= elfNN_aarch64_tls_relax (globals
, input_bfd
, contents
, rel
, h
);
4928 unresolved_reloc
= 0;
4931 r
= bfd_reloc_continue
;
4933 /* There may be multiple consecutive relocations for the
4934 same offset. In that case we are supposed to treat the
4935 output of each relocation as the addend for the next. */
4936 if (rel
+ 1 < relend
4937 && rel
->r_offset
== rel
[1].r_offset
4938 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
4939 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
4942 save_addend
= FALSE
;
4944 if (r
== bfd_reloc_continue
)
4945 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
4946 input_section
, contents
, rel
,
4947 relocation
, info
, sec
,
4948 h
, &unresolved_reloc
,
4949 save_addend
, &addend
, sym
);
4951 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
4953 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4954 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4955 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4956 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
4958 bfd_boolean need_relocs
= FALSE
;
4963 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
4964 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
4967 (info
->shared
|| indx
!= 0) &&
4969 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
4970 || h
->root
.type
!= bfd_link_hash_undefweak
);
4972 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
4976 Elf_Internal_Rela rela
;
4977 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
4979 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
4980 globals
->root
.sgot
->output_offset
+ off
;
4983 loc
= globals
->root
.srelgot
->contents
;
4984 loc
+= globals
->root
.srelgot
->reloc_count
++
4985 * RELOC_SIZE (htab
);
4986 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
4990 bfd_put_NN (output_bfd
,
4991 relocation
- dtpoff_base (info
),
4992 globals
->root
.sgot
->contents
+ off
4997 /* This TLS symbol is global. We emit a
4998 relocation to fixup the tls offset at load
5001 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
5004 (globals
->root
.sgot
->output_section
->vma
5005 + globals
->root
.sgot
->output_offset
+ off
5008 loc
= globals
->root
.srelgot
->contents
;
5009 loc
+= globals
->root
.srelgot
->reloc_count
++
5010 * RELOC_SIZE (globals
);
5011 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5012 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5013 globals
->root
.sgot
->contents
+ off
5019 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
5020 globals
->root
.sgot
->contents
+ off
);
5021 bfd_put_NN (output_bfd
,
5022 relocation
- dtpoff_base (info
),
5023 globals
->root
.sgot
->contents
+ off
5027 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5031 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5032 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5033 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5034 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5036 bfd_boolean need_relocs
= FALSE
;
5041 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5043 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5046 (info
->shared
|| indx
!= 0) &&
5048 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5049 || h
->root
.type
!= bfd_link_hash_undefweak
);
5051 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5055 Elf_Internal_Rela rela
;
5058 rela
.r_addend
= relocation
- dtpoff_base (info
);
5062 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
5063 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
5064 globals
->root
.sgot
->output_offset
+ off
;
5066 loc
= globals
->root
.srelgot
->contents
;
5067 loc
+= globals
->root
.srelgot
->reloc_count
++
5068 * RELOC_SIZE (htab
);
5070 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5072 bfd_put_NN (output_bfd
, rela
.r_addend
,
5073 globals
->root
.sgot
->contents
+ off
);
5076 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
5077 globals
->root
.sgot
->contents
+ off
);
5079 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5083 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5084 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5085 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5086 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5087 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5088 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5089 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5090 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5093 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5094 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5095 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5096 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5098 bfd_boolean need_relocs
= FALSE
;
5099 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5100 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
5102 need_relocs
= (h
== NULL
5103 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5104 || h
->root
.type
!= bfd_link_hash_undefweak
);
5106 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5107 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
5112 Elf_Internal_Rela rela
;
5113 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLSDESC
));
5116 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
5117 + globals
->root
.sgotplt
->output_offset
5118 + off
+ globals
->sgotplt_jump_table_size
);
5121 rela
.r_addend
= relocation
- dtpoff_base (info
);
5123 /* Allocate the next available slot in the PLT reloc
5124 section to hold our R_AARCH64_TLSDESC, the next
5125 available slot is determined from reloc_count,
5126 which we step. But note, reloc_count was
5127 artifically moved down while allocating slots for
5128 real PLT relocs such that all of the PLT relocs
5129 will fit above the initial reloc_count and the
5130 extra stuff will fit below. */
5131 loc
= globals
->root
.srelplt
->contents
;
5132 loc
+= globals
->root
.srelplt
->reloc_count
++
5133 * RELOC_SIZE (globals
);
5135 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5137 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5138 globals
->root
.sgotplt
->contents
+ off
+
5139 globals
->sgotplt_jump_table_size
);
5140 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5141 globals
->root
.sgotplt
->contents
+ off
+
5142 globals
->sgotplt_jump_table_size
+
5146 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
5157 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
5158 because such sections are not SEC_ALLOC and thus ld.so will
5159 not process them. */
5160 if (unresolved_reloc
5161 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
5163 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
5164 +rel
->r_offset
) != (bfd_vma
) - 1)
5166 (*_bfd_error_handler
)
5168 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
5169 input_bfd
, input_section
, (long) rel
->r_offset
, howto
->name
,
5170 h
->root
.root
.string
);
5174 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
5178 case bfd_reloc_overflow
:
5179 /* If the overflowing reloc was to an undefined symbol,
5180 we have already printed one error message and there
5181 is no point complaining again. */
5183 h
->root
.type
!= bfd_link_hash_undefined
)
5184 && (!((*info
->callbacks
->reloc_overflow
)
5185 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
5186 (bfd_vma
) 0, input_bfd
, input_section
,
5191 case bfd_reloc_undefined
:
5192 if (!((*info
->callbacks
->undefined_symbol
)
5193 (info
, name
, input_bfd
, input_section
,
5194 rel
->r_offset
, TRUE
)))
5198 case bfd_reloc_outofrange
:
5199 error_message
= _("out of range");
5202 case bfd_reloc_notsupported
:
5203 error_message
= _("unsupported relocation");
5206 case bfd_reloc_dangerous
:
5207 /* error_message should already be set. */
5211 error_message
= _("unknown error");
5215 BFD_ASSERT (error_message
!= NULL
);
5216 if (!((*info
->callbacks
->reloc_dangerous
)
5217 (info
, error_message
, input_bfd
, input_section
,
5228 /* Set the right machine number. */
5231 elfNN_aarch64_object_p (bfd
*abfd
)
5234 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
5236 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
5241 /* Function to keep AArch64 specific flags in the ELF header. */
5244 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
5246 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
5251 elf_elfheader (abfd
)->e_flags
= flags
;
5252 elf_flags_init (abfd
) = TRUE
;
5258 /* Merge backend specific data from an object file to the output
5259 object file when linking. */
5262 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
5266 bfd_boolean flags_compatible
= TRUE
;
5269 /* Check if we have the same endianess. */
5270 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
5273 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
5276 /* The input BFD must have had its flags initialised. */
5277 /* The following seems bogus to me -- The flags are initialized in
5278 the assembler but I don't think an elf_flags_init field is
5279 written into the object. */
5280 /* BFD_ASSERT (elf_flags_init (ibfd)); */
5282 in_flags
= elf_elfheader (ibfd
)->e_flags
;
5283 out_flags
= elf_elfheader (obfd
)->e_flags
;
5285 if (!elf_flags_init (obfd
))
5287 /* If the input is the default architecture and had the default
5288 flags then do not bother setting the flags for the output
5289 architecture, instead allow future merges to do this. If no
5290 future merges ever set these flags then they will retain their
5291 uninitialised values, which surprise surprise, correspond
5292 to the default values. */
5293 if (bfd_get_arch_info (ibfd
)->the_default
5294 && elf_elfheader (ibfd
)->e_flags
== 0)
5297 elf_flags_init (obfd
) = TRUE
;
5298 elf_elfheader (obfd
)->e_flags
= in_flags
;
5300 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
5301 && bfd_get_arch_info (obfd
)->the_default
)
5302 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
5303 bfd_get_mach (ibfd
));
5308 /* Identical flags must be compatible. */
5309 if (in_flags
== out_flags
)
5312 /* Check to see if the input BFD actually contains any sections. If
5313 not, its flags may not have been initialised either, but it
5314 cannot actually cause any incompatiblity. Do not short-circuit
5315 dynamic objects; their section list may be emptied by
5316 elf_link_add_object_symbols.
5318 Also check to see if there are no code sections in the input.
5319 In this case there is no need to check for code specific flags.
5320 XXX - do we need to worry about floating-point format compatability
5321 in data sections ? */
5322 if (!(ibfd
->flags
& DYNAMIC
))
5324 bfd_boolean null_input_bfd
= TRUE
;
5325 bfd_boolean only_data_sections
= TRUE
;
5327 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5329 if ((bfd_get_section_flags (ibfd
, sec
)
5330 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
5331 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
5332 only_data_sections
= FALSE
;
5334 null_input_bfd
= FALSE
;
5338 if (null_input_bfd
|| only_data_sections
)
5342 return flags_compatible
;
5345 /* Display the flags field. */
5348 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
5350 FILE *file
= (FILE *) ptr
;
5351 unsigned long flags
;
5353 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
5355 /* Print normal ELF private data. */
5356 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
5358 flags
= elf_elfheader (abfd
)->e_flags
;
5359 /* Ignore init flag - it may not be set, despite the flags field
5360 containing valid data. */
5362 /* xgettext:c-format */
5363 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
5366 fprintf (file
, _("<Unrecognised flag bits set>"));
5373 /* Update the got entry reference counts for the section being removed. */
5376 elfNN_aarch64_gc_sweep_hook (bfd
*abfd
,
5377 struct bfd_link_info
*info
,
5379 const Elf_Internal_Rela
* relocs
)
5381 struct elf_aarch64_link_hash_table
*htab
;
5382 Elf_Internal_Shdr
*symtab_hdr
;
5383 struct elf_link_hash_entry
**sym_hashes
;
5384 struct elf_aarch64_local_symbol
*locals
;
5385 const Elf_Internal_Rela
*rel
, *relend
;
5387 if (info
->relocatable
)
5390 htab
= elf_aarch64_hash_table (info
);
5395 elf_section_data (sec
)->local_dynrel
= NULL
;
5397 symtab_hdr
= &elf_symtab_hdr (abfd
);
5398 sym_hashes
= elf_sym_hashes (abfd
);
5400 locals
= elf_aarch64_locals (abfd
);
5402 relend
= relocs
+ sec
->reloc_count
;
5403 for (rel
= relocs
; rel
< relend
; rel
++)
5405 unsigned long r_symndx
;
5406 unsigned int r_type
;
5407 struct elf_link_hash_entry
*h
= NULL
;
5409 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5411 if (r_symndx
>= symtab_hdr
->sh_info
)
5414 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
5415 while (h
->root
.type
== bfd_link_hash_indirect
5416 || h
->root
.type
== bfd_link_hash_warning
)
5417 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
5421 Elf_Internal_Sym
*isym
;
5423 /* A local symbol. */
5424 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
5427 /* Check relocation against local STT_GNU_IFUNC symbol. */
5429 && ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
5431 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
, FALSE
);
5439 struct elf_aarch64_link_hash_entry
*eh
;
5440 struct elf_dyn_relocs
**pp
;
5441 struct elf_dyn_relocs
*p
;
5443 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
5445 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
; pp
= &p
->next
)
5448 /* Everything must go for SEC. */
5454 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5455 switch (aarch64_tls_transition (abfd
,info
, r_type
, h
,r_symndx
))
5457 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5458 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5459 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5460 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5461 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5462 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5463 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5464 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
5465 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5466 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5467 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5468 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5469 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5470 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5471 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5472 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5473 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5474 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5475 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5476 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5477 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5478 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5479 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5482 if (h
->got
.refcount
> 0)
5483 h
->got
.refcount
-= 1;
5485 if (h
->type
== STT_GNU_IFUNC
)
5487 if (h
->plt
.refcount
> 0)
5488 h
->plt
.refcount
-= 1;
5491 else if (locals
!= NULL
)
5493 if (locals
[r_symndx
].got_refcount
> 0)
5494 locals
[r_symndx
].got_refcount
-= 1;
5498 case BFD_RELOC_AARCH64_CALL26
:
5499 case BFD_RELOC_AARCH64_JUMP26
:
5500 /* If this is a local symbol then we resolve it
5501 directly without creating a PLT entry. */
5505 if (h
->plt
.refcount
> 0)
5506 h
->plt
.refcount
-= 1;
5509 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
5510 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
5511 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
5512 case BFD_RELOC_AARCH64_MOVW_G3
:
5513 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
5514 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5515 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
5516 case BFD_RELOC_AARCH64_NN
:
5517 if (h
!= NULL
&& info
->executable
)
5519 if (h
->plt
.refcount
> 0)
5520 h
->plt
.refcount
-= 1;
5532 /* Adjust a symbol defined by a dynamic object and referenced by a
5533 regular object. The current definition is in some section of the
5534 dynamic object, but we're not including those sections. We have to
5535 change the definition to something the rest of the link can
5539 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
5540 struct elf_link_hash_entry
*h
)
5542 struct elf_aarch64_link_hash_table
*htab
;
5545 /* If this is a function, put it in the procedure linkage table. We
5546 will fill in the contents of the procedure linkage table later,
5547 when we know the address of the .got section. */
5548 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
5550 if (h
->plt
.refcount
<= 0
5551 || (h
->type
!= STT_GNU_IFUNC
5552 && (SYMBOL_CALLS_LOCAL (info
, h
)
5553 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
5554 && h
->root
.type
== bfd_link_hash_undefweak
))))
5556 /* This case can occur if we saw a CALL26 reloc in
5557 an input file, but the symbol wasn't referred to
5558 by a dynamic object or all references were
5559 garbage collected. In which case we can end up
5561 h
->plt
.offset
= (bfd_vma
) - 1;
5568 /* It's possible that we incorrectly decided a .plt reloc was
5569 needed for an R_X86_64_PC32 reloc to a non-function sym in
5570 check_relocs. We can't decide accurately between function and
5571 non-function syms in check-relocs; Objects loaded later in
5572 the link may change h->type. So fix it now. */
5573 h
->plt
.offset
= (bfd_vma
) - 1;
5576 /* If this is a weak symbol, and there is a real definition, the
5577 processor independent code will have arranged for us to see the
5578 real definition first, and we can just use the same value. */
5579 if (h
->u
.weakdef
!= NULL
)
5581 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
5582 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
5583 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
5584 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
5585 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
5586 h
->non_got_ref
= h
->u
.weakdef
->non_got_ref
;
5590 /* If we are creating a shared library, we must presume that the
5591 only references to the symbol are via the global offset table.
5592 For such cases we need not do anything here; the relocations will
5593 be handled correctly by relocate_section. */
5597 /* If there are no references to this symbol that do not use the
5598 GOT, we don't need to generate a copy reloc. */
5599 if (!h
->non_got_ref
)
5602 /* If -z nocopyreloc was given, we won't generate them either. */
5603 if (info
->nocopyreloc
)
5609 /* We must allocate the symbol in our .dynbss section, which will
5610 become part of the .bss section of the executable. There will be
5611 an entry for this symbol in the .dynsym section. The dynamic
5612 object will contain position independent code, so all references
5613 from the dynamic object to this symbol will go through the global
5614 offset table. The dynamic linker will use the .dynsym entry to
5615 determine the address it must put in the global offset table, so
5616 both the dynamic object and the regular object will refer to the
5617 same memory location for the variable. */
5619 htab
= elf_aarch64_hash_table (info
);
5621 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
5622 to copy the initial value out of the dynamic object and into the
5623 runtime process image. */
5624 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
5626 htab
->srelbss
->size
+= RELOC_SIZE (htab
);
5632 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
5637 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
5639 struct elf_aarch64_local_symbol
*locals
;
5640 locals
= elf_aarch64_locals (abfd
);
5643 locals
= (struct elf_aarch64_local_symbol
*)
5644 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
5647 elf_aarch64_locals (abfd
) = locals
;
5652 /* Create the .got section to hold the global offset table. */
5655 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
5657 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
5660 struct elf_link_hash_entry
*h
;
5661 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
5663 /* This function may be called more than once. */
5664 s
= bfd_get_linker_section (abfd
, ".got");
5668 flags
= bed
->dynamic_sec_flags
;
5670 s
= bfd_make_section_anyway_with_flags (abfd
,
5671 (bed
->rela_plts_and_copies_p
5672 ? ".rela.got" : ".rel.got"),
5673 (bed
->dynamic_sec_flags
5676 || ! bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
5680 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
5682 || !bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
5685 htab
->sgot
->size
+= GOT_ENTRY_SIZE
;
5687 if (bed
->want_got_sym
)
5689 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
5690 (or .got.plt) section. We don't do this in the linker script
5691 because we don't want to define the symbol if we are not creating
5692 a global offset table. */
5693 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
5694 "_GLOBAL_OFFSET_TABLE_");
5695 elf_hash_table (info
)->hgot
= h
;
5700 if (bed
->want_got_plt
)
5702 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
5704 || !bfd_set_section_alignment (abfd
, s
,
5705 bed
->s
->log_file_align
))
5710 /* The first bit of the global offset table is the header. */
5711 s
->size
+= bed
->got_header_size
;
5716 /* Look through the relocs for a section during the first phase. */
5719 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
5720 asection
*sec
, const Elf_Internal_Rela
*relocs
)
5722 Elf_Internal_Shdr
*symtab_hdr
;
5723 struct elf_link_hash_entry
**sym_hashes
;
5724 const Elf_Internal_Rela
*rel
;
5725 const Elf_Internal_Rela
*rel_end
;
5728 struct elf_aarch64_link_hash_table
*htab
;
5730 if (info
->relocatable
)
5733 BFD_ASSERT (is_aarch64_elf (abfd
));
5735 htab
= elf_aarch64_hash_table (info
);
5738 symtab_hdr
= &elf_symtab_hdr (abfd
);
5739 sym_hashes
= elf_sym_hashes (abfd
);
5741 rel_end
= relocs
+ sec
->reloc_count
;
5742 for (rel
= relocs
; rel
< rel_end
; rel
++)
5744 struct elf_link_hash_entry
*h
;
5745 unsigned long r_symndx
;
5746 unsigned int r_type
;
5747 bfd_reloc_code_real_type bfd_r_type
;
5748 Elf_Internal_Sym
*isym
;
5750 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5751 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5753 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
5755 (*_bfd_error_handler
) (_("%B: bad symbol index: %d"), abfd
,
5760 if (r_symndx
< symtab_hdr
->sh_info
)
5762 /* A local symbol. */
5763 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
5768 /* Check relocation against local STT_GNU_IFUNC symbol. */
5769 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
5771 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
5776 /* Fake a STT_GNU_IFUNC symbol. */
5777 h
->type
= STT_GNU_IFUNC
;
5780 h
->forced_local
= 1;
5781 h
->root
.type
= bfd_link_hash_defined
;
5788 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
5789 while (h
->root
.type
== bfd_link_hash_indirect
5790 || h
->root
.type
== bfd_link_hash_warning
)
5791 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
5793 /* PR15323, ref flags aren't set for references in the same
5795 h
->root
.non_ir_ref
= 1;
5798 /* Could be done earlier, if h were already available. */
5799 bfd_r_type
= aarch64_tls_transition (abfd
, info
, r_type
, h
, r_symndx
);
5803 /* Create the ifunc sections for static executables. If we
5804 never see an indirect function symbol nor we are building
5805 a static executable, those sections will be empty and
5806 won't appear in output. */
5812 case BFD_RELOC_AARCH64_NN
:
5813 case BFD_RELOC_AARCH64_CALL26
:
5814 case BFD_RELOC_AARCH64_JUMP26
:
5815 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5816 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5817 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5818 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5819 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5820 case BFD_RELOC_AARCH64_ADD_LO12
:
5821 if (htab
->root
.dynobj
== NULL
)
5822 htab
->root
.dynobj
= abfd
;
5823 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
5828 /* It is referenced by a non-shared object. */
5830 h
->root
.non_ir_ref
= 1;
5835 case BFD_RELOC_AARCH64_NN
:
5837 /* We don't need to handle relocs into sections not going into
5838 the "real" output. */
5839 if ((sec
->flags
& SEC_ALLOC
) == 0)
5847 h
->plt
.refcount
+= 1;
5848 h
->pointer_equality_needed
= 1;
5851 /* No need to do anything if we're not creating a shared
5857 struct elf_dyn_relocs
*p
;
5858 struct elf_dyn_relocs
**head
;
5860 /* We must copy these reloc types into the output file.
5861 Create a reloc section in dynobj and make room for
5865 if (htab
->root
.dynobj
== NULL
)
5866 htab
->root
.dynobj
= abfd
;
5868 sreloc
= _bfd_elf_make_dynamic_reloc_section
5869 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ TRUE
);
5875 /* If this is a global symbol, we count the number of
5876 relocations we need for this symbol. */
5879 struct elf_aarch64_link_hash_entry
*eh
;
5880 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
5881 head
= &eh
->dyn_relocs
;
5885 /* Track dynamic relocs needed for local syms too.
5886 We really need local syms available to do this
5892 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
5897 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
5901 /* Beware of type punned pointers vs strict aliasing
5903 vpp
= &(elf_section_data (s
)->local_dynrel
);
5904 head
= (struct elf_dyn_relocs
**) vpp
;
5908 if (p
== NULL
|| p
->sec
!= sec
)
5910 bfd_size_type amt
= sizeof *p
;
5911 p
= ((struct elf_dyn_relocs
*)
5912 bfd_zalloc (htab
->root
.dynobj
, amt
));
5925 /* RR: We probably want to keep a consistency check that
5926 there are no dangling GOT_PAGE relocs. */
5927 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5928 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5929 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5930 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5931 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5932 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5933 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5934 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
5935 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5936 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5937 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5938 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5939 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5940 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5941 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5942 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5943 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5944 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5945 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5946 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5947 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5948 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5949 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5952 unsigned old_got_type
;
5954 got_type
= aarch64_reloc_got_type (bfd_r_type
);
5958 h
->got
.refcount
+= 1;
5959 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
5963 struct elf_aarch64_local_symbol
*locals
;
5965 if (!elfNN_aarch64_allocate_local_symbols
5966 (abfd
, symtab_hdr
->sh_info
))
5969 locals
= elf_aarch64_locals (abfd
);
5970 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
5971 locals
[r_symndx
].got_refcount
+= 1;
5972 old_got_type
= locals
[r_symndx
].got_type
;
5975 /* If a variable is accessed with both general dynamic TLS
5976 methods, two slots may be created. */
5977 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
5978 got_type
|= old_got_type
;
5980 /* We will already have issued an error message if there
5981 is a TLS/non-TLS mismatch, based on the symbol type.
5982 So just combine any TLS types needed. */
5983 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
5984 && got_type
!= GOT_NORMAL
)
5985 got_type
|= old_got_type
;
5987 /* If the symbol is accessed by both IE and GD methods, we
5988 are able to relax. Turn off the GD flag, without
5989 messing up with any other kind of TLS types that may be
5991 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
5992 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
5994 if (old_got_type
!= got_type
)
5997 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
6000 struct elf_aarch64_local_symbol
*locals
;
6001 locals
= elf_aarch64_locals (abfd
);
6002 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
6003 locals
[r_symndx
].got_type
= got_type
;
6007 if (htab
->root
.dynobj
== NULL
)
6008 htab
->root
.dynobj
= abfd
;
6009 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
6014 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6015 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6016 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6017 case BFD_RELOC_AARCH64_MOVW_G3
:
6020 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6021 (*_bfd_error_handler
)
6022 (_("%B: relocation %s against `%s' can not be used when making "
6023 "a shared object; recompile with -fPIC"),
6024 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
6025 (h
) ? h
->root
.root
.string
: "a local symbol");
6026 bfd_set_error (bfd_error_bad_value
);
6030 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6031 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6032 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6033 if (h
!= NULL
&& info
->executable
)
6035 /* If this reloc is in a read-only section, we might
6036 need a copy reloc. We can't check reliably at this
6037 stage whether the section is read-only, as input
6038 sections have not yet been mapped to output sections.
6039 Tentatively set the flag for now, and correct in
6040 adjust_dynamic_symbol. */
6042 h
->plt
.refcount
+= 1;
6043 h
->pointer_equality_needed
= 1;
6045 /* FIXME:: RR need to handle these in shared libraries
6046 and essentially bomb out as these being non-PIC
6047 relocations in shared libraries. */
6050 case BFD_RELOC_AARCH64_CALL26
:
6051 case BFD_RELOC_AARCH64_JUMP26
:
6052 /* If this is a local symbol then we resolve it
6053 directly without creating a PLT entry. */
6058 if (h
->plt
.refcount
<= 0)
6059 h
->plt
.refcount
= 1;
6061 h
->plt
.refcount
+= 1;
6072 /* Treat mapping symbols as special target symbols. */
6075 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
6078 return bfd_is_aarch64_special_symbol_name (sym
->name
,
6079 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
6082 /* This is a copy of elf_find_function () from elf.c except that
6083 AArch64 mapping symbols are ignored when looking for function names. */
6086 aarch64_elf_find_function (bfd
*abfd ATTRIBUTE_UNUSED
,
6090 const char **filename_ptr
,
6091 const char **functionname_ptr
)
6093 const char *filename
= NULL
;
6094 asymbol
*func
= NULL
;
6095 bfd_vma low_func
= 0;
6098 for (p
= symbols
; *p
!= NULL
; p
++)
6102 q
= (elf_symbol_type
*) * p
;
6104 switch (ELF_ST_TYPE (q
->internal_elf_sym
.st_info
))
6109 filename
= bfd_asymbol_name (&q
->symbol
);
6113 /* Skip mapping symbols. */
6114 if ((q
->symbol
.flags
& BSF_LOCAL
)
6115 && (bfd_is_aarch64_special_symbol_name
6116 (q
->symbol
.name
, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
)))
6119 if (bfd_get_section (&q
->symbol
) == section
6120 && q
->symbol
.value
>= low_func
&& q
->symbol
.value
<= offset
)
6122 func
= (asymbol
*) q
;
6123 low_func
= q
->symbol
.value
;
6133 *filename_ptr
= filename
;
6134 if (functionname_ptr
)
6135 *functionname_ptr
= bfd_asymbol_name (func
);
6141 /* Find the nearest line to a particular section and offset, for error
6142 reporting. This code is a duplicate of the code in elf.c, except
6143 that it uses aarch64_elf_find_function. */
6146 elfNN_aarch64_find_nearest_line (bfd
*abfd
,
6150 const char **filename_ptr
,
6151 const char **functionname_ptr
,
6152 unsigned int *line_ptr
,
6153 unsigned int *discriminator_ptr
)
6155 bfd_boolean found
= FALSE
;
6157 if (_bfd_dwarf2_find_nearest_line (abfd
, symbols
, NULL
, section
, offset
,
6158 filename_ptr
, functionname_ptr
,
6159 line_ptr
, discriminator_ptr
,
6160 dwarf_debug_sections
, 0,
6161 &elf_tdata (abfd
)->dwarf2_find_line_info
))
6163 if (!*functionname_ptr
)
6164 aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
6165 *filename_ptr
? NULL
: filename_ptr
,
6171 /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
6172 toolchain uses DWARF1. */
6174 if (!_bfd_stab_section_find_nearest_line (abfd
, symbols
, section
, offset
,
6175 &found
, filename_ptr
,
6176 functionname_ptr
, line_ptr
,
6177 &elf_tdata (abfd
)->line_info
))
6180 if (found
&& (*functionname_ptr
|| *line_ptr
))
6183 if (symbols
== NULL
)
6186 if (!aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
6187 filename_ptr
, functionname_ptr
))
6195 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
6196 const char **filename_ptr
,
6197 const char **functionname_ptr
,
6198 unsigned int *line_ptr
)
6201 found
= _bfd_dwarf2_find_inliner_info
6202 (abfd
, filename_ptr
,
6203 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
6209 elfNN_aarch64_post_process_headers (bfd
*abfd
,
6210 struct bfd_link_info
*link_info
)
6212 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
6214 i_ehdrp
= elf_elfheader (abfd
);
6215 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
6217 _bfd_elf_post_process_headers (abfd
, link_info
);
6220 static enum elf_reloc_type_class
6221 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
6222 const asection
*rel_sec ATTRIBUTE_UNUSED
,
6223 const Elf_Internal_Rela
*rela
)
6225 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
6227 case AARCH64_R (RELATIVE
):
6228 return reloc_class_relative
;
6229 case AARCH64_R (JUMP_SLOT
):
6230 return reloc_class_plt
;
6231 case AARCH64_R (COPY
):
6232 return reloc_class_copy
;
6234 return reloc_class_normal
;
6238 /* Handle an AArch64 specific section when reading an object file. This is
6239 called when bfd_section_from_shdr finds a section with an unknown
6243 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
6244 Elf_Internal_Shdr
*hdr
,
6245 const char *name
, int shindex
)
6247 /* There ought to be a place to keep ELF backend specific flags, but
6248 at the moment there isn't one. We just keep track of the
6249 sections by their name, instead. Fortunately, the ABI gives
6250 names for all the AArch64 specific sections, so we will probably get
6252 switch (hdr
->sh_type
)
6254 case SHT_AARCH64_ATTRIBUTES
:
6261 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
6267 /* A structure used to record a list of sections, independently
6268 of the next and prev fields in the asection structure. */
6269 typedef struct section_list
6272 struct section_list
*next
;
6273 struct section_list
*prev
;
6277 /* Unfortunately we need to keep a list of sections for which
6278 an _aarch64_elf_section_data structure has been allocated. This
6279 is because it is possible for functions like elfNN_aarch64_write_section
6280 to be called on a section which has had an elf_data_structure
6281 allocated for it (and so the used_by_bfd field is valid) but
6282 for which the AArch64 extended version of this structure - the
6283 _aarch64_elf_section_data structure - has not been allocated. */
6284 static section_list
*sections_with_aarch64_elf_section_data
= NULL
;
6287 record_section_with_aarch64_elf_section_data (asection
*sec
)
6289 struct section_list
*entry
;
6291 entry
= bfd_malloc (sizeof (*entry
));
6295 entry
->next
= sections_with_aarch64_elf_section_data
;
6297 if (entry
->next
!= NULL
)
6298 entry
->next
->prev
= entry
;
6299 sections_with_aarch64_elf_section_data
= entry
;
6302 static struct section_list
*
6303 find_aarch64_elf_section_entry (asection
*sec
)
6305 struct section_list
*entry
;
6306 static struct section_list
*last_entry
= NULL
;
6308 /* This is a short cut for the typical case where the sections are added
6309 to the sections_with_aarch64_elf_section_data list in forward order and
6310 then looked up here in backwards order. This makes a real difference
6311 to the ld-srec/sec64k.exp linker test. */
6312 entry
= sections_with_aarch64_elf_section_data
;
6313 if (last_entry
!= NULL
)
6315 if (last_entry
->sec
== sec
)
6317 else if (last_entry
->next
!= NULL
&& last_entry
->next
->sec
== sec
)
6318 entry
= last_entry
->next
;
6321 for (; entry
; entry
= entry
->next
)
6322 if (entry
->sec
== sec
)
6326 /* Record the entry prior to this one - it is the entry we are
6327 most likely to want to locate next time. Also this way if we
6328 have been called from
6329 unrecord_section_with_aarch64_elf_section_data () we will not
6330 be caching a pointer that is about to be freed. */
6331 last_entry
= entry
->prev
;
6337 unrecord_section_with_aarch64_elf_section_data (asection
*sec
)
6339 struct section_list
*entry
;
6341 entry
= find_aarch64_elf_section_entry (sec
);
6345 if (entry
->prev
!= NULL
)
6346 entry
->prev
->next
= entry
->next
;
6347 if (entry
->next
!= NULL
)
6348 entry
->next
->prev
= entry
->prev
;
6349 if (entry
== sections_with_aarch64_elf_section_data
)
6350 sections_with_aarch64_elf_section_data
= entry
->next
;
6359 struct bfd_link_info
*info
;
6362 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
6363 asection
*, struct elf_link_hash_entry
*);
6364 } output_arch_syminfo
;
6366 enum map_symbol_type
6373 /* Output a single mapping symbol. */
6376 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
6377 enum map_symbol_type type
, bfd_vma offset
)
6379 static const char *names
[2] = { "$x", "$d" };
6380 Elf_Internal_Sym sym
;
6382 sym
.st_value
= (osi
->sec
->output_section
->vma
6383 + osi
->sec
->output_offset
+ offset
);
6386 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
6387 sym
.st_shndx
= osi
->sec_shndx
;
6388 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
6393 /* Output mapping symbols for PLT entries associated with H. */
6396 elfNN_aarch64_output_plt_map (struct elf_link_hash_entry
*h
, void *inf
)
6398 output_arch_syminfo
*osi
= (output_arch_syminfo
*) inf
;
6401 if (h
->root
.type
== bfd_link_hash_indirect
)
6404 if (h
->root
.type
== bfd_link_hash_warning
)
6405 /* When warning symbols are created, they **replace** the "real"
6406 entry in the hash table, thus we never get to see the real
6407 symbol in a hash traversal. So look at it now. */
6408 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6410 if (h
->plt
.offset
== (bfd_vma
) - 1)
6413 addr
= h
->plt
.offset
;
6416 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
6423 /* Output a single local symbol for a generated stub. */
6426 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
6427 bfd_vma offset
, bfd_vma size
)
6429 Elf_Internal_Sym sym
;
6431 sym
.st_value
= (osi
->sec
->output_section
->vma
6432 + osi
->sec
->output_offset
+ offset
);
6435 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
6436 sym
.st_shndx
= osi
->sec_shndx
;
6437 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
6441 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
6443 struct elf_aarch64_stub_hash_entry
*stub_entry
;
6447 output_arch_syminfo
*osi
;
6449 /* Massage our args to the form they really have. */
6450 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
6451 osi
= (output_arch_syminfo
*) in_arg
;
6453 stub_sec
= stub_entry
->stub_sec
;
6455 /* Ensure this stub is attached to the current section being
6457 if (stub_sec
!= osi
->sec
)
6460 addr
= (bfd_vma
) stub_entry
->stub_offset
;
6462 stub_name
= stub_entry
->output_name
;
6464 switch (stub_entry
->stub_type
)
6466 case aarch64_stub_adrp_branch
:
6467 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
6468 sizeof (aarch64_adrp_branch_stub
)))
6470 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
6473 case aarch64_stub_long_branch
:
6474 if (!elfNN_aarch64_output_stub_sym
6475 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
6477 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
6479 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
6482 case aarch64_stub_erratum_835769_veneer
:
6483 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
6484 sizeof (aarch64_erratum_835769_stub
)))
6486 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
6496 /* Output mapping symbols for linker generated sections. */
6499 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
6500 struct bfd_link_info
*info
,
6502 int (*func
) (void *, const char *,
6505 struct elf_link_hash_entry
6508 output_arch_syminfo osi
;
6509 struct elf_aarch64_link_hash_table
*htab
;
6511 htab
= elf_aarch64_hash_table (info
);
6517 /* Long calls stubs. */
6518 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
6522 for (stub_sec
= htab
->stub_bfd
->sections
;
6523 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
6525 /* Ignore non-stub sections. */
6526 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
6531 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
6532 (output_bfd
, osi
.sec
->output_section
);
6534 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
6539 /* Finally, output mapping symbols for the PLT. */
6540 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
6543 /* For now live without mapping symbols for the plt. */
6544 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
6545 (output_bfd
, htab
->root
.splt
->output_section
);
6546 osi
.sec
= htab
->root
.splt
;
6548 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_output_plt_map
,
6555 /* Allocate target specific section data. */
6558 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
6560 if (!sec
->used_by_bfd
)
6562 _aarch64_elf_section_data
*sdata
;
6563 bfd_size_type amt
= sizeof (*sdata
);
6565 sdata
= bfd_zalloc (abfd
, amt
);
6568 sec
->used_by_bfd
= sdata
;
6571 record_section_with_aarch64_elf_section_data (sec
);
6573 return _bfd_elf_new_section_hook (abfd
, sec
);
6578 unrecord_section_via_map_over_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
6580 void *ignore ATTRIBUTE_UNUSED
)
6582 unrecord_section_with_aarch64_elf_section_data (sec
);
6586 elfNN_aarch64_close_and_cleanup (bfd
*abfd
)
6589 bfd_map_over_sections (abfd
,
6590 unrecord_section_via_map_over_sections
, NULL
);
6592 return _bfd_elf_close_and_cleanup (abfd
);
6596 elfNN_aarch64_bfd_free_cached_info (bfd
*abfd
)
6599 bfd_map_over_sections (abfd
,
6600 unrecord_section_via_map_over_sections
, NULL
);
6602 return _bfd_free_cached_info (abfd
);
6605 /* Create dynamic sections. This is different from the ARM backend in that
6606 the got, plt, gotplt and their relocation sections are all created in the
6607 standard part of the bfd elf backend. */
6610 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
6611 struct bfd_link_info
*info
)
6613 struct elf_aarch64_link_hash_table
*htab
;
6615 /* We need to create .got section. */
6616 if (!aarch64_elf_create_got_section (dynobj
, info
))
6619 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
6622 htab
= elf_aarch64_hash_table (info
);
6623 htab
->sdynbss
= bfd_get_linker_section (dynobj
, ".dynbss");
6625 htab
->srelbss
= bfd_get_linker_section (dynobj
, ".rela.bss");
6627 if (!htab
->sdynbss
|| (!info
->shared
&& !htab
->srelbss
))
6634 /* Allocate space in .plt, .got and associated reloc sections for
6638 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
6640 struct bfd_link_info
*info
;
6641 struct elf_aarch64_link_hash_table
*htab
;
6642 struct elf_aarch64_link_hash_entry
*eh
;
6643 struct elf_dyn_relocs
*p
;
6645 /* An example of a bfd_link_hash_indirect symbol is versioned
6646 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
6647 -> __gxx_personality_v0(bfd_link_hash_defined)
6649 There is no need to process bfd_link_hash_indirect symbols here
6650 because we will also be presented with the concrete instance of
6651 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
6652 called to copy all relevant data from the generic to the concrete
6655 if (h
->root
.type
== bfd_link_hash_indirect
)
6658 if (h
->root
.type
== bfd_link_hash_warning
)
6659 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6661 info
= (struct bfd_link_info
*) inf
;
6662 htab
= elf_aarch64_hash_table (info
);
6664 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
6665 here if it is defined and referenced in a non-shared object. */
6666 if (h
->type
== STT_GNU_IFUNC
6669 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
6671 /* Make sure this symbol is output as a dynamic symbol.
6672 Undefined weak syms won't yet be marked as dynamic. */
6673 if (h
->dynindx
== -1 && !h
->forced_local
)
6675 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
6679 if (info
->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
6681 asection
*s
= htab
->root
.splt
;
6683 /* If this is the first .plt entry, make room for the special
6686 s
->size
+= htab
->plt_header_size
;
6688 h
->plt
.offset
= s
->size
;
6690 /* If this symbol is not defined in a regular file, and we are
6691 not generating a shared library, then set the symbol to this
6692 location in the .plt. This is required to make function
6693 pointers compare as equal between the normal executable and
6694 the shared library. */
6695 if (!info
->shared
&& !h
->def_regular
)
6697 h
->root
.u
.def
.section
= s
;
6698 h
->root
.u
.def
.value
= h
->plt
.offset
;
6701 /* Make room for this entry. For now we only create the
6702 small model PLT entries. We later need to find a way
6703 of relaxing into these from the large model PLT entries. */
6704 s
->size
+= PLT_SMALL_ENTRY_SIZE
;
6706 /* We also need to make an entry in the .got.plt section, which
6707 will be placed in the .got section by the linker script. */
6708 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
;
6710 /* We also need to make an entry in the .rela.plt section. */
6711 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
6713 /* We need to ensure that all GOT entries that serve the PLT
6714 are consecutive with the special GOT slots [0] [1] and
6715 [2]. Any addtional relocations, such as
6716 R_AARCH64_TLSDESC, must be placed after the PLT related
6717 entries. We abuse the reloc_count such that during
6718 sizing we adjust reloc_count to indicate the number of
6719 PLT related reserved entries. In subsequent phases when
6720 filling in the contents of the reloc entries, PLT related
6721 entries are placed by computing their PLT index (0
6722 .. reloc_count). While other none PLT relocs are placed
6723 at the slot indicated by reloc_count and reloc_count is
6726 htab
->root
.srelplt
->reloc_count
++;
6730 h
->plt
.offset
= (bfd_vma
) - 1;
6736 h
->plt
.offset
= (bfd_vma
) - 1;
6740 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6741 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
6743 if (h
->got
.refcount
> 0)
6746 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
6748 h
->got
.offset
= (bfd_vma
) - 1;
6750 dyn
= htab
->root
.dynamic_sections_created
;
6752 /* Make sure this symbol is output as a dynamic symbol.
6753 Undefined weak syms won't yet be marked as dynamic. */
6754 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
)
6756 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
6760 if (got_type
== GOT_UNKNOWN
)
6763 else if (got_type
== GOT_NORMAL
)
6765 h
->got
.offset
= htab
->root
.sgot
->size
;
6766 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
6767 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
6768 || h
->root
.type
!= bfd_link_hash_undefweak
)
6770 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
6772 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
6778 if (got_type
& GOT_TLSDESC_GD
)
6780 eh
->tlsdesc_got_jump_table_offset
=
6781 (htab
->root
.sgotplt
->size
6782 - aarch64_compute_jump_table_size (htab
));
6783 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
6784 h
->got
.offset
= (bfd_vma
) - 2;
6787 if (got_type
& GOT_TLS_GD
)
6789 h
->got
.offset
= htab
->root
.sgot
->size
;
6790 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
6793 if (got_type
& GOT_TLS_IE
)
6795 h
->got
.offset
= htab
->root
.sgot
->size
;
6796 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
6799 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
6800 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
6801 || h
->root
.type
!= bfd_link_hash_undefweak
)
6804 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
6806 if (got_type
& GOT_TLSDESC_GD
)
6808 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
6809 /* Note reloc_count not incremented here! We have
6810 already adjusted reloc_count for this relocation
6813 /* TLSDESC PLT is now needed, but not yet determined. */
6814 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
6817 if (got_type
& GOT_TLS_GD
)
6818 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
6820 if (got_type
& GOT_TLS_IE
)
6821 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
6827 h
->got
.offset
= (bfd_vma
) - 1;
6830 if (eh
->dyn_relocs
== NULL
)
6833 /* In the shared -Bsymbolic case, discard space allocated for
6834 dynamic pc-relative relocs against symbols which turn out to be
6835 defined in regular objects. For the normal shared case, discard
6836 space for pc-relative relocs that have become local due to symbol
6837 visibility changes. */
6841 /* Relocs that use pc_count are those that appear on a call
6842 insn, or certain REL relocs that can generated via assembly.
6843 We want calls to protected symbols to resolve directly to the
6844 function rather than going via the plt. If people want
6845 function pointer comparisons to work as expected then they
6846 should avoid writing weird assembly. */
6847 if (SYMBOL_CALLS_LOCAL (info
, h
))
6849 struct elf_dyn_relocs
**pp
;
6851 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
;)
6853 p
->count
-= p
->pc_count
;
6862 /* Also discard relocs on undefined weak syms with non-default
6864 if (eh
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
6866 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
6867 eh
->dyn_relocs
= NULL
;
6869 /* Make sure undefined weak symbols are output as a dynamic
6871 else if (h
->dynindx
== -1
6873 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
6878 else if (ELIMINATE_COPY_RELOCS
)
6880 /* For the non-shared case, discard space for relocs against
6881 symbols which turn out to need copy relocs or are not
6887 || (htab
->root
.dynamic_sections_created
6888 && (h
->root
.type
== bfd_link_hash_undefweak
6889 || h
->root
.type
== bfd_link_hash_undefined
))))
6891 /* Make sure this symbol is output as a dynamic symbol.
6892 Undefined weak syms won't yet be marked as dynamic. */
6893 if (h
->dynindx
== -1
6895 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
6898 /* If that succeeded, we know we'll be keeping all the
6900 if (h
->dynindx
!= -1)
6904 eh
->dyn_relocs
= NULL
;
6909 /* Finally, allocate space. */
6910 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
6914 sreloc
= elf_section_data (p
->sec
)->sreloc
;
6916 BFD_ASSERT (sreloc
!= NULL
);
6918 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
6924 /* Allocate space in .plt, .got and associated reloc sections for
6925 ifunc dynamic relocs. */
6928 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
6931 struct bfd_link_info
*info
;
6932 struct elf_aarch64_link_hash_table
*htab
;
6933 struct elf_aarch64_link_hash_entry
*eh
;
6935 /* An example of a bfd_link_hash_indirect symbol is versioned
6936 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
6937 -> __gxx_personality_v0(bfd_link_hash_defined)
6939 There is no need to process bfd_link_hash_indirect symbols here
6940 because we will also be presented with the concrete instance of
6941 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
6942 called to copy all relevant data from the generic to the concrete
6945 if (h
->root
.type
== bfd_link_hash_indirect
)
6948 if (h
->root
.type
== bfd_link_hash_warning
)
6949 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6951 info
= (struct bfd_link_info
*) inf
;
6952 htab
= elf_aarch64_hash_table (info
);
6954 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6956 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
6957 here if it is defined and referenced in a non-shared object. */
6958 if (h
->type
== STT_GNU_IFUNC
6960 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
6962 htab
->plt_entry_size
,
6963 htab
->plt_header_size
,
6968 /* Allocate space in .plt, .got and associated reloc sections for
6969 local dynamic relocs. */
6972 elfNN_aarch64_allocate_local_dynrelocs (void **slot
, void *inf
)
6974 struct elf_link_hash_entry
*h
6975 = (struct elf_link_hash_entry
*) *slot
;
6977 if (h
->type
!= STT_GNU_IFUNC
6981 || h
->root
.type
!= bfd_link_hash_defined
)
6984 return elfNN_aarch64_allocate_dynrelocs (h
, inf
);
6987 /* Allocate space in .plt, .got and associated reloc sections for
6988 local ifunc dynamic relocs. */
6991 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
6993 struct elf_link_hash_entry
*h
6994 = (struct elf_link_hash_entry
*) *slot
;
6996 if (h
->type
!= STT_GNU_IFUNC
7000 || h
->root
.type
!= bfd_link_hash_defined
)
7003 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
7006 /* This is the most important function of all . Innocuosly named
7009 elfNN_aarch64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
7010 struct bfd_link_info
*info
)
7012 struct elf_aarch64_link_hash_table
*htab
;
7018 htab
= elf_aarch64_hash_table ((info
));
7019 dynobj
= htab
->root
.dynobj
;
7021 BFD_ASSERT (dynobj
!= NULL
);
7023 if (htab
->root
.dynamic_sections_created
)
7025 if (info
->executable
)
7027 s
= bfd_get_linker_section (dynobj
, ".interp");
7030 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
7031 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
7035 /* Set up .got offsets for local syms, and space for local dynamic
7037 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
7039 struct elf_aarch64_local_symbol
*locals
= NULL
;
7040 Elf_Internal_Shdr
*symtab_hdr
;
7044 if (!is_aarch64_elf (ibfd
))
7047 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
7049 struct elf_dyn_relocs
*p
;
7051 for (p
= (struct elf_dyn_relocs
*)
7052 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
7054 if (!bfd_is_abs_section (p
->sec
)
7055 && bfd_is_abs_section (p
->sec
->output_section
))
7057 /* Input section has been discarded, either because
7058 it is a copy of a linkonce section or due to
7059 linker script /DISCARD/, so we'll be discarding
7062 else if (p
->count
!= 0)
7064 srel
= elf_section_data (p
->sec
)->sreloc
;
7065 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
7066 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
7067 info
->flags
|= DF_TEXTREL
;
7072 locals
= elf_aarch64_locals (ibfd
);
7076 symtab_hdr
= &elf_symtab_hdr (ibfd
);
7077 srel
= htab
->root
.srelgot
;
7078 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
7080 locals
[i
].got_offset
= (bfd_vma
) - 1;
7081 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
7082 if (locals
[i
].got_refcount
> 0)
7084 unsigned got_type
= locals
[i
].got_type
;
7085 if (got_type
& GOT_TLSDESC_GD
)
7087 locals
[i
].tlsdesc_got_jump_table_offset
=
7088 (htab
->root
.sgotplt
->size
7089 - aarch64_compute_jump_table_size (htab
));
7090 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
7091 locals
[i
].got_offset
= (bfd_vma
) - 2;
7094 if (got_type
& GOT_TLS_GD
)
7096 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
7097 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
7100 if (got_type
& GOT_TLS_IE
)
7102 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
7103 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7106 if (got_type
== GOT_UNKNOWN
)
7110 if (got_type
== GOT_NORMAL
)
7116 if (got_type
& GOT_TLSDESC_GD
)
7118 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7119 /* Note RELOC_COUNT not incremented here! */
7120 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
7123 if (got_type
& GOT_TLS_GD
)
7124 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
7126 if (got_type
& GOT_TLS_IE
)
7127 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7132 locals
[i
].got_refcount
= (bfd_vma
) - 1;
7138 /* Allocate global sym .plt and .got entries, and space for global
7139 sym dynamic relocs. */
7140 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
7143 /* Allocate global ifunc sym .plt and .got entries, and space for global
7144 ifunc sym dynamic relocs. */
7145 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
7148 /* Allocate .plt and .got entries, and space for local symbols. */
7149 htab_traverse (htab
->loc_hash_table
,
7150 elfNN_aarch64_allocate_local_dynrelocs
,
7153 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
7154 htab_traverse (htab
->loc_hash_table
,
7155 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
7158 /* For every jump slot reserved in the sgotplt, reloc_count is
7159 incremented. However, when we reserve space for TLS descriptors,
7160 it's not incremented, so in order to compute the space reserved
7161 for them, it suffices to multiply the reloc count by the jump
7164 if (htab
->root
.srelplt
)
7165 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
7167 if (htab
->tlsdesc_plt
)
7169 if (htab
->root
.splt
->size
== 0)
7170 htab
->root
.splt
->size
+= PLT_ENTRY_SIZE
;
7172 htab
->tlsdesc_plt
= htab
->root
.splt
->size
;
7173 htab
->root
.splt
->size
+= PLT_TLSDESC_ENTRY_SIZE
;
7175 /* If we're not using lazy TLS relocations, don't generate the
7176 GOT entry required. */
7177 if (!(info
->flags
& DF_BIND_NOW
))
7179 htab
->dt_tlsdesc_got
= htab
->root
.sgot
->size
;
7180 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7184 /* Init mapping symbols information to use later to distingush between
7185 code and data while scanning for erratam 835769. */
7186 if (htab
->fix_erratum_835769
)
7187 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
7189 if (!is_aarch64_elf (ibfd
))
7191 bfd_elfNN_aarch64_init_maps (ibfd
);
7194 /* We now have determined the sizes of the various dynamic sections.
7195 Allocate memory for them. */
7197 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
7199 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
7202 if (s
== htab
->root
.splt
7203 || s
== htab
->root
.sgot
7204 || s
== htab
->root
.sgotplt
7205 || s
== htab
->root
.iplt
7206 || s
== htab
->root
.igotplt
|| s
== htab
->sdynbss
)
7208 /* Strip this section if we don't need it; see the
7211 else if (CONST_STRNEQ (bfd_get_section_name (dynobj
, s
), ".rela"))
7213 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
7216 /* We use the reloc_count field as a counter if we need
7217 to copy relocs into the output file. */
7218 if (s
!= htab
->root
.srelplt
)
7223 /* It's not one of our sections, so don't allocate space. */
7229 /* If we don't need this section, strip it from the
7230 output file. This is mostly to handle .rela.bss and
7231 .rela.plt. We must create both sections in
7232 create_dynamic_sections, because they must be created
7233 before the linker maps input sections to output
7234 sections. The linker does that before
7235 adjust_dynamic_symbol is called, and it is that
7236 function which decides whether anything needs to go
7237 into these sections. */
7239 s
->flags
|= SEC_EXCLUDE
;
7243 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
7246 /* Allocate memory for the section contents. We use bfd_zalloc
7247 here in case unused entries are not reclaimed before the
7248 section's contents are written out. This should not happen,
7249 but this way if it does, we get a R_AARCH64_NONE reloc instead
7251 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
7252 if (s
->contents
== NULL
)
7256 if (htab
->root
.dynamic_sections_created
)
7258 /* Add some entries to the .dynamic section. We fill in the
7259 values later, in elfNN_aarch64_finish_dynamic_sections, but we
7260 must add the entries now so that we get the correct size for
7261 the .dynamic section. The DT_DEBUG entry is filled in by the
7262 dynamic linker and used by the debugger. */
7263 #define add_dynamic_entry(TAG, VAL) \
7264 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
7266 if (info
->executable
)
7268 if (!add_dynamic_entry (DT_DEBUG
, 0))
7272 if (htab
->root
.splt
->size
!= 0)
7274 if (!add_dynamic_entry (DT_PLTGOT
, 0)
7275 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
7276 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
7277 || !add_dynamic_entry (DT_JMPREL
, 0))
7280 if (htab
->tlsdesc_plt
7281 && (!add_dynamic_entry (DT_TLSDESC_PLT
, 0)
7282 || !add_dynamic_entry (DT_TLSDESC_GOT
, 0)))
7288 if (!add_dynamic_entry (DT_RELA
, 0)
7289 || !add_dynamic_entry (DT_RELASZ
, 0)
7290 || !add_dynamic_entry (DT_RELAENT
, RELOC_SIZE (htab
)))
7293 /* If any dynamic relocs apply to a read-only section,
7294 then we need a DT_TEXTREL entry. */
7295 if ((info
->flags
& DF_TEXTREL
) != 0)
7297 if (!add_dynamic_entry (DT_TEXTREL
, 0))
7302 #undef add_dynamic_entry
7308 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
7309 bfd_reloc_code_real_type r_type
,
7310 bfd_byte
*plt_entry
, bfd_vma value
)
7312 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
7314 _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
7318 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
7319 struct elf_aarch64_link_hash_table
7320 *htab
, bfd
*output_bfd
,
7321 struct bfd_link_info
*info
)
7323 bfd_byte
*plt_entry
;
7326 bfd_vma gotplt_entry_address
;
7327 bfd_vma plt_entry_address
;
7328 Elf_Internal_Rela rela
;
7330 asection
*plt
, *gotplt
, *relplt
;
7332 /* When building a static executable, use .iplt, .igot.plt and
7333 .rela.iplt sections for STT_GNU_IFUNC symbols. */
7334 if (htab
->root
.splt
!= NULL
)
7336 plt
= htab
->root
.splt
;
7337 gotplt
= htab
->root
.sgotplt
;
7338 relplt
= htab
->root
.srelplt
;
7342 plt
= htab
->root
.iplt
;
7343 gotplt
= htab
->root
.igotplt
;
7344 relplt
= htab
->root
.irelplt
;
7347 /* Get the index in the procedure linkage table which
7348 corresponds to this symbol. This is the index of this symbol
7349 in all the symbols for which we are making plt entries. The
7350 first entry in the procedure linkage table is reserved.
7352 Get the offset into the .got table of the entry that
7353 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
7354 bytes. The first three are reserved for the dynamic linker.
7356 For static executables, we don't reserve anything. */
7358 if (plt
== htab
->root
.splt
)
7360 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
7361 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
7365 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
7366 got_offset
= plt_index
* GOT_ENTRY_SIZE
;
7369 plt_entry
= plt
->contents
+ h
->plt
.offset
;
7370 plt_entry_address
= plt
->output_section
->vma
7371 + plt
->output_offset
+ h
->plt
.offset
;
7372 gotplt_entry_address
= gotplt
->output_section
->vma
+
7373 gotplt
->output_offset
+ got_offset
;
7375 /* Copy in the boiler-plate for the PLTn entry. */
7376 memcpy (plt_entry
, elfNN_aarch64_small_plt_entry
, PLT_SMALL_ENTRY_SIZE
);
7378 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
7379 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
7380 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
7382 PG (gotplt_entry_address
) -
7383 PG (plt_entry_address
));
7385 /* Fill in the lo12 bits for the load from the pltgot. */
7386 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
7388 PG_OFFSET (gotplt_entry_address
));
7390 /* Fill in the lo12 bits for the add from the pltgot entry. */
7391 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
7393 PG_OFFSET (gotplt_entry_address
));
7395 /* All the GOTPLT Entries are essentially initialized to PLT0. */
7396 bfd_put_NN (output_bfd
,
7397 plt
->output_section
->vma
+ plt
->output_offset
,
7398 gotplt
->contents
+ got_offset
);
7400 rela
.r_offset
= gotplt_entry_address
;
7402 if (h
->dynindx
== -1
7403 || ((info
->executable
7404 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
7406 && h
->type
== STT_GNU_IFUNC
))
7408 /* If an STT_GNU_IFUNC symbol is locally defined, generate
7409 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
7410 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
7411 rela
.r_addend
= (h
->root
.u
.def
.value
7412 + h
->root
.u
.def
.section
->output_section
->vma
7413 + h
->root
.u
.def
.section
->output_offset
);
7417 /* Fill in the entry in the .rela.plt section. */
7418 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
));
7422 /* Compute the relocation entry to used based on PLT index and do
7423 not adjust reloc_count. The reloc_count has already been adjusted
7424 to account for this entry. */
7425 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
7426 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7429 /* Size sections even though they're not dynamic. We use it to setup
7430 _TLS_MODULE_BASE_, if needed. */
7433 elfNN_aarch64_always_size_sections (bfd
*output_bfd
,
7434 struct bfd_link_info
*info
)
7438 if (info
->relocatable
)
7441 tls_sec
= elf_hash_table (info
)->tls_sec
;
7445 struct elf_link_hash_entry
*tlsbase
;
7447 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
7448 "_TLS_MODULE_BASE_", TRUE
, TRUE
, FALSE
);
7452 struct bfd_link_hash_entry
*h
= NULL
;
7453 const struct elf_backend_data
*bed
=
7454 get_elf_backend_data (output_bfd
);
7456 if (!(_bfd_generic_link_add_one_symbol
7457 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
7458 tls_sec
, 0, NULL
, FALSE
, bed
->collect
, &h
)))
7461 tlsbase
->type
= STT_TLS
;
7462 tlsbase
= (struct elf_link_hash_entry
*) h
;
7463 tlsbase
->def_regular
= 1;
7464 tlsbase
->other
= STV_HIDDEN
;
7465 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, TRUE
);
7472 /* Finish up dynamic symbol handling. We set the contents of various
7473 dynamic sections here. */
7475 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
7476 struct bfd_link_info
*info
,
7477 struct elf_link_hash_entry
*h
,
7478 Elf_Internal_Sym
*sym
)
7480 struct elf_aarch64_link_hash_table
*htab
;
7481 htab
= elf_aarch64_hash_table (info
);
7483 if (h
->plt
.offset
!= (bfd_vma
) - 1)
7485 asection
*plt
, *gotplt
, *relplt
;
7487 /* This symbol has an entry in the procedure linkage table. Set
7490 /* When building a static executable, use .iplt, .igot.plt and
7491 .rela.iplt sections for STT_GNU_IFUNC symbols. */
7492 if (htab
->root
.splt
!= NULL
)
7494 plt
= htab
->root
.splt
;
7495 gotplt
= htab
->root
.sgotplt
;
7496 relplt
= htab
->root
.srelplt
;
7500 plt
= htab
->root
.iplt
;
7501 gotplt
= htab
->root
.igotplt
;
7502 relplt
= htab
->root
.irelplt
;
7505 /* This symbol has an entry in the procedure linkage table. Set
7507 if ((h
->dynindx
== -1
7508 && !((h
->forced_local
|| info
->executable
)
7510 && h
->type
== STT_GNU_IFUNC
))
7516 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
7517 if (!h
->def_regular
)
7519 /* Mark the symbol as undefined, rather than as defined in
7520 the .plt section. */
7521 sym
->st_shndx
= SHN_UNDEF
;
7522 /* If the symbol is weak we need to clear the value.
7523 Otherwise, the PLT entry would provide a definition for
7524 the symbol even if the symbol wasn't defined anywhere,
7525 and so the symbol would never be NULL. Leave the value if
7526 there were any relocations where pointer equality matters
7527 (this is a clue for the dynamic linker, to make function
7528 pointer comparisons work between an application and shared
7530 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
7535 if (h
->got
.offset
!= (bfd_vma
) - 1
7536 && elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
)
7538 Elf_Internal_Rela rela
;
7541 /* This symbol has an entry in the global offset table. Set it
7543 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
7546 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
7547 + htab
->root
.sgot
->output_offset
7548 + (h
->got
.offset
& ~(bfd_vma
) 1));
7551 && h
->type
== STT_GNU_IFUNC
)
7555 /* Generate R_AARCH64_GLOB_DAT. */
7562 if (!h
->pointer_equality_needed
)
7565 /* For non-shared object, we can't use .got.plt, which
7566 contains the real function address if we need pointer
7567 equality. We load the GOT entry with the PLT entry. */
7568 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
7569 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
7570 + plt
->output_offset
7572 htab
->root
.sgot
->contents
7573 + (h
->got
.offset
& ~(bfd_vma
) 1));
7577 else if (info
->shared
&& SYMBOL_REFERENCES_LOCAL (info
, h
))
7579 if (!h
->def_regular
)
7582 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
7583 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
7584 rela
.r_addend
= (h
->root
.u
.def
.value
7585 + h
->root
.u
.def
.section
->output_section
->vma
7586 + h
->root
.u
.def
.section
->output_offset
);
7591 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
7592 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
7593 htab
->root
.sgot
->contents
+ h
->got
.offset
);
7594 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (GLOB_DAT
));
7598 loc
= htab
->root
.srelgot
->contents
;
7599 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
7600 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7605 Elf_Internal_Rela rela
;
7608 /* This symbol needs a copy reloc. Set it up. */
7610 if (h
->dynindx
== -1
7611 || (h
->root
.type
!= bfd_link_hash_defined
7612 && h
->root
.type
!= bfd_link_hash_defweak
)
7613 || htab
->srelbss
== NULL
)
7616 rela
.r_offset
= (h
->root
.u
.def
.value
7617 + h
->root
.u
.def
.section
->output_section
->vma
7618 + h
->root
.u
.def
.section
->output_offset
);
7619 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
7621 loc
= htab
->srelbss
->contents
;
7622 loc
+= htab
->srelbss
->reloc_count
++ * RELOC_SIZE (htab
);
7623 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7626 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
7627 be NULL for local symbols. */
7629 && (h
== elf_hash_table (info
)->hdynamic
7630 || h
== elf_hash_table (info
)->hgot
))
7631 sym
->st_shndx
= SHN_ABS
;
7636 /* Finish up local dynamic symbol handling. We set the contents of
7637 various dynamic sections here. */
7640 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
7642 struct elf_link_hash_entry
*h
7643 = (struct elf_link_hash_entry
*) *slot
;
7644 struct bfd_link_info
*info
7645 = (struct bfd_link_info
*) inf
;
7647 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
7652 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
7653 struct elf_aarch64_link_hash_table
7656 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
7657 small and large plts and at the minute just generates
7660 /* PLT0 of the small PLT looks like this in ELF64 -
7661 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
7662 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
7663 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
7665 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
7666 // GOTPLT entry for this.
7668 PLT0 will be slightly different in ELF32 due to different got entry
7671 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
7675 memcpy (htab
->root
.splt
->contents
, elfNN_aarch64_small_plt0_entry
,
7677 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
=
7680 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
7681 + htab
->root
.sgotplt
->output_offset
7682 + GOT_ENTRY_SIZE
* 2);
7684 plt_base
= htab
->root
.splt
->output_section
->vma
+
7685 htab
->root
.splt
->output_offset
;
7687 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
7688 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
7689 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
7690 htab
->root
.splt
->contents
+ 4,
7691 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
7693 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
7694 htab
->root
.splt
->contents
+ 8,
7695 PG_OFFSET (plt_got_2nd_ent
));
7697 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
7698 htab
->root
.splt
->contents
+ 12,
7699 PG_OFFSET (plt_got_2nd_ent
));
7703 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
7704 struct bfd_link_info
*info
)
7706 struct elf_aarch64_link_hash_table
*htab
;
7710 htab
= elf_aarch64_hash_table (info
);
7711 dynobj
= htab
->root
.dynobj
;
7712 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
7714 if (htab
->root
.dynamic_sections_created
)
7716 ElfNN_External_Dyn
*dyncon
, *dynconend
;
7718 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
7721 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
7722 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
7723 for (; dyncon
< dynconend
; dyncon
++)
7725 Elf_Internal_Dyn dyn
;
7728 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
7736 s
= htab
->root
.sgotplt
;
7737 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
7741 dyn
.d_un
.d_ptr
= htab
->root
.srelplt
->output_section
->vma
;
7745 s
= htab
->root
.srelplt
;
7746 dyn
.d_un
.d_val
= s
->size
;
7750 /* The procedure linkage table relocs (DT_JMPREL) should
7751 not be included in the overall relocs (DT_RELA).
7752 Therefore, we override the DT_RELASZ entry here to
7753 make it not include the JMPREL relocs. Since the
7754 linker script arranges for .rela.plt to follow all
7755 other relocation sections, we don't have to worry
7756 about changing the DT_RELA entry. */
7757 if (htab
->root
.srelplt
!= NULL
)
7759 s
= htab
->root
.srelplt
;
7760 dyn
.d_un
.d_val
-= s
->size
;
7764 case DT_TLSDESC_PLT
:
7765 s
= htab
->root
.splt
;
7766 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
7767 + htab
->tlsdesc_plt
;
7770 case DT_TLSDESC_GOT
:
7771 s
= htab
->root
.sgot
;
7772 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
7773 + htab
->dt_tlsdesc_got
;
7777 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
7782 /* Fill in the special first entry in the procedure linkage table. */
7783 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
7785 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
7787 elf_section_data (htab
->root
.splt
->output_section
)->
7788 this_hdr
.sh_entsize
= htab
->plt_entry_size
;
7791 if (htab
->tlsdesc_plt
)
7793 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
7794 htab
->root
.sgot
->contents
+ htab
->dt_tlsdesc_got
);
7796 memcpy (htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
,
7797 elfNN_aarch64_tlsdesc_small_plt_entry
,
7798 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry
));
7801 bfd_vma adrp1_addr
=
7802 htab
->root
.splt
->output_section
->vma
7803 + htab
->root
.splt
->output_offset
+ htab
->tlsdesc_plt
+ 4;
7805 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
7808 htab
->root
.sgot
->output_section
->vma
7809 + htab
->root
.sgot
->output_offset
;
7811 bfd_vma pltgot_addr
=
7812 htab
->root
.sgotplt
->output_section
->vma
7813 + htab
->root
.sgotplt
->output_offset
;
7815 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->dt_tlsdesc_got
;
7817 bfd_byte
*plt_entry
=
7818 htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
;
7820 /* adrp x2, DT_TLSDESC_GOT */
7821 elf_aarch64_update_plt_entry (output_bfd
,
7822 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
7824 (PG (dt_tlsdesc_got
)
7825 - PG (adrp1_addr
)));
7828 elf_aarch64_update_plt_entry (output_bfd
,
7829 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
7832 - PG (adrp2_addr
)));
7834 /* ldr x2, [x2, #0] */
7835 elf_aarch64_update_plt_entry (output_bfd
,
7836 BFD_RELOC_AARCH64_LDSTNN_LO12
,
7838 PG_OFFSET (dt_tlsdesc_got
));
7841 elf_aarch64_update_plt_entry (output_bfd
,
7842 BFD_RELOC_AARCH64_ADD_LO12
,
7844 PG_OFFSET (pltgot_addr
));
7849 if (htab
->root
.sgotplt
)
7851 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
7853 (*_bfd_error_handler
)
7854 (_("discarded output section: `%A'"), htab
->root
.sgotplt
);
7858 /* Fill in the first three entries in the global offset table. */
7859 if (htab
->root
.sgotplt
->size
> 0)
7861 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
7863 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
7864 bfd_put_NN (output_bfd
,
7866 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
7867 bfd_put_NN (output_bfd
,
7869 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
* 2);
7872 if (htab
->root
.sgot
)
7874 if (htab
->root
.sgot
->size
> 0)
7877 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
7878 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
7882 elf_section_data (htab
->root
.sgotplt
->output_section
)->
7883 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
7886 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
7887 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
7890 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
7891 htab_traverse (htab
->loc_hash_table
,
7892 elfNN_aarch64_finish_local_dynamic_symbol
,
7898 /* Return address for Ith PLT stub in section PLT, for relocation REL
7899 or (bfd_vma) -1 if it should not be included. */
7902 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
7903 const arelent
*rel ATTRIBUTE_UNUSED
)
7905 return plt
->vma
+ PLT_ENTRY_SIZE
+ i
* PLT_SMALL_ENTRY_SIZE
;
7909 /* We use this so we can override certain functions
7910 (though currently we don't). */
7912 const struct elf_size_info elfNN_aarch64_size_info
=
7914 sizeof (ElfNN_External_Ehdr
),
7915 sizeof (ElfNN_External_Phdr
),
7916 sizeof (ElfNN_External_Shdr
),
7917 sizeof (ElfNN_External_Rel
),
7918 sizeof (ElfNN_External_Rela
),
7919 sizeof (ElfNN_External_Sym
),
7920 sizeof (ElfNN_External_Dyn
),
7921 sizeof (Elf_External_Note
),
7922 4, /* Hash table entry size. */
7923 1, /* Internal relocs per external relocs. */
7924 ARCH_SIZE
, /* Arch size. */
7925 LOG_FILE_ALIGN
, /* Log_file_align. */
7926 ELFCLASSNN
, EV_CURRENT
,
7927 bfd_elfNN_write_out_phdrs
,
7928 bfd_elfNN_write_shdrs_and_ehdr
,
7929 bfd_elfNN_checksum_contents
,
7930 bfd_elfNN_write_relocs
,
7931 bfd_elfNN_swap_symbol_in
,
7932 bfd_elfNN_swap_symbol_out
,
7933 bfd_elfNN_slurp_reloc_table
,
7934 bfd_elfNN_slurp_symbol_table
,
7935 bfd_elfNN_swap_dyn_in
,
7936 bfd_elfNN_swap_dyn_out
,
7937 bfd_elfNN_swap_reloc_in
,
7938 bfd_elfNN_swap_reloc_out
,
7939 bfd_elfNN_swap_reloca_in
,
7940 bfd_elfNN_swap_reloca_out
7943 #define ELF_ARCH bfd_arch_aarch64
7944 #define ELF_MACHINE_CODE EM_AARCH64
7945 #define ELF_MAXPAGESIZE 0x10000
7946 #define ELF_MINPAGESIZE 0x1000
7947 #define ELF_COMMONPAGESIZE 0x1000
7949 #define bfd_elfNN_close_and_cleanup \
7950 elfNN_aarch64_close_and_cleanup
7952 #define bfd_elfNN_bfd_free_cached_info \
7953 elfNN_aarch64_bfd_free_cached_info
7955 #define bfd_elfNN_bfd_is_target_special_symbol \
7956 elfNN_aarch64_is_target_special_symbol
7958 #define bfd_elfNN_bfd_link_hash_table_create \
7959 elfNN_aarch64_link_hash_table_create
7961 #define bfd_elfNN_bfd_merge_private_bfd_data \
7962 elfNN_aarch64_merge_private_bfd_data
7964 #define bfd_elfNN_bfd_print_private_bfd_data \
7965 elfNN_aarch64_print_private_bfd_data
7967 #define bfd_elfNN_bfd_reloc_type_lookup \
7968 elfNN_aarch64_reloc_type_lookup
7970 #define bfd_elfNN_bfd_reloc_name_lookup \
7971 elfNN_aarch64_reloc_name_lookup
7973 #define bfd_elfNN_bfd_set_private_flags \
7974 elfNN_aarch64_set_private_flags
7976 #define bfd_elfNN_find_inliner_info \
7977 elfNN_aarch64_find_inliner_info
7979 #define bfd_elfNN_find_nearest_line \
7980 elfNN_aarch64_find_nearest_line
7982 #define bfd_elfNN_mkobject \
7983 elfNN_aarch64_mkobject
7985 #define bfd_elfNN_new_section_hook \
7986 elfNN_aarch64_new_section_hook
7988 #define elf_backend_adjust_dynamic_symbol \
7989 elfNN_aarch64_adjust_dynamic_symbol
7991 #define elf_backend_always_size_sections \
7992 elfNN_aarch64_always_size_sections
7994 #define elf_backend_check_relocs \
7995 elfNN_aarch64_check_relocs
7997 #define elf_backend_copy_indirect_symbol \
7998 elfNN_aarch64_copy_indirect_symbol
8000 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
8001 to them in our hash. */
8002 #define elf_backend_create_dynamic_sections \
8003 elfNN_aarch64_create_dynamic_sections
8005 #define elf_backend_init_index_section \
8006 _bfd_elf_init_2_index_sections
8008 #define elf_backend_finish_dynamic_sections \
8009 elfNN_aarch64_finish_dynamic_sections
8011 #define elf_backend_finish_dynamic_symbol \
8012 elfNN_aarch64_finish_dynamic_symbol
8014 #define elf_backend_gc_sweep_hook \
8015 elfNN_aarch64_gc_sweep_hook
8017 #define elf_backend_object_p \
8018 elfNN_aarch64_object_p
8020 #define elf_backend_output_arch_local_syms \
8021 elfNN_aarch64_output_arch_local_syms
8023 #define elf_backend_plt_sym_val \
8024 elfNN_aarch64_plt_sym_val
8026 #define elf_backend_post_process_headers \
8027 elfNN_aarch64_post_process_headers
8029 #define elf_backend_relocate_section \
8030 elfNN_aarch64_relocate_section
8032 #define elf_backend_reloc_type_class \
8033 elfNN_aarch64_reloc_type_class
8035 #define elf_backend_section_from_shdr \
8036 elfNN_aarch64_section_from_shdr
8038 #define elf_backend_size_dynamic_sections \
8039 elfNN_aarch64_size_dynamic_sections
8041 #define elf_backend_size_info \
8042 elfNN_aarch64_size_info
8044 #define elf_backend_write_section \
8045 elfNN_aarch64_write_section
8047 #define elf_backend_can_refcount 1
8048 #define elf_backend_can_gc_sections 1
8049 #define elf_backend_plt_readonly 1
8050 #define elf_backend_want_got_plt 1
8051 #define elf_backend_want_plt_sym 0
8052 #define elf_backend_may_use_rel_p 0
8053 #define elf_backend_may_use_rela_p 1
8054 #define elf_backend_default_use_rela_p 1
8055 #define elf_backend_rela_normal 1
8056 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
8057 #define elf_backend_default_execstack 0
8059 #undef elf_backend_obj_attrs_section
8060 #define elf_backend_obj_attrs_section ".ARM.attributes"
8062 #include "elfNN-target.h"