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