1 /* AArch64-specific support for NN-bit ELF.
2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* Notes on implementation:
23 Thread Local Store (TLS)
27 The implementation currently supports both traditional TLS and TLS
28 descriptors, but only general dynamic (GD).
30 For traditional TLS the assembler will present us with code
31 fragments of the form:
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
40 For TLS descriptors the assembler will present us with code
41 fragments of the form:
43 adrp x0, :tlsdesc:foo R_AARCH64_TLSDESC_ADR_PAGE21(foo)
44 ldr x1, [x0, #:tlsdesc_lo12:foo] R_AARCH64_TLSDESC_LD64_LO12(foo)
45 add x0, x0, #:tlsdesc_lo12:foo R_AARCH64_TLSDESC_ADD_LO12(foo)
47 blr x1 R_AARCH64_TLSDESC_CALL(foo)
49 The relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} against foo
50 indicate that foo is thread local and should be accessed via the
51 traditional TLS mechanims.
53 The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
54 against foo indicate that 'foo' is thread local and should be accessed
55 via a TLS descriptor mechanism.
57 The precise instruction sequence is only relevant from the
58 perspective of linker relaxation which is currently not implemented.
60 The static linker must detect that 'foo' is a TLS object and
61 allocate a double GOT entry. The GOT entry must be created for both
62 global and local TLS symbols. Note that this is different to none
63 TLS local objects which do not need a GOT entry.
65 In the traditional TLS mechanism, the double GOT entry is used to
66 provide the tls_index structure, containing module and offset
67 entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
68 on the module entry. The loader will subsequently fixup this
69 relocation with the module identity.
71 For global traditional TLS symbols the static linker places an
72 R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
73 will subsequently fixup the offset. For local TLS symbols the static
74 linker fixes up offset.
76 In the TLS descriptor mechanism the double GOT entry is used to
77 provide the descriptor. The static linker places the relocation
78 R_AARCH64_TLSDESC on the first GOT slot. The loader will
79 subsequently fix this up.
83 The handling of TLS symbols is implemented across a number of
84 different backend functions. The following is a top level view of
85 what processing is performed where.
87 The TLS implementation maintains state information for each TLS
88 symbol. The state information for local and global symbols is kept
89 in different places. Global symbols use generic BFD structures while
90 local symbols use backend specific structures that are allocated and
91 maintained entirely by the backend.
95 elfNN_aarch64_check_relocs()
97 This function is invoked for each relocation.
99 The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
100 R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
101 spotted. One time creation of local symbol data structures are
102 created when the first local symbol is seen.
104 The reference count for a symbol is incremented. The GOT type for
105 each symbol is marked as general dynamic.
107 elfNN_aarch64_allocate_dynrelocs ()
109 For each global with positive reference count we allocate a double
110 GOT slot. For a traditional TLS symbol we allocate space for two
111 relocation entries on the GOT, for a TLS descriptor symbol we
112 allocate space for one relocation on the slot. Record the GOT offset
115 elfNN_aarch64_size_dynamic_sections ()
117 Iterate all input BFDS, look for in the local symbol data structure
118 constructed earlier for local TLS symbols and allocate them double
119 GOT slots along with space for a single GOT relocation. Update the
120 local symbol structure to record the GOT offset allocated.
122 elfNN_aarch64_relocate_section ()
124 Calls elfNN_aarch64_final_link_relocate ()
126 Emit the relevant TLS relocations against the GOT for each TLS
127 symbol. For local TLS symbols emit the GOT offset directly. The GOT
128 relocations are emitted once the first time a TLS symbol is
129 encountered. The implementation uses the LSB of the GOT offset to
130 flag that the relevant GOT relocations for a symbol have been
131 emitted. All of the TLS code that uses the GOT offset needs to take
132 care to mask out this flag bit before using the offset.
134 elfNN_aarch64_final_link_relocate ()
136 Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
140 #include "libiberty.h"
142 #include "bfd_stdint.h"
145 #include "objalloc.h"
146 #include "elf/aarch64.h"
147 #include "elfxx-aarch64.h"
152 #define AARCH64_R(NAME) R_AARCH64_ ## NAME
153 #define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
154 #define HOWTO64(...) HOWTO (__VA_ARGS__)
155 #define HOWTO32(...) EMPTY_HOWTO (0)
156 #define LOG_FILE_ALIGN 3
160 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
161 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
162 #define HOWTO64(...) EMPTY_HOWTO (0)
163 #define HOWTO32(...) HOWTO (__VA_ARGS__)
164 #define LOG_FILE_ALIGN 2
167 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
168 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
169 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
170 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
171 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12 \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12 \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0 \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1 \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2 \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
199 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
201 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
202 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
207 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
208 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
209 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
210 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
212 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
213 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC)
215 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
216 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
220 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
221 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
222 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
223 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
224 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
225 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
226 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
227 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
229 #define ELIMINATE_COPY_RELOCS 0
231 /* Return size of a relocation entry. HTAB is the bfd's
232 elf_aarch64_link_hash_entry. */
233 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
235 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
236 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
237 #define PLT_ENTRY_SIZE (32)
238 #define PLT_SMALL_ENTRY_SIZE (16)
239 #define PLT_TLSDESC_ENTRY_SIZE (32)
241 /* Encoding of the nop instruction */
242 #define INSN_NOP 0xd503201f
244 #define aarch64_compute_jump_table_size(htab) \
245 (((htab)->root.srelplt == NULL) ? 0 \
246 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
248 /* The first entry in a procedure linkage table looks like this
249 if the distance between the PLTGOT and the PLT is < 4GB use
250 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
251 in x16 and needs to work out PLTGOT[1] by using an address of
252 [x16,#-GOT_ENTRY_SIZE]. */
253 static const bfd_byte elfNN_aarch64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
255 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
256 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
258 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
259 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
261 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
262 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
264 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
265 0x1f, 0x20, 0x03, 0xd5, /* nop */
266 0x1f, 0x20, 0x03, 0xd5, /* nop */
267 0x1f, 0x20, 0x03, 0xd5, /* nop */
270 /* Per function entry in a procedure linkage table looks like this
271 if the distance between the PLTGOT and the PLT is < 4GB use
272 these PLT entries. */
273 static const bfd_byte elfNN_aarch64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
275 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
277 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
278 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
280 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
281 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
283 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
286 static const bfd_byte
287 elfNN_aarch64_tlsdesc_small_plt_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
289 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
290 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
291 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
293 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
294 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
296 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
297 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
299 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
300 0x1f, 0x20, 0x03, 0xd5, /* nop */
301 0x1f, 0x20, 0x03, 0xd5, /* nop */
304 #define elf_info_to_howto elfNN_aarch64_info_to_howto
305 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
307 #define AARCH64_ELF_ABI_VERSION 0
309 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
310 #define ALL_ONES (~ (bfd_vma) 0)
312 /* Indexed by the bfd interal reloc enumerators.
313 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
316 static reloc_howto_type elfNN_aarch64_howto_table
[] =
320 /* Basic data relocations. */
323 HOWTO (R_AARCH64_NULL
, /* type */
325 3, /* size (0 = byte, 1 = short, 2 = long) */
327 FALSE
, /* pc_relative */
329 complain_overflow_dont
, /* complain_on_overflow */
330 bfd_elf_generic_reloc
, /* special_function */
331 "R_AARCH64_NULL", /* name */
332 FALSE
, /* partial_inplace */
335 FALSE
), /* pcrel_offset */
337 HOWTO (R_AARCH64_NONE
, /* type */
339 3, /* size (0 = byte, 1 = short, 2 = long) */
341 FALSE
, /* pc_relative */
343 complain_overflow_dont
, /* complain_on_overflow */
344 bfd_elf_generic_reloc
, /* special_function */
345 "R_AARCH64_NONE", /* name */
346 FALSE
, /* partial_inplace */
349 FALSE
), /* pcrel_offset */
353 HOWTO64 (AARCH64_R (ABS64
), /* type */
355 4, /* size (4 = long long) */
357 FALSE
, /* pc_relative */
359 complain_overflow_unsigned
, /* complain_on_overflow */
360 bfd_elf_generic_reloc
, /* special_function */
361 AARCH64_R_STR (ABS64
), /* name */
362 FALSE
, /* partial_inplace */
363 ALL_ONES
, /* src_mask */
364 ALL_ONES
, /* dst_mask */
365 FALSE
), /* pcrel_offset */
368 HOWTO (AARCH64_R (ABS32
), /* type */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
372 FALSE
, /* pc_relative */
374 complain_overflow_unsigned
, /* complain_on_overflow */
375 bfd_elf_generic_reloc
, /* special_function */
376 AARCH64_R_STR (ABS32
), /* name */
377 FALSE
, /* partial_inplace */
378 0xffffffff, /* src_mask */
379 0xffffffff, /* dst_mask */
380 FALSE
), /* pcrel_offset */
383 HOWTO (AARCH64_R (ABS16
), /* type */
385 1, /* size (0 = byte, 1 = short, 2 = long) */
387 FALSE
, /* pc_relative */
389 complain_overflow_unsigned
, /* complain_on_overflow */
390 bfd_elf_generic_reloc
, /* special_function */
391 AARCH64_R_STR (ABS16
), /* name */
392 FALSE
, /* partial_inplace */
393 0xffff, /* src_mask */
394 0xffff, /* dst_mask */
395 FALSE
), /* pcrel_offset */
397 /* .xword: (S+A-P) */
398 HOWTO64 (AARCH64_R (PREL64
), /* type */
400 4, /* size (4 = long long) */
402 TRUE
, /* pc_relative */
404 complain_overflow_signed
, /* complain_on_overflow */
405 bfd_elf_generic_reloc
, /* special_function */
406 AARCH64_R_STR (PREL64
), /* name */
407 FALSE
, /* partial_inplace */
408 ALL_ONES
, /* src_mask */
409 ALL_ONES
, /* dst_mask */
410 TRUE
), /* pcrel_offset */
413 HOWTO (AARCH64_R (PREL32
), /* type */
415 2, /* size (0 = byte, 1 = short, 2 = long) */
417 TRUE
, /* pc_relative */
419 complain_overflow_signed
, /* complain_on_overflow */
420 bfd_elf_generic_reloc
, /* special_function */
421 AARCH64_R_STR (PREL32
), /* name */
422 FALSE
, /* partial_inplace */
423 0xffffffff, /* src_mask */
424 0xffffffff, /* dst_mask */
425 TRUE
), /* pcrel_offset */
428 HOWTO (AARCH64_R (PREL16
), /* type */
430 1, /* size (0 = byte, 1 = short, 2 = long) */
432 TRUE
, /* pc_relative */
434 complain_overflow_signed
, /* complain_on_overflow */
435 bfd_elf_generic_reloc
, /* special_function */
436 AARCH64_R_STR (PREL16
), /* name */
437 FALSE
, /* partial_inplace */
438 0xffff, /* src_mask */
439 0xffff, /* dst_mask */
440 TRUE
), /* pcrel_offset */
442 /* Group relocations to create a 16, 32, 48 or 64 bit
443 unsigned data or abs address inline. */
445 /* MOVZ: ((S+A) >> 0) & 0xffff */
446 HOWTO (AARCH64_R (MOVW_UABS_G0
), /* type */
448 2, /* size (0 = byte, 1 = short, 2 = long) */
450 FALSE
, /* pc_relative */
452 complain_overflow_unsigned
, /* complain_on_overflow */
453 bfd_elf_generic_reloc
, /* special_function */
454 AARCH64_R_STR (MOVW_UABS_G0
), /* name */
455 FALSE
, /* partial_inplace */
456 0xffff, /* src_mask */
457 0xffff, /* dst_mask */
458 FALSE
), /* pcrel_offset */
460 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
461 HOWTO (AARCH64_R (MOVW_UABS_G0_NC
), /* type */
463 2, /* size (0 = byte, 1 = short, 2 = long) */
465 FALSE
, /* pc_relative */
467 complain_overflow_dont
, /* complain_on_overflow */
468 bfd_elf_generic_reloc
, /* special_function */
469 AARCH64_R_STR (MOVW_UABS_G0_NC
), /* name */
470 FALSE
, /* partial_inplace */
471 0xffff, /* src_mask */
472 0xffff, /* dst_mask */
473 FALSE
), /* pcrel_offset */
475 /* MOVZ: ((S+A) >> 16) & 0xffff */
476 HOWTO (AARCH64_R (MOVW_UABS_G1
), /* type */
478 2, /* size (0 = byte, 1 = short, 2 = long) */
480 FALSE
, /* pc_relative */
482 complain_overflow_unsigned
, /* complain_on_overflow */
483 bfd_elf_generic_reloc
, /* special_function */
484 AARCH64_R_STR (MOVW_UABS_G1
), /* name */
485 FALSE
, /* partial_inplace */
486 0xffff, /* src_mask */
487 0xffff, /* dst_mask */
488 FALSE
), /* pcrel_offset */
490 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
491 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC
), /* type */
493 2, /* size (0 = byte, 1 = short, 2 = long) */
495 FALSE
, /* pc_relative */
497 complain_overflow_dont
, /* complain_on_overflow */
498 bfd_elf_generic_reloc
, /* special_function */
499 AARCH64_R_STR (MOVW_UABS_G1_NC
), /* name */
500 FALSE
, /* partial_inplace */
501 0xffff, /* src_mask */
502 0xffff, /* dst_mask */
503 FALSE
), /* pcrel_offset */
505 /* MOVZ: ((S+A) >> 32) & 0xffff */
506 HOWTO64 (AARCH64_R (MOVW_UABS_G2
), /* type */
508 2, /* size (0 = byte, 1 = short, 2 = long) */
510 FALSE
, /* pc_relative */
512 complain_overflow_unsigned
, /* complain_on_overflow */
513 bfd_elf_generic_reloc
, /* special_function */
514 AARCH64_R_STR (MOVW_UABS_G2
), /* name */
515 FALSE
, /* partial_inplace */
516 0xffff, /* src_mask */
517 0xffff, /* dst_mask */
518 FALSE
), /* pcrel_offset */
520 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
521 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC
), /* type */
523 2, /* size (0 = byte, 1 = short, 2 = long) */
525 FALSE
, /* pc_relative */
527 complain_overflow_dont
, /* complain_on_overflow */
528 bfd_elf_generic_reloc
, /* special_function */
529 AARCH64_R_STR (MOVW_UABS_G2_NC
), /* name */
530 FALSE
, /* partial_inplace */
531 0xffff, /* src_mask */
532 0xffff, /* dst_mask */
533 FALSE
), /* pcrel_offset */
535 /* MOVZ: ((S+A) >> 48) & 0xffff */
536 HOWTO64 (AARCH64_R (MOVW_UABS_G3
), /* type */
538 2, /* size (0 = byte, 1 = short, 2 = long) */
540 FALSE
, /* pc_relative */
542 complain_overflow_unsigned
, /* complain_on_overflow */
543 bfd_elf_generic_reloc
, /* special_function */
544 AARCH64_R_STR (MOVW_UABS_G3
), /* name */
545 FALSE
, /* partial_inplace */
546 0xffff, /* src_mask */
547 0xffff, /* dst_mask */
548 FALSE
), /* pcrel_offset */
550 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
551 signed data or abs address inline. Will change instruction
552 to MOVN or MOVZ depending on sign of calculated value. */
554 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
555 HOWTO (AARCH64_R (MOVW_SABS_G0
), /* type */
557 2, /* size (0 = byte, 1 = short, 2 = long) */
559 FALSE
, /* pc_relative */
561 complain_overflow_signed
, /* complain_on_overflow */
562 bfd_elf_generic_reloc
, /* special_function */
563 AARCH64_R_STR (MOVW_SABS_G0
), /* name */
564 FALSE
, /* partial_inplace */
565 0xffff, /* src_mask */
566 0xffff, /* dst_mask */
567 FALSE
), /* pcrel_offset */
569 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
570 HOWTO64 (AARCH64_R (MOVW_SABS_G1
), /* type */
572 2, /* size (0 = byte, 1 = short, 2 = long) */
574 FALSE
, /* pc_relative */
576 complain_overflow_signed
, /* complain_on_overflow */
577 bfd_elf_generic_reloc
, /* special_function */
578 AARCH64_R_STR (MOVW_SABS_G1
), /* name */
579 FALSE
, /* partial_inplace */
580 0xffff, /* src_mask */
581 0xffff, /* dst_mask */
582 FALSE
), /* pcrel_offset */
584 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
585 HOWTO64 (AARCH64_R (MOVW_SABS_G2
), /* type */
587 2, /* size (0 = byte, 1 = short, 2 = long) */
589 FALSE
, /* pc_relative */
591 complain_overflow_signed
, /* complain_on_overflow */
592 bfd_elf_generic_reloc
, /* special_function */
593 AARCH64_R_STR (MOVW_SABS_G2
), /* name */
594 FALSE
, /* partial_inplace */
595 0xffff, /* src_mask */
596 0xffff, /* dst_mask */
597 FALSE
), /* pcrel_offset */
599 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
600 addresses: PG(x) is (x & ~0xfff). */
602 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
603 HOWTO (AARCH64_R (LD_PREL_LO19
), /* type */
605 2, /* size (0 = byte, 1 = short, 2 = long) */
607 TRUE
, /* pc_relative */
609 complain_overflow_signed
, /* complain_on_overflow */
610 bfd_elf_generic_reloc
, /* special_function */
611 AARCH64_R_STR (LD_PREL_LO19
), /* name */
612 FALSE
, /* partial_inplace */
613 0x7ffff, /* src_mask */
614 0x7ffff, /* dst_mask */
615 TRUE
), /* pcrel_offset */
617 /* ADR: (S+A-P) & 0x1fffff */
618 HOWTO (AARCH64_R (ADR_PREL_LO21
), /* type */
620 2, /* size (0 = byte, 1 = short, 2 = long) */
622 TRUE
, /* pc_relative */
624 complain_overflow_signed
, /* complain_on_overflow */
625 bfd_elf_generic_reloc
, /* special_function */
626 AARCH64_R_STR (ADR_PREL_LO21
), /* name */
627 FALSE
, /* partial_inplace */
628 0x1fffff, /* src_mask */
629 0x1fffff, /* dst_mask */
630 TRUE
), /* pcrel_offset */
632 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
633 HOWTO (AARCH64_R (ADR_PREL_PG_HI21
), /* type */
635 2, /* size (0 = byte, 1 = short, 2 = long) */
637 TRUE
, /* pc_relative */
639 complain_overflow_signed
, /* complain_on_overflow */
640 bfd_elf_generic_reloc
, /* special_function */
641 AARCH64_R_STR (ADR_PREL_PG_HI21
), /* name */
642 FALSE
, /* partial_inplace */
643 0x1fffff, /* src_mask */
644 0x1fffff, /* dst_mask */
645 TRUE
), /* pcrel_offset */
647 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
648 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC
), /* type */
650 2, /* size (0 = byte, 1 = short, 2 = long) */
652 TRUE
, /* pc_relative */
654 complain_overflow_dont
, /* complain_on_overflow */
655 bfd_elf_generic_reloc
, /* special_function */
656 AARCH64_R_STR (ADR_PREL_PG_HI21_NC
), /* name */
657 FALSE
, /* partial_inplace */
658 0x1fffff, /* src_mask */
659 0x1fffff, /* dst_mask */
660 TRUE
), /* pcrel_offset */
662 /* ADD: (S+A) & 0xfff [no overflow check] */
663 HOWTO (AARCH64_R (ADD_ABS_LO12_NC
), /* type */
665 2, /* size (0 = byte, 1 = short, 2 = long) */
667 FALSE
, /* pc_relative */
669 complain_overflow_dont
, /* complain_on_overflow */
670 bfd_elf_generic_reloc
, /* special_function */
671 AARCH64_R_STR (ADD_ABS_LO12_NC
), /* name */
672 FALSE
, /* partial_inplace */
673 0x3ffc00, /* src_mask */
674 0x3ffc00, /* dst_mask */
675 FALSE
), /* pcrel_offset */
677 /* LD/ST8: (S+A) & 0xfff */
678 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC
), /* type */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
682 FALSE
, /* pc_relative */
684 complain_overflow_dont
, /* complain_on_overflow */
685 bfd_elf_generic_reloc
, /* special_function */
686 AARCH64_R_STR (LDST8_ABS_LO12_NC
), /* name */
687 FALSE
, /* partial_inplace */
688 0xfff, /* src_mask */
689 0xfff, /* dst_mask */
690 FALSE
), /* pcrel_offset */
692 /* Relocations for control-flow instructions. */
694 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
695 HOWTO (AARCH64_R (TSTBR14
), /* type */
697 2, /* size (0 = byte, 1 = short, 2 = long) */
699 TRUE
, /* pc_relative */
701 complain_overflow_signed
, /* complain_on_overflow */
702 bfd_elf_generic_reloc
, /* special_function */
703 AARCH64_R_STR (TSTBR14
), /* name */
704 FALSE
, /* partial_inplace */
705 0x3fff, /* src_mask */
706 0x3fff, /* dst_mask */
707 TRUE
), /* pcrel_offset */
709 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
710 HOWTO (AARCH64_R (CONDBR19
), /* type */
712 2, /* size (0 = byte, 1 = short, 2 = long) */
714 TRUE
, /* pc_relative */
716 complain_overflow_signed
, /* complain_on_overflow */
717 bfd_elf_generic_reloc
, /* special_function */
718 AARCH64_R_STR (CONDBR19
), /* name */
719 FALSE
, /* partial_inplace */
720 0x7ffff, /* src_mask */
721 0x7ffff, /* dst_mask */
722 TRUE
), /* pcrel_offset */
724 /* B: ((S+A-P) >> 2) & 0x3ffffff */
725 HOWTO (AARCH64_R (JUMP26
), /* type */
727 2, /* size (0 = byte, 1 = short, 2 = long) */
729 TRUE
, /* pc_relative */
731 complain_overflow_signed
, /* complain_on_overflow */
732 bfd_elf_generic_reloc
, /* special_function */
733 AARCH64_R_STR (JUMP26
), /* name */
734 FALSE
, /* partial_inplace */
735 0x3ffffff, /* src_mask */
736 0x3ffffff, /* dst_mask */
737 TRUE
), /* pcrel_offset */
739 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
740 HOWTO (AARCH64_R (CALL26
), /* type */
742 2, /* size (0 = byte, 1 = short, 2 = long) */
744 TRUE
, /* pc_relative */
746 complain_overflow_signed
, /* complain_on_overflow */
747 bfd_elf_generic_reloc
, /* special_function */
748 AARCH64_R_STR (CALL26
), /* name */
749 FALSE
, /* partial_inplace */
750 0x3ffffff, /* src_mask */
751 0x3ffffff, /* dst_mask */
752 TRUE
), /* pcrel_offset */
754 /* LD/ST16: (S+A) & 0xffe */
755 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC
), /* type */
757 2, /* size (0 = byte, 1 = short, 2 = long) */
759 FALSE
, /* pc_relative */
761 complain_overflow_dont
, /* complain_on_overflow */
762 bfd_elf_generic_reloc
, /* special_function */
763 AARCH64_R_STR (LDST16_ABS_LO12_NC
), /* name */
764 FALSE
, /* partial_inplace */
765 0xffe, /* src_mask */
766 0xffe, /* dst_mask */
767 FALSE
), /* pcrel_offset */
769 /* LD/ST32: (S+A) & 0xffc */
770 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC
), /* type */
772 2, /* size (0 = byte, 1 = short, 2 = long) */
774 FALSE
, /* pc_relative */
776 complain_overflow_dont
, /* complain_on_overflow */
777 bfd_elf_generic_reloc
, /* special_function */
778 AARCH64_R_STR (LDST32_ABS_LO12_NC
), /* name */
779 FALSE
, /* partial_inplace */
780 0xffc, /* src_mask */
781 0xffc, /* dst_mask */
782 FALSE
), /* pcrel_offset */
784 /* LD/ST64: (S+A) & 0xff8 */
785 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC
), /* type */
787 2, /* size (0 = byte, 1 = short, 2 = long) */
789 FALSE
, /* pc_relative */
791 complain_overflow_dont
, /* complain_on_overflow */
792 bfd_elf_generic_reloc
, /* special_function */
793 AARCH64_R_STR (LDST64_ABS_LO12_NC
), /* name */
794 FALSE
, /* partial_inplace */
795 0xff8, /* src_mask */
796 0xff8, /* dst_mask */
797 FALSE
), /* pcrel_offset */
799 /* LD/ST128: (S+A) & 0xff0 */
800 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC
), /* type */
802 2, /* size (0 = byte, 1 = short, 2 = long) */
804 FALSE
, /* pc_relative */
806 complain_overflow_dont
, /* complain_on_overflow */
807 bfd_elf_generic_reloc
, /* special_function */
808 AARCH64_R_STR (LDST128_ABS_LO12_NC
), /* name */
809 FALSE
, /* partial_inplace */
810 0xff0, /* src_mask */
811 0xff0, /* dst_mask */
812 FALSE
), /* pcrel_offset */
814 /* Set a load-literal immediate field to bits
815 0x1FFFFC of G(S)-P */
816 HOWTO (AARCH64_R (GOT_LD_PREL19
), /* type */
818 2, /* size (0 = byte,1 = short,2 = long) */
820 TRUE
, /* pc_relative */
822 complain_overflow_signed
, /* complain_on_overflow */
823 bfd_elf_generic_reloc
, /* special_function */
824 AARCH64_R_STR (GOT_LD_PREL19
), /* name */
825 FALSE
, /* partial_inplace */
826 0xffffe0, /* src_mask */
827 0xffffe0, /* dst_mask */
828 TRUE
), /* pcrel_offset */
830 /* Get to the page for the GOT entry for the symbol
831 (G(S) - P) using an ADRP instruction. */
832 HOWTO (AARCH64_R (ADR_GOT_PAGE
), /* type */
834 2, /* size (0 = byte, 1 = short, 2 = long) */
836 TRUE
, /* pc_relative */
838 complain_overflow_dont
, /* complain_on_overflow */
839 bfd_elf_generic_reloc
, /* special_function */
840 AARCH64_R_STR (ADR_GOT_PAGE
), /* name */
841 FALSE
, /* partial_inplace */
842 0x1fffff, /* src_mask */
843 0x1fffff, /* dst_mask */
844 TRUE
), /* pcrel_offset */
846 /* LD64: GOT offset G(S) & 0xff8 */
847 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC
), /* type */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
851 FALSE
, /* pc_relative */
853 complain_overflow_dont
, /* complain_on_overflow */
854 bfd_elf_generic_reloc
, /* special_function */
855 AARCH64_R_STR (LD64_GOT_LO12_NC
), /* name */
856 FALSE
, /* partial_inplace */
857 0xff8, /* src_mask */
858 0xff8, /* dst_mask */
859 FALSE
), /* pcrel_offset */
861 /* LD32: GOT offset G(S) & 0xffc */
862 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC
), /* type */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
866 FALSE
, /* pc_relative */
868 complain_overflow_dont
, /* complain_on_overflow */
869 bfd_elf_generic_reloc
, /* special_function */
870 AARCH64_R_STR (LD32_GOT_LO12_NC
), /* name */
871 FALSE
, /* partial_inplace */
872 0xffc, /* src_mask */
873 0xffc, /* dst_mask */
874 FALSE
), /* pcrel_offset */
876 /* LD64: GOT offset for the symbol. */
877 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15
), /* type */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
881 FALSE
, /* pc_relative */
883 complain_overflow_unsigned
, /* complain_on_overflow */
884 bfd_elf_generic_reloc
, /* special_function */
885 AARCH64_R_STR (LD64_GOTOFF_LO15
), /* name */
886 FALSE
, /* partial_inplace */
887 0x7ff8, /* src_mask */
888 0x7ff8, /* dst_mask */
889 FALSE
), /* pcrel_offset */
891 /* LD32: GOT offset to the page address of GOT table.
892 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
893 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14
), /* type */
895 2, /* size (0 = byte, 1 = short, 2 = long) */
897 FALSE
, /* pc_relative */
899 complain_overflow_unsigned
, /* complain_on_overflow */
900 bfd_elf_generic_reloc
, /* special_function */
901 AARCH64_R_STR (LD32_GOTPAGE_LO14
), /* name */
902 FALSE
, /* partial_inplace */
903 0x5ffc, /* src_mask */
904 0x5ffc, /* dst_mask */
905 FALSE
), /* pcrel_offset */
907 /* LD64: GOT offset to the page address of GOT table.
908 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
909 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15
), /* type */
911 2, /* size (0 = byte, 1 = short, 2 = long) */
913 FALSE
, /* pc_relative */
915 complain_overflow_unsigned
, /* complain_on_overflow */
916 bfd_elf_generic_reloc
, /* special_function */
917 AARCH64_R_STR (LD64_GOTPAGE_LO15
), /* name */
918 FALSE
, /* partial_inplace */
919 0x7ff8, /* src_mask */
920 0x7ff8, /* dst_mask */
921 FALSE
), /* pcrel_offset */
923 /* Get to the page for the GOT entry for the symbol
924 (G(S) - P) using an ADRP instruction. */
925 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21
), /* type */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
929 TRUE
, /* pc_relative */
931 complain_overflow_dont
, /* complain_on_overflow */
932 bfd_elf_generic_reloc
, /* special_function */
933 AARCH64_R_STR (TLSGD_ADR_PAGE21
), /* name */
934 FALSE
, /* partial_inplace */
935 0x1fffff, /* src_mask */
936 0x1fffff, /* dst_mask */
937 TRUE
), /* pcrel_offset */
939 HOWTO (AARCH64_R (TLSGD_ADR_PREL21
), /* type */
941 2, /* size (0 = byte, 1 = short, 2 = long) */
943 TRUE
, /* pc_relative */
945 complain_overflow_dont
, /* complain_on_overflow */
946 bfd_elf_generic_reloc
, /* special_function */
947 AARCH64_R_STR (TLSGD_ADR_PREL21
), /* name */
948 FALSE
, /* partial_inplace */
949 0x1fffff, /* src_mask */
950 0x1fffff, /* dst_mask */
951 TRUE
), /* pcrel_offset */
953 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
954 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC
), /* type */
956 2, /* size (0 = byte, 1 = short, 2 = long) */
958 FALSE
, /* pc_relative */
960 complain_overflow_dont
, /* complain_on_overflow */
961 bfd_elf_generic_reloc
, /* special_function */
962 AARCH64_R_STR (TLSGD_ADD_LO12_NC
), /* name */
963 FALSE
, /* partial_inplace */
964 0xfff, /* src_mask */
965 0xfff, /* dst_mask */
966 FALSE
), /* pcrel_offset */
968 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1
), /* type */
970 2, /* size (0 = byte, 1 = short, 2 = long) */
972 FALSE
, /* pc_relative */
974 complain_overflow_dont
, /* complain_on_overflow */
975 bfd_elf_generic_reloc
, /* special_function */
976 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1
), /* name */
977 FALSE
, /* partial_inplace */
978 0xffff, /* src_mask */
979 0xffff, /* dst_mask */
980 FALSE
), /* pcrel_offset */
982 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC
), /* type */
984 2, /* size (0 = byte, 1 = short, 2 = long) */
986 FALSE
, /* pc_relative */
988 complain_overflow_dont
, /* complain_on_overflow */
989 bfd_elf_generic_reloc
, /* special_function */
990 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC
), /* name */
991 FALSE
, /* partial_inplace */
992 0xffff, /* src_mask */
993 0xffff, /* dst_mask */
994 FALSE
), /* pcrel_offset */
996 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21
), /* type */
998 2, /* size (0 = byte, 1 = short, 2 = long) */
1000 FALSE
, /* pc_relative */
1002 complain_overflow_dont
, /* complain_on_overflow */
1003 bfd_elf_generic_reloc
, /* special_function */
1004 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21
), /* name */
1005 FALSE
, /* partial_inplace */
1006 0x1fffff, /* src_mask */
1007 0x1fffff, /* dst_mask */
1008 FALSE
), /* pcrel_offset */
1010 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC
), /* type */
1012 2, /* size (0 = byte, 1 = short, 2 = long) */
1014 FALSE
, /* pc_relative */
1016 complain_overflow_dont
, /* complain_on_overflow */
1017 bfd_elf_generic_reloc
, /* special_function */
1018 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC
), /* name */
1019 FALSE
, /* partial_inplace */
1020 0xff8, /* src_mask */
1021 0xff8, /* dst_mask */
1022 FALSE
), /* pcrel_offset */
1024 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC
), /* type */
1026 2, /* size (0 = byte, 1 = short, 2 = long) */
1028 FALSE
, /* pc_relative */
1030 complain_overflow_dont
, /* complain_on_overflow */
1031 bfd_elf_generic_reloc
, /* special_function */
1032 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC
), /* name */
1033 FALSE
, /* partial_inplace */
1034 0xffc, /* src_mask */
1035 0xffc, /* dst_mask */
1036 FALSE
), /* pcrel_offset */
1038 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19
), /* type */
1040 2, /* size (0 = byte, 1 = short, 2 = long) */
1042 FALSE
, /* pc_relative */
1044 complain_overflow_dont
, /* complain_on_overflow */
1045 bfd_elf_generic_reloc
, /* special_function */
1046 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19
), /* name */
1047 FALSE
, /* partial_inplace */
1048 0x1ffffc, /* src_mask */
1049 0x1ffffc, /* dst_mask */
1050 FALSE
), /* pcrel_offset */
1052 /* ADD: bit[23:12] of byte offset to module TLS base address. */
1053 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12
), /* type */
1054 12, /* rightshift */
1055 2, /* size (0 = byte, 1 = short, 2 = long) */
1057 FALSE
, /* pc_relative */
1059 complain_overflow_unsigned
, /* complain_on_overflow */
1060 bfd_elf_generic_reloc
, /* special_function */
1061 AARCH64_R_STR (TLSLD_ADD_DTPREL_HI12
), /* name */
1062 FALSE
, /* partial_inplace */
1063 0xfff, /* src_mask */
1064 0xfff, /* dst_mask */
1065 FALSE
), /* pcrel_offset */
1067 /* Unsigned 12 bit byte offset to module TLS base address. */
1068 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12
), /* type */
1070 2, /* size (0 = byte, 1 = short, 2 = long) */
1072 FALSE
, /* pc_relative */
1074 complain_overflow_unsigned
, /* complain_on_overflow */
1075 bfd_elf_generic_reloc
, /* special_function */
1076 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12
), /* name */
1077 FALSE
, /* partial_inplace */
1078 0xfff, /* src_mask */
1079 0xfff, /* dst_mask */
1080 FALSE
), /* pcrel_offset */
1082 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1083 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC
), /* type */
1085 2, /* size (0 = byte, 1 = short, 2 = long) */
1087 FALSE
, /* pc_relative */
1089 complain_overflow_dont
, /* complain_on_overflow */
1090 bfd_elf_generic_reloc
, /* special_function */
1091 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC
), /* name */
1092 FALSE
, /* partial_inplace */
1093 0xfff, /* src_mask */
1094 0xfff, /* dst_mask */
1095 FALSE
), /* pcrel_offset */
1097 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1098 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC
), /* type */
1100 2, /* size (0 = byte, 1 = short, 2 = long) */
1102 FALSE
, /* pc_relative */
1104 complain_overflow_dont
, /* complain_on_overflow */
1105 bfd_elf_generic_reloc
, /* special_function */
1106 AARCH64_R_STR (TLSLD_ADD_LO12_NC
), /* name */
1107 FALSE
, /* partial_inplace */
1108 0xfff, /* src_mask */
1109 0xfff, /* dst_mask */
1110 FALSE
), /* pcrel_offset */
1112 /* Get to the page for the GOT entry for the symbol
1113 (G(S) - P) using an ADRP instruction. */
1114 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21
), /* type */
1115 12, /* rightshift */
1116 2, /* size (0 = byte, 1 = short, 2 = long) */
1118 TRUE
, /* pc_relative */
1120 complain_overflow_signed
, /* complain_on_overflow */
1121 bfd_elf_generic_reloc
, /* special_function */
1122 AARCH64_R_STR (TLSLD_ADR_PAGE21
), /* name */
1123 FALSE
, /* partial_inplace */
1124 0x1fffff, /* src_mask */
1125 0x1fffff, /* dst_mask */
1126 TRUE
), /* pcrel_offset */
1128 HOWTO (AARCH64_R (TLSLD_ADR_PREL21
), /* type */
1130 2, /* size (0 = byte, 1 = short, 2 = long) */
1132 TRUE
, /* pc_relative */
1134 complain_overflow_signed
, /* complain_on_overflow */
1135 bfd_elf_generic_reloc
, /* special_function */
1136 AARCH64_R_STR (TLSLD_ADR_PREL21
), /* name */
1137 FALSE
, /* partial_inplace */
1138 0x1fffff, /* src_mask */
1139 0x1fffff, /* dst_mask */
1140 TRUE
), /* pcrel_offset */
1142 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1143 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12
), /* type */
1145 2, /* size (0 = byte, 1 = short, 2 = long) */
1147 FALSE
, /* pc_relative */
1149 complain_overflow_unsigned
, /* complain_on_overflow */
1150 bfd_elf_generic_reloc
, /* special_function */
1151 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12
), /* name */
1152 FALSE
, /* partial_inplace */
1153 0x1ffc00, /* src_mask */
1154 0x1ffc00, /* dst_mask */
1155 FALSE
), /* pcrel_offset */
1157 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, but no overflow check. */
1158 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12_NC
), /* type */
1160 2, /* size (0 = byte, 1 = short, 2 = long) */
1162 FALSE
, /* pc_relative */
1164 complain_overflow_dont
, /* complain_on_overflow */
1165 bfd_elf_generic_reloc
, /* special_function */
1166 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12_NC
), /* name */
1167 FALSE
, /* partial_inplace */
1168 0x1ffc00, /* src_mask */
1169 0x1ffc00, /* dst_mask */
1170 FALSE
), /* pcrel_offset */
1172 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1173 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12
), /* type */
1175 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 FALSE
, /* pc_relative */
1179 complain_overflow_unsigned
, /* complain_on_overflow */
1180 bfd_elf_generic_reloc
, /* special_function */
1181 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12
), /* name */
1182 FALSE
, /* partial_inplace */
1183 0x3ffc00, /* src_mask */
1184 0x3ffc00, /* dst_mask */
1185 FALSE
), /* pcrel_offset */
1187 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no overflow check. */
1188 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12_NC
), /* type */
1190 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 FALSE
, /* pc_relative */
1194 complain_overflow_dont
, /* complain_on_overflow */
1195 bfd_elf_generic_reloc
, /* special_function */
1196 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12_NC
), /* name */
1197 FALSE
, /* partial_inplace */
1198 0xffc00, /* src_mask */
1199 0xffc00, /* dst_mask */
1200 FALSE
), /* pcrel_offset */
1202 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1203 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12
), /* type */
1205 2, /* size (0 = byte, 1 = short, 2 = long) */
1207 FALSE
, /* pc_relative */
1209 complain_overflow_unsigned
, /* complain_on_overflow */
1210 bfd_elf_generic_reloc
, /* special_function */
1211 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12
), /* name */
1212 FALSE
, /* partial_inplace */
1213 0x3ffc00, /* src_mask */
1214 0x3ffc00, /* dst_mask */
1215 FALSE
), /* pcrel_offset */
1217 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, but no overflow check. */
1218 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12_NC
), /* type */
1220 2, /* size (0 = byte, 1 = short, 2 = long) */
1222 FALSE
, /* pc_relative */
1224 complain_overflow_dont
, /* complain_on_overflow */
1225 bfd_elf_generic_reloc
, /* special_function */
1226 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12_NC
), /* name */
1227 FALSE
, /* partial_inplace */
1228 0x7fc00, /* src_mask */
1229 0x7fc00, /* dst_mask */
1230 FALSE
), /* pcrel_offset */
1232 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1233 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12
), /* type */
1235 2, /* size (0 = byte, 1 = short, 2 = long) */
1237 FALSE
, /* pc_relative */
1239 complain_overflow_unsigned
, /* complain_on_overflow */
1240 bfd_elf_generic_reloc
, /* special_function */
1241 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12
), /* name */
1242 FALSE
, /* partial_inplace */
1243 0x3ffc00, /* src_mask */
1244 0x3ffc00, /* dst_mask */
1245 FALSE
), /* pcrel_offset */
1247 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, but no overflow check. */
1248 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12_NC
), /* type */
1250 2, /* size (0 = byte, 1 = short, 2 = long) */
1252 FALSE
, /* pc_relative */
1254 complain_overflow_dont
, /* complain_on_overflow */
1255 bfd_elf_generic_reloc
, /* special_function */
1256 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12_NC
), /* name */
1257 FALSE
, /* partial_inplace */
1258 0x3ffc00, /* src_mask */
1259 0x3ffc00, /* dst_mask */
1260 FALSE
), /* pcrel_offset */
1262 /* MOVZ: bit[15:0] of byte offset to module TLS base address. */
1263 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0
), /* type */
1265 2, /* size (0 = byte, 1 = short, 2 = long) */
1267 FALSE
, /* pc_relative */
1269 complain_overflow_unsigned
, /* complain_on_overflow */
1270 bfd_elf_generic_reloc
, /* special_function */
1271 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0
), /* name */
1272 FALSE
, /* partial_inplace */
1273 0xffff, /* src_mask */
1274 0xffff, /* dst_mask */
1275 FALSE
), /* pcrel_offset */
1277 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */
1278 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0_NC
), /* type */
1280 2, /* size (0 = byte, 1 = short, 2 = long) */
1282 FALSE
, /* pc_relative */
1284 complain_overflow_dont
, /* complain_on_overflow */
1285 bfd_elf_generic_reloc
, /* special_function */
1286 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0_NC
), /* name */
1287 FALSE
, /* partial_inplace */
1288 0xffff, /* src_mask */
1289 0xffff, /* dst_mask */
1290 FALSE
), /* pcrel_offset */
1292 /* MOVZ: bit[31:16] of byte offset to module TLS base address. */
1293 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G1
), /* type */
1294 16, /* rightshift */
1295 2, /* size (0 = byte, 1 = short, 2 = long) */
1297 FALSE
, /* pc_relative */
1299 complain_overflow_unsigned
, /* complain_on_overflow */
1300 bfd_elf_generic_reloc
, /* special_function */
1301 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1
), /* name */
1302 FALSE
, /* partial_inplace */
1303 0xffff, /* src_mask */
1304 0xffff, /* dst_mask */
1305 FALSE
), /* pcrel_offset */
1307 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */
1308 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G1_NC
), /* type */
1309 16, /* rightshift */
1310 2, /* size (0 = byte, 1 = short, 2 = long) */
1312 FALSE
, /* pc_relative */
1314 complain_overflow_dont
, /* complain_on_overflow */
1315 bfd_elf_generic_reloc
, /* special_function */
1316 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1_NC
), /* name */
1317 FALSE
, /* partial_inplace */
1318 0xffff, /* src_mask */
1319 0xffff, /* dst_mask */
1320 FALSE
), /* pcrel_offset */
1322 /* MOVZ: bit[47:32] of byte offset to module TLS base address. */
1323 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G2
), /* type */
1324 32, /* rightshift */
1325 2, /* size (0 = byte, 1 = short, 2 = long) */
1327 FALSE
, /* pc_relative */
1329 complain_overflow_unsigned
, /* complain_on_overflow */
1330 bfd_elf_generic_reloc
, /* special_function */
1331 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G2
), /* name */
1332 FALSE
, /* partial_inplace */
1333 0xffff, /* src_mask */
1334 0xffff, /* dst_mask */
1335 FALSE
), /* pcrel_offset */
1337 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2
), /* type */
1338 32, /* rightshift */
1339 2, /* size (0 = byte, 1 = short, 2 = long) */
1341 FALSE
, /* pc_relative */
1343 complain_overflow_unsigned
, /* complain_on_overflow */
1344 bfd_elf_generic_reloc
, /* special_function */
1345 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2
), /* name */
1346 FALSE
, /* partial_inplace */
1347 0xffff, /* src_mask */
1348 0xffff, /* dst_mask */
1349 FALSE
), /* pcrel_offset */
1351 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1
), /* type */
1352 16, /* rightshift */
1353 2, /* size (0 = byte, 1 = short, 2 = long) */
1355 FALSE
, /* pc_relative */
1357 complain_overflow_dont
, /* complain_on_overflow */
1358 bfd_elf_generic_reloc
, /* special_function */
1359 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1
), /* name */
1360 FALSE
, /* partial_inplace */
1361 0xffff, /* src_mask */
1362 0xffff, /* dst_mask */
1363 FALSE
), /* pcrel_offset */
1365 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC
), /* type */
1366 16, /* rightshift */
1367 2, /* 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 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC
), /* name */
1374 FALSE
, /* partial_inplace */
1375 0xffff, /* src_mask */
1376 0xffff, /* dst_mask */
1377 FALSE
), /* pcrel_offset */
1379 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0
), /* type */
1381 2, /* size (0 = byte, 1 = short, 2 = long) */
1383 FALSE
, /* pc_relative */
1385 complain_overflow_dont
, /* complain_on_overflow */
1386 bfd_elf_generic_reloc
, /* special_function */
1387 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0
), /* name */
1388 FALSE
, /* partial_inplace */
1389 0xffff, /* src_mask */
1390 0xffff, /* dst_mask */
1391 FALSE
), /* pcrel_offset */
1393 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
), /* type */
1395 2, /* size (0 = byte, 1 = short, 2 = long) */
1397 FALSE
, /* pc_relative */
1399 complain_overflow_dont
, /* complain_on_overflow */
1400 bfd_elf_generic_reloc
, /* special_function */
1401 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC
), /* name */
1402 FALSE
, /* partial_inplace */
1403 0xffff, /* src_mask */
1404 0xffff, /* dst_mask */
1405 FALSE
), /* pcrel_offset */
1407 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12
), /* type */
1408 12, /* rightshift */
1409 2, /* size (0 = byte, 1 = short, 2 = long) */
1411 FALSE
, /* pc_relative */
1413 complain_overflow_unsigned
, /* complain_on_overflow */
1414 bfd_elf_generic_reloc
, /* special_function */
1415 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12
), /* name */
1416 FALSE
, /* partial_inplace */
1417 0xfff, /* src_mask */
1418 0xfff, /* dst_mask */
1419 FALSE
), /* pcrel_offset */
1421 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12
), /* type */
1423 2, /* size (0 = byte, 1 = short, 2 = long) */
1425 FALSE
, /* pc_relative */
1427 complain_overflow_unsigned
, /* complain_on_overflow */
1428 bfd_elf_generic_reloc
, /* special_function */
1429 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12
), /* name */
1430 FALSE
, /* partial_inplace */
1431 0xfff, /* src_mask */
1432 0xfff, /* dst_mask */
1433 FALSE
), /* pcrel_offset */
1435 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
), /* type */
1437 2, /* size (0 = byte, 1 = short, 2 = long) */
1439 FALSE
, /* pc_relative */
1441 complain_overflow_dont
, /* complain_on_overflow */
1442 bfd_elf_generic_reloc
, /* special_function */
1443 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC
), /* name */
1444 FALSE
, /* partial_inplace */
1445 0xfff, /* src_mask */
1446 0xfff, /* dst_mask */
1447 FALSE
), /* pcrel_offset */
1449 HOWTO (AARCH64_R (TLSDESC_LD_PREL19
), /* type */
1451 2, /* size (0 = byte, 1 = short, 2 = long) */
1453 TRUE
, /* pc_relative */
1455 complain_overflow_dont
, /* complain_on_overflow */
1456 bfd_elf_generic_reloc
, /* special_function */
1457 AARCH64_R_STR (TLSDESC_LD_PREL19
), /* name */
1458 FALSE
, /* partial_inplace */
1459 0x0ffffe0, /* src_mask */
1460 0x0ffffe0, /* dst_mask */
1461 TRUE
), /* pcrel_offset */
1463 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21
), /* type */
1465 2, /* size (0 = byte, 1 = short, 2 = long) */
1467 TRUE
, /* pc_relative */
1469 complain_overflow_dont
, /* complain_on_overflow */
1470 bfd_elf_generic_reloc
, /* special_function */
1471 AARCH64_R_STR (TLSDESC_ADR_PREL21
), /* name */
1472 FALSE
, /* partial_inplace */
1473 0x1fffff, /* src_mask */
1474 0x1fffff, /* dst_mask */
1475 TRUE
), /* pcrel_offset */
1477 /* Get to the page for the GOT entry for the symbol
1478 (G(S) - P) using an ADRP instruction. */
1479 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21
), /* type */
1480 12, /* rightshift */
1481 2, /* size (0 = byte, 1 = short, 2 = long) */
1483 TRUE
, /* pc_relative */
1485 complain_overflow_dont
, /* complain_on_overflow */
1486 bfd_elf_generic_reloc
, /* special_function */
1487 AARCH64_R_STR (TLSDESC_ADR_PAGE21
), /* name */
1488 FALSE
, /* partial_inplace */
1489 0x1fffff, /* src_mask */
1490 0x1fffff, /* dst_mask */
1491 TRUE
), /* pcrel_offset */
1493 /* LD64: GOT offset G(S) & 0xff8. */
1494 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC
), /* type */
1496 2, /* size (0 = byte, 1 = short, 2 = long) */
1498 FALSE
, /* pc_relative */
1500 complain_overflow_dont
, /* complain_on_overflow */
1501 bfd_elf_generic_reloc
, /* special_function */
1502 AARCH64_R_STR (TLSDESC_LD64_LO12_NC
), /* name */
1503 FALSE
, /* partial_inplace */
1504 0xff8, /* src_mask */
1505 0xff8, /* dst_mask */
1506 FALSE
), /* pcrel_offset */
1508 /* LD32: GOT offset G(S) & 0xffc. */
1509 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC
), /* type */
1511 2, /* size (0 = byte, 1 = short, 2 = long) */
1513 FALSE
, /* pc_relative */
1515 complain_overflow_dont
, /* complain_on_overflow */
1516 bfd_elf_generic_reloc
, /* special_function */
1517 AARCH64_R_STR (TLSDESC_LD32_LO12_NC
), /* name */
1518 FALSE
, /* partial_inplace */
1519 0xffc, /* src_mask */
1520 0xffc, /* dst_mask */
1521 FALSE
), /* pcrel_offset */
1523 /* ADD: GOT offset G(S) & 0xfff. */
1524 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC
), /* type */
1526 2, /* size (0 = byte, 1 = short, 2 = long) */
1528 FALSE
, /* pc_relative */
1530 complain_overflow_dont
, /* complain_on_overflow */
1531 bfd_elf_generic_reloc
, /* special_function */
1532 AARCH64_R_STR (TLSDESC_ADD_LO12_NC
), /* name */
1533 FALSE
, /* partial_inplace */
1534 0xfff, /* src_mask */
1535 0xfff, /* dst_mask */
1536 FALSE
), /* pcrel_offset */
1538 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1
), /* type */
1539 16, /* rightshift */
1540 2, /* size (0 = byte, 1 = short, 2 = long) */
1542 FALSE
, /* pc_relative */
1544 complain_overflow_dont
, /* complain_on_overflow */
1545 bfd_elf_generic_reloc
, /* special_function */
1546 AARCH64_R_STR (TLSDESC_OFF_G1
), /* name */
1547 FALSE
, /* partial_inplace */
1548 0xffff, /* src_mask */
1549 0xffff, /* dst_mask */
1550 FALSE
), /* pcrel_offset */
1552 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC
), /* type */
1554 2, /* size (0 = byte, 1 = short, 2 = long) */
1556 FALSE
, /* pc_relative */
1558 complain_overflow_dont
, /* complain_on_overflow */
1559 bfd_elf_generic_reloc
, /* special_function */
1560 AARCH64_R_STR (TLSDESC_OFF_G0_NC
), /* name */
1561 FALSE
, /* partial_inplace */
1562 0xffff, /* src_mask */
1563 0xffff, /* dst_mask */
1564 FALSE
), /* pcrel_offset */
1566 HOWTO64 (AARCH64_R (TLSDESC_LDR
), /* type */
1568 2, /* size (0 = byte, 1 = short, 2 = long) */
1570 FALSE
, /* pc_relative */
1572 complain_overflow_dont
, /* complain_on_overflow */
1573 bfd_elf_generic_reloc
, /* special_function */
1574 AARCH64_R_STR (TLSDESC_LDR
), /* name */
1575 FALSE
, /* partial_inplace */
1578 FALSE
), /* pcrel_offset */
1580 HOWTO64 (AARCH64_R (TLSDESC_ADD
), /* type */
1582 2, /* size (0 = byte, 1 = short, 2 = long) */
1584 FALSE
, /* pc_relative */
1586 complain_overflow_dont
, /* complain_on_overflow */
1587 bfd_elf_generic_reloc
, /* special_function */
1588 AARCH64_R_STR (TLSDESC_ADD
), /* name */
1589 FALSE
, /* partial_inplace */
1592 FALSE
), /* pcrel_offset */
1594 HOWTO (AARCH64_R (TLSDESC_CALL
), /* type */
1596 2, /* size (0 = byte, 1 = short, 2 = long) */
1598 FALSE
, /* pc_relative */
1600 complain_overflow_dont
, /* complain_on_overflow */
1601 bfd_elf_generic_reloc
, /* special_function */
1602 AARCH64_R_STR (TLSDESC_CALL
), /* name */
1603 FALSE
, /* partial_inplace */
1606 FALSE
), /* pcrel_offset */
1608 HOWTO (AARCH64_R (COPY
), /* type */
1610 2, /* size (0 = byte, 1 = short, 2 = long) */
1612 FALSE
, /* pc_relative */
1614 complain_overflow_bitfield
, /* complain_on_overflow */
1615 bfd_elf_generic_reloc
, /* special_function */
1616 AARCH64_R_STR (COPY
), /* name */
1617 TRUE
, /* partial_inplace */
1618 0xffffffff, /* src_mask */
1619 0xffffffff, /* dst_mask */
1620 FALSE
), /* pcrel_offset */
1622 HOWTO (AARCH64_R (GLOB_DAT
), /* type */
1624 2, /* size (0 = byte, 1 = short, 2 = long) */
1626 FALSE
, /* pc_relative */
1628 complain_overflow_bitfield
, /* complain_on_overflow */
1629 bfd_elf_generic_reloc
, /* special_function */
1630 AARCH64_R_STR (GLOB_DAT
), /* name */
1631 TRUE
, /* partial_inplace */
1632 0xffffffff, /* src_mask */
1633 0xffffffff, /* dst_mask */
1634 FALSE
), /* pcrel_offset */
1636 HOWTO (AARCH64_R (JUMP_SLOT
), /* type */
1638 2, /* size (0 = byte, 1 = short, 2 = long) */
1640 FALSE
, /* pc_relative */
1642 complain_overflow_bitfield
, /* complain_on_overflow */
1643 bfd_elf_generic_reloc
, /* special_function */
1644 AARCH64_R_STR (JUMP_SLOT
), /* name */
1645 TRUE
, /* partial_inplace */
1646 0xffffffff, /* src_mask */
1647 0xffffffff, /* dst_mask */
1648 FALSE
), /* pcrel_offset */
1650 HOWTO (AARCH64_R (RELATIVE
), /* type */
1652 2, /* size (0 = byte, 1 = short, 2 = long) */
1654 FALSE
, /* pc_relative */
1656 complain_overflow_bitfield
, /* complain_on_overflow */
1657 bfd_elf_generic_reloc
, /* special_function */
1658 AARCH64_R_STR (RELATIVE
), /* name */
1659 TRUE
, /* partial_inplace */
1660 ALL_ONES
, /* src_mask */
1661 ALL_ONES
, /* dst_mask */
1662 FALSE
), /* pcrel_offset */
1664 HOWTO (AARCH64_R (TLS_DTPMOD
), /* type */
1666 2, /* size (0 = byte, 1 = short, 2 = long) */
1668 FALSE
, /* pc_relative */
1670 complain_overflow_dont
, /* complain_on_overflow */
1671 bfd_elf_generic_reloc
, /* special_function */
1673 AARCH64_R_STR (TLS_DTPMOD64
), /* name */
1675 AARCH64_R_STR (TLS_DTPMOD
), /* name */
1677 FALSE
, /* partial_inplace */
1679 ALL_ONES
, /* dst_mask */
1680 FALSE
), /* pc_reloffset */
1682 HOWTO (AARCH64_R (TLS_DTPREL
), /* type */
1684 2, /* size (0 = byte, 1 = short, 2 = long) */
1686 FALSE
, /* pc_relative */
1688 complain_overflow_dont
, /* complain_on_overflow */
1689 bfd_elf_generic_reloc
, /* special_function */
1691 AARCH64_R_STR (TLS_DTPREL64
), /* name */
1693 AARCH64_R_STR (TLS_DTPREL
), /* name */
1695 FALSE
, /* partial_inplace */
1697 ALL_ONES
, /* dst_mask */
1698 FALSE
), /* pcrel_offset */
1700 HOWTO (AARCH64_R (TLS_TPREL
), /* type */
1702 2, /* size (0 = byte, 1 = short, 2 = long) */
1704 FALSE
, /* pc_relative */
1706 complain_overflow_dont
, /* complain_on_overflow */
1707 bfd_elf_generic_reloc
, /* special_function */
1709 AARCH64_R_STR (TLS_TPREL64
), /* name */
1711 AARCH64_R_STR (TLS_TPREL
), /* name */
1713 FALSE
, /* partial_inplace */
1715 ALL_ONES
, /* dst_mask */
1716 FALSE
), /* pcrel_offset */
1718 HOWTO (AARCH64_R (TLSDESC
), /* type */
1720 2, /* size (0 = byte, 1 = short, 2 = long) */
1722 FALSE
, /* pc_relative */
1724 complain_overflow_dont
, /* complain_on_overflow */
1725 bfd_elf_generic_reloc
, /* special_function */
1726 AARCH64_R_STR (TLSDESC
), /* name */
1727 FALSE
, /* partial_inplace */
1729 ALL_ONES
, /* dst_mask */
1730 FALSE
), /* pcrel_offset */
1732 HOWTO (AARCH64_R (IRELATIVE
), /* type */
1734 2, /* size (0 = byte, 1 = short, 2 = long) */
1736 FALSE
, /* pc_relative */
1738 complain_overflow_bitfield
, /* complain_on_overflow */
1739 bfd_elf_generic_reloc
, /* special_function */
1740 AARCH64_R_STR (IRELATIVE
), /* name */
1741 FALSE
, /* partial_inplace */
1743 ALL_ONES
, /* dst_mask */
1744 FALSE
), /* pcrel_offset */
1749 static reloc_howto_type elfNN_aarch64_howto_none
=
1750 HOWTO (R_AARCH64_NONE
, /* type */
1752 3, /* size (0 = byte, 1 = short, 2 = long) */
1754 FALSE
, /* pc_relative */
1756 complain_overflow_dont
,/* complain_on_overflow */
1757 bfd_elf_generic_reloc
, /* special_function */
1758 "R_AARCH64_NONE", /* name */
1759 FALSE
, /* partial_inplace */
1762 FALSE
); /* pcrel_offset */
1764 /* Given HOWTO, return the bfd internal relocation enumerator. */
1766 static bfd_reloc_code_real_type
1767 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type
*howto
)
1770 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table
);
1771 const ptrdiff_t offset
1772 = howto
- elfNN_aarch64_howto_table
;
1774 if (offset
> 0 && offset
< size
- 1)
1775 return BFD_RELOC_AARCH64_RELOC_START
+ offset
;
1777 if (howto
== &elfNN_aarch64_howto_none
)
1778 return BFD_RELOC_AARCH64_NONE
;
1780 return BFD_RELOC_AARCH64_RELOC_START
;
1783 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1785 static bfd_reloc_code_real_type
1786 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type
)
1788 static bfd_boolean initialized_p
= FALSE
;
1789 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1790 static unsigned int offsets
[R_AARCH64_end
];
1792 if (initialized_p
== FALSE
)
1796 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1797 if (elfNN_aarch64_howto_table
[i
].type
!= 0)
1798 offsets
[elfNN_aarch64_howto_table
[i
].type
] = i
;
1800 initialized_p
= TRUE
;
1803 if (r_type
== R_AARCH64_NONE
|| r_type
== R_AARCH64_NULL
)
1804 return BFD_RELOC_AARCH64_NONE
;
1806 /* PR 17512: file: b371e70a. */
1807 if (r_type
>= R_AARCH64_end
)
1809 _bfd_error_handler (_("Invalid AArch64 reloc number: %d"), r_type
);
1810 bfd_set_error (bfd_error_bad_value
);
1811 return BFD_RELOC_AARCH64_NONE
;
1814 return BFD_RELOC_AARCH64_RELOC_START
+ offsets
[r_type
];
1817 struct elf_aarch64_reloc_map
1819 bfd_reloc_code_real_type from
;
1820 bfd_reloc_code_real_type to
;
1823 /* Map bfd generic reloc to AArch64-specific reloc. */
1824 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map
[] =
1826 {BFD_RELOC_NONE
, BFD_RELOC_AARCH64_NONE
},
1828 /* Basic data relocations. */
1829 {BFD_RELOC_CTOR
, BFD_RELOC_AARCH64_NN
},
1830 {BFD_RELOC_64
, BFD_RELOC_AARCH64_64
},
1831 {BFD_RELOC_32
, BFD_RELOC_AARCH64_32
},
1832 {BFD_RELOC_16
, BFD_RELOC_AARCH64_16
},
1833 {BFD_RELOC_64_PCREL
, BFD_RELOC_AARCH64_64_PCREL
},
1834 {BFD_RELOC_32_PCREL
, BFD_RELOC_AARCH64_32_PCREL
},
1835 {BFD_RELOC_16_PCREL
, BFD_RELOC_AARCH64_16_PCREL
},
1838 /* Given the bfd internal relocation enumerator in CODE, return the
1839 corresponding howto entry. */
1841 static reloc_howto_type
*
1842 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code
)
1846 /* Convert bfd generic reloc to AArch64-specific reloc. */
1847 if (code
< BFD_RELOC_AARCH64_RELOC_START
1848 || code
> BFD_RELOC_AARCH64_RELOC_END
)
1849 for (i
= 0; i
< ARRAY_SIZE (elf_aarch64_reloc_map
); i
++)
1850 if (elf_aarch64_reloc_map
[i
].from
== code
)
1852 code
= elf_aarch64_reloc_map
[i
].to
;
1856 if (code
> BFD_RELOC_AARCH64_RELOC_START
1857 && code
< BFD_RELOC_AARCH64_RELOC_END
)
1858 if (elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
].type
)
1859 return &elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
];
1861 if (code
== BFD_RELOC_AARCH64_NONE
)
1862 return &elfNN_aarch64_howto_none
;
1867 static reloc_howto_type
*
1868 elfNN_aarch64_howto_from_type (unsigned int r_type
)
1870 bfd_reloc_code_real_type val
;
1871 reloc_howto_type
*howto
;
1876 bfd_set_error (bfd_error_bad_value
);
1881 if (r_type
== R_AARCH64_NONE
)
1882 return &elfNN_aarch64_howto_none
;
1884 val
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
1885 howto
= elfNN_aarch64_howto_from_bfd_reloc (val
);
1890 bfd_set_error (bfd_error_bad_value
);
1895 elfNN_aarch64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*bfd_reloc
,
1896 Elf_Internal_Rela
*elf_reloc
)
1898 unsigned int r_type
;
1900 r_type
= ELFNN_R_TYPE (elf_reloc
->r_info
);
1901 bfd_reloc
->howto
= elfNN_aarch64_howto_from_type (r_type
);
1904 static reloc_howto_type
*
1905 elfNN_aarch64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1906 bfd_reloc_code_real_type code
)
1908 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (code
);
1913 bfd_set_error (bfd_error_bad_value
);
1917 static reloc_howto_type
*
1918 elfNN_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1923 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1924 if (elfNN_aarch64_howto_table
[i
].name
!= NULL
1925 && strcasecmp (elfNN_aarch64_howto_table
[i
].name
, r_name
) == 0)
1926 return &elfNN_aarch64_howto_table
[i
];
1931 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
1932 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1933 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
1934 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1936 /* The linker script knows the section names for placement.
1937 The entry_names are used to do simple name mangling on the stubs.
1938 Given a function name, and its type, the stub can be found. The
1939 name can be changed. The only requirement is the %s be present. */
1940 #define STUB_ENTRY_NAME "__%s_veneer"
1942 /* The name of the dynamic interpreter. This is put in the .interp
1944 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1946 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1947 (((1 << 25) - 1) << 2)
1948 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1951 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1952 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1955 aarch64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
1957 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
1958 return offset
<= AARCH64_MAX_ADRP_IMM
&& offset
>= AARCH64_MIN_ADRP_IMM
;
1962 aarch64_valid_branch_p (bfd_vma value
, bfd_vma place
)
1964 bfd_signed_vma offset
= (bfd_signed_vma
) (value
- place
);
1965 return (offset
<= AARCH64_MAX_FWD_BRANCH_OFFSET
1966 && offset
>= AARCH64_MAX_BWD_BRANCH_OFFSET
);
1969 static const uint32_t aarch64_adrp_branch_stub
[] =
1971 0x90000010, /* adrp ip0, X */
1972 /* R_AARCH64_ADR_HI21_PCREL(X) */
1973 0x91000210, /* add ip0, ip0, :lo12:X */
1974 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
1975 0xd61f0200, /* br ip0 */
1978 static const uint32_t aarch64_long_branch_stub
[] =
1981 0x58000090, /* ldr ip0, 1f */
1983 0x18000090, /* ldr wip0, 1f */
1985 0x10000011, /* adr ip1, #0 */
1986 0x8b110210, /* add ip0, ip0, ip1 */
1987 0xd61f0200, /* br ip0 */
1988 0x00000000, /* 1: .xword or .word
1989 R_AARCH64_PRELNN(X) + 12
1994 static const uint32_t aarch64_erratum_835769_stub
[] =
1996 0x00000000, /* Placeholder for multiply accumulate. */
1997 0x14000000, /* b <label> */
2000 static const uint32_t aarch64_erratum_843419_stub
[] =
2002 0x00000000, /* Placeholder for LDR instruction. */
2003 0x14000000, /* b <label> */
2006 /* Section name for stubs is the associated section name plus this
2008 #define STUB_SUFFIX ".stub"
2010 enum elf_aarch64_stub_type
2013 aarch64_stub_adrp_branch
,
2014 aarch64_stub_long_branch
,
2015 aarch64_stub_erratum_835769_veneer
,
2016 aarch64_stub_erratum_843419_veneer
,
2019 struct elf_aarch64_stub_hash_entry
2021 /* Base hash table entry structure. */
2022 struct bfd_hash_entry root
;
2024 /* The stub section. */
2027 /* Offset within stub_sec of the beginning of this stub. */
2028 bfd_vma stub_offset
;
2030 /* Given the symbol's value and its section we can determine its final
2031 value when building the stubs (so the stub knows where to jump). */
2032 bfd_vma target_value
;
2033 asection
*target_section
;
2035 enum elf_aarch64_stub_type stub_type
;
2037 /* The symbol table entry, if any, that this was derived from. */
2038 struct elf_aarch64_link_hash_entry
*h
;
2040 /* Destination symbol type */
2041 unsigned char st_type
;
2043 /* Where this stub is being called from, or, in the case of combined
2044 stub sections, the first input section in the group. */
2047 /* The name for the local symbol at the start of this stub. The
2048 stub name in the hash table has to be unique; this does not, so
2049 it can be friendlier. */
2052 /* The instruction which caused this stub to be generated (only valid for
2053 erratum 835769 workaround stubs at present). */
2054 uint32_t veneered_insn
;
2056 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
2057 bfd_vma adrp_offset
;
2060 /* Used to build a map of a section. This is required for mixed-endian
2063 typedef struct elf_elf_section_map
2068 elf_aarch64_section_map
;
2071 typedef struct _aarch64_elf_section_data
2073 struct bfd_elf_section_data elf
;
2074 unsigned int mapcount
;
2075 unsigned int mapsize
;
2076 elf_aarch64_section_map
*map
;
2078 _aarch64_elf_section_data
;
2080 #define elf_aarch64_section_data(sec) \
2081 ((_aarch64_elf_section_data *) elf_section_data (sec))
2083 /* The size of the thread control block which is defined to be two pointers. */
2084 #define TCB_SIZE (ARCH_SIZE/8)*2
2086 struct elf_aarch64_local_symbol
2088 unsigned int got_type
;
2089 bfd_signed_vma got_refcount
;
2092 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2093 offset is from the end of the jump table and reserved entries
2096 The magic value (bfd_vma) -1 indicates that an offset has not be
2098 bfd_vma tlsdesc_got_jump_table_offset
;
2101 struct elf_aarch64_obj_tdata
2103 struct elf_obj_tdata root
;
2105 /* local symbol descriptors */
2106 struct elf_aarch64_local_symbol
*locals
;
2108 /* Zero to warn when linking objects with incompatible enum sizes. */
2109 int no_enum_size_warning
;
2111 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
2112 int no_wchar_size_warning
;
2115 #define elf_aarch64_tdata(bfd) \
2116 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
2118 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
2120 #define is_aarch64_elf(bfd) \
2121 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2122 && elf_tdata (bfd) != NULL \
2123 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2126 elfNN_aarch64_mkobject (bfd
*abfd
)
2128 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
),
2132 #define elf_aarch64_hash_entry(ent) \
2133 ((struct elf_aarch64_link_hash_entry *)(ent))
2135 #define GOT_UNKNOWN 0
2136 #define GOT_NORMAL 1
2137 #define GOT_TLS_GD 2
2138 #define GOT_TLS_IE 4
2139 #define GOT_TLSDESC_GD 8
2141 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
2143 /* AArch64 ELF linker hash entry. */
2144 struct elf_aarch64_link_hash_entry
2146 struct elf_link_hash_entry root
;
2148 /* Track dynamic relocs copied for this symbol. */
2149 struct elf_dyn_relocs
*dyn_relocs
;
2151 /* Since PLT entries have variable size, we need to record the
2152 index into .got.plt instead of recomputing it from the PLT
2154 bfd_signed_vma plt_got_offset
;
2156 /* Bit mask representing the type of GOT entry(s) if any required by
2158 unsigned int got_type
;
2160 /* A pointer to the most recently used stub hash entry against this
2162 struct elf_aarch64_stub_hash_entry
*stub_cache
;
2164 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
2165 is from the end of the jump table and reserved entries within the PLTGOT.
2167 The magic value (bfd_vma) -1 indicates that an offset has not
2169 bfd_vma tlsdesc_got_jump_table_offset
;
2173 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
2175 unsigned long r_symndx
)
2178 return elf_aarch64_hash_entry (h
)->got_type
;
2180 if (! elf_aarch64_locals (abfd
))
2183 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
2186 /* Get the AArch64 elf linker hash table from a link_info structure. */
2187 #define elf_aarch64_hash_table(info) \
2188 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
2190 #define aarch64_stub_hash_lookup(table, string, create, copy) \
2191 ((struct elf_aarch64_stub_hash_entry *) \
2192 bfd_hash_lookup ((table), (string), (create), (copy)))
2194 /* AArch64 ELF linker hash table. */
2195 struct elf_aarch64_link_hash_table
2197 /* The main hash table. */
2198 struct elf_link_hash_table root
;
2200 /* Nonzero to force PIC branch veneers. */
2203 /* Fix erratum 835769. */
2204 int fix_erratum_835769
;
2206 /* Fix erratum 843419. */
2207 int fix_erratum_843419
;
2209 /* Enable ADRP->ADR rewrite for erratum 843419 workaround. */
2210 int fix_erratum_843419_adr
;
2212 /* The number of bytes in the initial entry in the PLT. */
2213 bfd_size_type plt_header_size
;
2215 /* The number of bytes in the subsequent PLT etries. */
2216 bfd_size_type plt_entry_size
;
2218 /* Short-cuts to get to dynamic linker sections. */
2222 /* Small local sym cache. */
2223 struct sym_cache sym_cache
;
2225 /* For convenience in allocate_dynrelocs. */
2228 /* The amount of space used by the reserved portion of the sgotplt
2229 section, plus whatever space is used by the jump slots. */
2230 bfd_vma sgotplt_jump_table_size
;
2232 /* The stub hash table. */
2233 struct bfd_hash_table stub_hash_table
;
2235 /* Linker stub bfd. */
2238 /* Linker call-backs. */
2239 asection
*(*add_stub_section
) (const char *, asection
*);
2240 void (*layout_sections_again
) (void);
2242 /* Array to keep track of which stub sections have been created, and
2243 information on stub grouping. */
2246 /* This is the section to which stubs in the group will be
2249 /* The stub section. */
2253 /* Assorted information used by elfNN_aarch64_size_stubs. */
2254 unsigned int bfd_count
;
2256 asection
**input_list
;
2258 /* The offset into splt of the PLT entry for the TLS descriptor
2259 resolver. Special values are 0, if not necessary (or not found
2260 to be necessary yet), and -1 if needed but not determined
2262 bfd_vma tlsdesc_plt
;
2264 /* The GOT offset for the lazy trampoline. Communicated to the
2265 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
2266 indicates an offset is not allocated. */
2267 bfd_vma dt_tlsdesc_got
;
2269 /* Used by local STT_GNU_IFUNC symbols. */
2270 htab_t loc_hash_table
;
2271 void * loc_hash_memory
;
2274 /* Create an entry in an AArch64 ELF linker hash table. */
2276 static struct bfd_hash_entry
*
2277 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
2278 struct bfd_hash_table
*table
,
2281 struct elf_aarch64_link_hash_entry
*ret
=
2282 (struct elf_aarch64_link_hash_entry
*) entry
;
2284 /* Allocate the structure if it has not already been allocated by a
2287 ret
= bfd_hash_allocate (table
,
2288 sizeof (struct elf_aarch64_link_hash_entry
));
2290 return (struct bfd_hash_entry
*) ret
;
2292 /* Call the allocation method of the superclass. */
2293 ret
= ((struct elf_aarch64_link_hash_entry
*)
2294 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
2298 ret
->dyn_relocs
= NULL
;
2299 ret
->got_type
= GOT_UNKNOWN
;
2300 ret
->plt_got_offset
= (bfd_vma
) - 1;
2301 ret
->stub_cache
= NULL
;
2302 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
2305 return (struct bfd_hash_entry
*) ret
;
2308 /* Initialize an entry in the stub hash table. */
2310 static struct bfd_hash_entry
*
2311 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
2312 struct bfd_hash_table
*table
, const char *string
)
2314 /* Allocate the structure if it has not already been allocated by a
2318 entry
= bfd_hash_allocate (table
,
2320 elf_aarch64_stub_hash_entry
));
2325 /* Call the allocation method of the superclass. */
2326 entry
= bfd_hash_newfunc (entry
, table
, string
);
2329 struct elf_aarch64_stub_hash_entry
*eh
;
2331 /* Initialize the local fields. */
2332 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
2333 eh
->adrp_offset
= 0;
2334 eh
->stub_sec
= NULL
;
2335 eh
->stub_offset
= 0;
2336 eh
->target_value
= 0;
2337 eh
->target_section
= NULL
;
2338 eh
->stub_type
= aarch64_stub_none
;
2346 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
2347 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2348 as global symbol. We reuse indx and dynstr_index for local symbol
2349 hash since they aren't used by global symbols in this backend. */
2352 elfNN_aarch64_local_htab_hash (const void *ptr
)
2354 struct elf_link_hash_entry
*h
2355 = (struct elf_link_hash_entry
*) ptr
;
2356 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
2359 /* Compare local hash entries. */
2362 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
2364 struct elf_link_hash_entry
*h1
2365 = (struct elf_link_hash_entry
*) ptr1
;
2366 struct elf_link_hash_entry
*h2
2367 = (struct elf_link_hash_entry
*) ptr2
;
2369 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
2372 /* Find and/or create a hash entry for local symbol. */
2374 static struct elf_link_hash_entry
*
2375 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
2376 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2379 struct elf_aarch64_link_hash_entry e
, *ret
;
2380 asection
*sec
= abfd
->sections
;
2381 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
2382 ELFNN_R_SYM (rel
->r_info
));
2385 e
.root
.indx
= sec
->id
;
2386 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2387 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
2388 create
? INSERT
: NO_INSERT
);
2395 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
2399 ret
= (struct elf_aarch64_link_hash_entry
*)
2400 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
2401 sizeof (struct elf_aarch64_link_hash_entry
));
2404 memset (ret
, 0, sizeof (*ret
));
2405 ret
->root
.indx
= sec
->id
;
2406 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2407 ret
->root
.dynindx
= -1;
2413 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2416 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
2417 struct elf_link_hash_entry
*dir
,
2418 struct elf_link_hash_entry
*ind
)
2420 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
2422 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
2423 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
2425 if (eind
->dyn_relocs
!= NULL
)
2427 if (edir
->dyn_relocs
!= NULL
)
2429 struct elf_dyn_relocs
**pp
;
2430 struct elf_dyn_relocs
*p
;
2432 /* Add reloc counts against the indirect sym to the direct sym
2433 list. Merge any entries against the same section. */
2434 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
2436 struct elf_dyn_relocs
*q
;
2438 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
2439 if (q
->sec
== p
->sec
)
2441 q
->pc_count
+= p
->pc_count
;
2442 q
->count
+= p
->count
;
2449 *pp
= edir
->dyn_relocs
;
2452 edir
->dyn_relocs
= eind
->dyn_relocs
;
2453 eind
->dyn_relocs
= NULL
;
2456 if (ind
->root
.type
== bfd_link_hash_indirect
)
2458 /* Copy over PLT info. */
2459 if (dir
->got
.refcount
<= 0)
2461 edir
->got_type
= eind
->got_type
;
2462 eind
->got_type
= GOT_UNKNOWN
;
2466 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2469 /* Destroy an AArch64 elf linker hash table. */
2472 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
2474 struct elf_aarch64_link_hash_table
*ret
2475 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
2477 if (ret
->loc_hash_table
)
2478 htab_delete (ret
->loc_hash_table
);
2479 if (ret
->loc_hash_memory
)
2480 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
2482 bfd_hash_table_free (&ret
->stub_hash_table
);
2483 _bfd_elf_link_hash_table_free (obfd
);
2486 /* Create an AArch64 elf linker hash table. */
2488 static struct bfd_link_hash_table
*
2489 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
2491 struct elf_aarch64_link_hash_table
*ret
;
2492 bfd_size_type amt
= sizeof (struct elf_aarch64_link_hash_table
);
2494 ret
= bfd_zmalloc (amt
);
2498 if (!_bfd_elf_link_hash_table_init
2499 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
2500 sizeof (struct elf_aarch64_link_hash_entry
), AARCH64_ELF_DATA
))
2506 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
2507 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
2509 ret
->dt_tlsdesc_got
= (bfd_vma
) - 1;
2511 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
2512 sizeof (struct elf_aarch64_stub_hash_entry
)))
2514 _bfd_elf_link_hash_table_free (abfd
);
2518 ret
->loc_hash_table
= htab_try_create (1024,
2519 elfNN_aarch64_local_htab_hash
,
2520 elfNN_aarch64_local_htab_eq
,
2522 ret
->loc_hash_memory
= objalloc_create ();
2523 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
2525 elfNN_aarch64_link_hash_table_free (abfd
);
2528 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
2530 return &ret
->root
.root
;
2534 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
2535 bfd_vma offset
, bfd_vma value
)
2537 reloc_howto_type
*howto
;
2540 howto
= elfNN_aarch64_howto_from_type (r_type
);
2541 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
2544 r_type
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
2545 value
= _bfd_aarch64_elf_resolve_relocation (r_type
, place
, value
, 0, FALSE
);
2546 return _bfd_aarch64_elf_put_addend (input_bfd
,
2547 input_section
->contents
+ offset
, r_type
,
2551 static enum elf_aarch64_stub_type
2552 aarch64_select_branch_stub (bfd_vma value
, bfd_vma place
)
2554 if (aarch64_valid_for_adrp_p (value
, place
))
2555 return aarch64_stub_adrp_branch
;
2556 return aarch64_stub_long_branch
;
2559 /* Determine the type of stub needed, if any, for a call. */
2561 static enum elf_aarch64_stub_type
2562 aarch64_type_of_stub (struct bfd_link_info
*info
,
2563 asection
*input_sec
,
2564 const Elf_Internal_Rela
*rel
,
2566 unsigned char st_type
,
2567 struct elf_aarch64_link_hash_entry
*hash
,
2568 bfd_vma destination
)
2571 bfd_signed_vma branch_offset
;
2572 unsigned int r_type
;
2573 struct elf_aarch64_link_hash_table
*globals
;
2574 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
2575 bfd_boolean via_plt_p
;
2577 if (st_type
!= STT_FUNC
2578 && (sym_sec
!= bfd_abs_section_ptr
))
2581 globals
= elf_aarch64_hash_table (info
);
2582 via_plt_p
= (globals
->root
.splt
!= NULL
&& hash
!= NULL
2583 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1);
2584 /* Make sure call to plt stub can fit into the branch range. */
2586 destination
= (globals
->root
.splt
->output_section
->vma
2587 + globals
->root
.splt
->output_offset
2588 + hash
->root
.plt
.offset
);
2590 /* Determine where the call point is. */
2591 location
= (input_sec
->output_offset
2592 + input_sec
->output_section
->vma
+ rel
->r_offset
);
2594 branch_offset
= (bfd_signed_vma
) (destination
- location
);
2596 r_type
= ELFNN_R_TYPE (rel
->r_info
);
2598 /* We don't want to redirect any old unconditional jump in this way,
2599 only one which is being used for a sibcall, where it is
2600 acceptable for the IP0 and IP1 registers to be clobbered. */
2601 if ((r_type
== AARCH64_R (CALL26
) || r_type
== AARCH64_R (JUMP26
))
2602 && (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
2603 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
))
2605 stub_type
= aarch64_stub_long_branch
;
2611 /* Build a name for an entry in the stub hash table. */
2614 elfNN_aarch64_stub_name (const asection
*input_section
,
2615 const asection
*sym_sec
,
2616 const struct elf_aarch64_link_hash_entry
*hash
,
2617 const Elf_Internal_Rela
*rel
)
2624 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
2625 stub_name
= bfd_malloc (len
);
2626 if (stub_name
!= NULL
)
2627 snprintf (stub_name
, len
, "%08x_%s+%" BFD_VMA_FMT
"x",
2628 (unsigned int) input_section
->id
,
2629 hash
->root
.root
.root
.string
,
2634 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2635 stub_name
= bfd_malloc (len
);
2636 if (stub_name
!= NULL
)
2637 snprintf (stub_name
, len
, "%08x_%x:%x+%" BFD_VMA_FMT
"x",
2638 (unsigned int) input_section
->id
,
2639 (unsigned int) sym_sec
->id
,
2640 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
2647 /* Look up an entry in the stub hash. Stub entries are cached because
2648 creating the stub name takes a bit of time. */
2650 static struct elf_aarch64_stub_hash_entry
*
2651 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
2652 const asection
*sym_sec
,
2653 struct elf_link_hash_entry
*hash
,
2654 const Elf_Internal_Rela
*rel
,
2655 struct elf_aarch64_link_hash_table
*htab
)
2657 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2658 struct elf_aarch64_link_hash_entry
*h
=
2659 (struct elf_aarch64_link_hash_entry
*) hash
;
2660 const asection
*id_sec
;
2662 if ((input_section
->flags
& SEC_CODE
) == 0)
2665 /* If this input section is part of a group of sections sharing one
2666 stub section, then use the id of the first section in the group.
2667 Stub names need to include a section id, as there may well be
2668 more than one stub used to reach say, printf, and we need to
2669 distinguish between them. */
2670 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
2672 if (h
!= NULL
&& h
->stub_cache
!= NULL
2673 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
2675 stub_entry
= h
->stub_cache
;
2681 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
);
2682 if (stub_name
== NULL
)
2685 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
2686 stub_name
, FALSE
, FALSE
);
2688 h
->stub_cache
= stub_entry
;
2697 /* Create a stub section. */
2700 _bfd_aarch64_create_stub_section (asection
*section
,
2701 struct elf_aarch64_link_hash_table
*htab
)
2707 namelen
= strlen (section
->name
);
2708 len
= namelen
+ sizeof (STUB_SUFFIX
);
2709 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
2713 memcpy (s_name
, section
->name
, namelen
);
2714 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
2715 return (*htab
->add_stub_section
) (s_name
, section
);
2719 /* Find or create a stub section for a link section.
2721 Fix or create the stub section used to collect stubs attached to
2722 the specified link section. */
2725 _bfd_aarch64_get_stub_for_link_section (asection
*link_section
,
2726 struct elf_aarch64_link_hash_table
*htab
)
2728 if (htab
->stub_group
[link_section
->id
].stub_sec
== NULL
)
2729 htab
->stub_group
[link_section
->id
].stub_sec
2730 = _bfd_aarch64_create_stub_section (link_section
, htab
);
2731 return htab
->stub_group
[link_section
->id
].stub_sec
;
2735 /* Find or create a stub section in the stub group for an input
2739 _bfd_aarch64_create_or_find_stub_sec (asection
*section
,
2740 struct elf_aarch64_link_hash_table
*htab
)
2742 asection
*link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2743 return _bfd_aarch64_get_stub_for_link_section (link_sec
, htab
);
2747 /* Add a new stub entry in the stub group associated with an input
2748 section to the stub hash. Not all fields of the new stub entry are
2751 static struct elf_aarch64_stub_hash_entry
*
2752 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name
,
2754 struct elf_aarch64_link_hash_table
*htab
)
2758 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2760 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2761 stub_sec
= _bfd_aarch64_create_or_find_stub_sec (section
, htab
);
2763 /* Enter this entry into the linker stub hash table. */
2764 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2766 if (stub_entry
== NULL
)
2768 (*_bfd_error_handler
) (_("%s: cannot create stub entry %s"),
2769 section
->owner
, stub_name
);
2773 stub_entry
->stub_sec
= stub_sec
;
2774 stub_entry
->stub_offset
= 0;
2775 stub_entry
->id_sec
= link_sec
;
2780 /* Add a new stub entry in the final stub section to the stub hash.
2781 Not all fields of the new stub entry are initialised. */
2783 static struct elf_aarch64_stub_hash_entry
*
2784 _bfd_aarch64_add_stub_entry_after (const char *stub_name
,
2785 asection
*link_section
,
2786 struct elf_aarch64_link_hash_table
*htab
)
2789 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2791 stub_sec
= _bfd_aarch64_get_stub_for_link_section (link_section
, htab
);
2792 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2794 if (stub_entry
== NULL
)
2796 (*_bfd_error_handler
) (_("cannot create stub entry %s"), stub_name
);
2800 stub_entry
->stub_sec
= stub_sec
;
2801 stub_entry
->stub_offset
= 0;
2802 stub_entry
->id_sec
= link_section
;
2809 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
2810 void *in_arg ATTRIBUTE_UNUSED
)
2812 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2817 bfd_vma veneered_insn_loc
;
2818 bfd_vma veneer_entry_loc
;
2819 bfd_signed_vma branch_offset
= 0;
2820 unsigned int template_size
;
2821 const uint32_t *template;
2824 /* Massage our args to the form they really have. */
2825 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2827 stub_sec
= stub_entry
->stub_sec
;
2829 /* Make a note of the offset within the stubs for this entry. */
2830 stub_entry
->stub_offset
= stub_sec
->size
;
2831 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
2833 stub_bfd
= stub_sec
->owner
;
2835 /* This is the address of the stub destination. */
2836 sym_value
= (stub_entry
->target_value
2837 + stub_entry
->target_section
->output_offset
2838 + stub_entry
->target_section
->output_section
->vma
);
2840 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
2842 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
2843 + stub_sec
->output_offset
);
2845 /* See if we can relax the stub. */
2846 if (aarch64_valid_for_adrp_p (sym_value
, place
))
2847 stub_entry
->stub_type
= aarch64_select_branch_stub (sym_value
, place
);
2850 switch (stub_entry
->stub_type
)
2852 case aarch64_stub_adrp_branch
:
2853 template = aarch64_adrp_branch_stub
;
2854 template_size
= sizeof (aarch64_adrp_branch_stub
);
2856 case aarch64_stub_long_branch
:
2857 template = aarch64_long_branch_stub
;
2858 template_size
= sizeof (aarch64_long_branch_stub
);
2860 case aarch64_stub_erratum_835769_veneer
:
2861 template = aarch64_erratum_835769_stub
;
2862 template_size
= sizeof (aarch64_erratum_835769_stub
);
2864 case aarch64_stub_erratum_843419_veneer
:
2865 template = aarch64_erratum_843419_stub
;
2866 template_size
= sizeof (aarch64_erratum_843419_stub
);
2872 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
2874 bfd_putl32 (template[i
], loc
);
2878 template_size
= (template_size
+ 7) & ~7;
2879 stub_sec
->size
+= template_size
;
2881 switch (stub_entry
->stub_type
)
2883 case aarch64_stub_adrp_branch
:
2884 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
2885 stub_entry
->stub_offset
, sym_value
))
2886 /* The stub would not have been relaxed if the offset was out
2890 if (aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
2891 stub_entry
->stub_offset
+ 4, sym_value
))
2895 case aarch64_stub_long_branch
:
2896 /* We want the value relative to the address 12 bytes back from the
2898 if (aarch64_relocate (AARCH64_R (PRELNN
), stub_bfd
, stub_sec
,
2899 stub_entry
->stub_offset
+ 16, sym_value
+ 12))
2903 case aarch64_stub_erratum_835769_veneer
:
2904 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
2905 + stub_entry
->target_section
->output_offset
2906 + stub_entry
->target_value
;
2907 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
2908 + stub_entry
->stub_sec
->output_offset
2909 + stub_entry
->stub_offset
;
2910 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
2911 branch_offset
>>= 2;
2912 branch_offset
&= 0x3ffffff;
2913 bfd_putl32 (stub_entry
->veneered_insn
,
2914 stub_sec
->contents
+ stub_entry
->stub_offset
);
2915 bfd_putl32 (template[1] | branch_offset
,
2916 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
2919 case aarch64_stub_erratum_843419_veneer
:
2920 if (aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
2921 stub_entry
->stub_offset
+ 4, sym_value
+ 4))
2932 /* As above, but don't actually build the stub. Just bump offset so
2933 we know stub section sizes. */
2936 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
,
2937 void *in_arg ATTRIBUTE_UNUSED
)
2939 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2942 /* Massage our args to the form they really have. */
2943 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2945 switch (stub_entry
->stub_type
)
2947 case aarch64_stub_adrp_branch
:
2948 size
= sizeof (aarch64_adrp_branch_stub
);
2950 case aarch64_stub_long_branch
:
2951 size
= sizeof (aarch64_long_branch_stub
);
2953 case aarch64_stub_erratum_835769_veneer
:
2954 size
= sizeof (aarch64_erratum_835769_stub
);
2956 case aarch64_stub_erratum_843419_veneer
:
2957 size
= sizeof (aarch64_erratum_843419_stub
);
2963 size
= (size
+ 7) & ~7;
2964 stub_entry
->stub_sec
->size
+= size
;
2968 /* External entry points for sizing and building linker stubs. */
2970 /* Set up various things so that we can make a list of input sections
2971 for each output section included in the link. Returns -1 on error,
2972 0 when no stubs will be needed, and 1 on success. */
2975 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
2976 struct bfd_link_info
*info
)
2979 unsigned int bfd_count
;
2980 int top_id
, top_index
;
2982 asection
**input_list
, **list
;
2984 struct elf_aarch64_link_hash_table
*htab
=
2985 elf_aarch64_hash_table (info
);
2987 if (!is_elf_hash_table (htab
))
2990 /* Count the number of input BFDs and find the top input section id. */
2991 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
2992 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
2995 for (section
= input_bfd
->sections
;
2996 section
!= NULL
; section
= section
->next
)
2998 if (top_id
< section
->id
)
2999 top_id
= section
->id
;
3002 htab
->bfd_count
= bfd_count
;
3004 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
3005 htab
->stub_group
= bfd_zmalloc (amt
);
3006 if (htab
->stub_group
== NULL
)
3009 /* We can't use output_bfd->section_count here to find the top output
3010 section index as some sections may have been removed, and
3011 _bfd_strip_section_from_output doesn't renumber the indices. */
3012 for (section
= output_bfd
->sections
, top_index
= 0;
3013 section
!= NULL
; section
= section
->next
)
3015 if (top_index
< section
->index
)
3016 top_index
= section
->index
;
3019 htab
->top_index
= top_index
;
3020 amt
= sizeof (asection
*) * (top_index
+ 1);
3021 input_list
= bfd_malloc (amt
);
3022 htab
->input_list
= input_list
;
3023 if (input_list
== NULL
)
3026 /* For sections we aren't interested in, mark their entries with a
3027 value we can check later. */
3028 list
= input_list
+ top_index
;
3030 *list
= bfd_abs_section_ptr
;
3031 while (list
-- != input_list
);
3033 for (section
= output_bfd
->sections
;
3034 section
!= NULL
; section
= section
->next
)
3036 if ((section
->flags
& SEC_CODE
) != 0)
3037 input_list
[section
->index
] = NULL
;
3043 /* Used by elfNN_aarch64_next_input_section and group_sections. */
3044 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
3046 /* The linker repeatedly calls this function for each input section,
3047 in the order that input sections are linked into output sections.
3048 Build lists of input sections to determine groupings between which
3049 we may insert linker stubs. */
3052 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
3054 struct elf_aarch64_link_hash_table
*htab
=
3055 elf_aarch64_hash_table (info
);
3057 if (isec
->output_section
->index
<= htab
->top_index
)
3059 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
3061 if (*list
!= bfd_abs_section_ptr
)
3063 /* Steal the link_sec pointer for our list. */
3064 /* This happens to make the list in reverse order,
3065 which is what we want. */
3066 PREV_SEC (isec
) = *list
;
3072 /* See whether we can group stub sections together. Grouping stub
3073 sections may result in fewer stubs. More importantly, we need to
3074 put all .init* and .fini* stubs at the beginning of the .init or
3075 .fini output sections respectively, because glibc splits the
3076 _init and _fini functions into multiple parts. Putting a stub in
3077 the middle of a function is not a good idea. */
3080 group_sections (struct elf_aarch64_link_hash_table
*htab
,
3081 bfd_size_type stub_group_size
,
3082 bfd_boolean stubs_always_before_branch
)
3084 asection
**list
= htab
->input_list
+ htab
->top_index
;
3088 asection
*tail
= *list
;
3090 if (tail
== bfd_abs_section_ptr
)
3093 while (tail
!= NULL
)
3097 bfd_size_type total
;
3101 while ((prev
= PREV_SEC (curr
)) != NULL
3102 && ((total
+= curr
->output_offset
- prev
->output_offset
)
3106 /* OK, the size from the start of CURR to the end is less
3107 than stub_group_size and thus can be handled by one stub
3108 section. (Or the tail section is itself larger than
3109 stub_group_size, in which case we may be toast.)
3110 We should really be keeping track of the total size of
3111 stubs added here, as stubs contribute to the final output
3115 prev
= PREV_SEC (tail
);
3116 /* Set up this stub group. */
3117 htab
->stub_group
[tail
->id
].link_sec
= curr
;
3119 while (tail
!= curr
&& (tail
= prev
) != NULL
);
3121 /* But wait, there's more! Input sections up to stub_group_size
3122 bytes before the stub section can be handled by it too. */
3123 if (!stubs_always_before_branch
)
3127 && ((total
+= tail
->output_offset
- prev
->output_offset
)
3131 prev
= PREV_SEC (tail
);
3132 htab
->stub_group
[tail
->id
].link_sec
= curr
;
3138 while (list
-- != htab
->input_list
);
3140 free (htab
->input_list
);
3145 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
3147 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
3148 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
3149 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
3150 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
3151 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
3152 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
3154 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
3155 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
3156 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
3157 #define AARCH64_ZR 0x1f
3159 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
3160 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
3162 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
3163 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
3164 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
3165 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
3166 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
3167 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
3168 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
3169 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
3170 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
3171 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
3172 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
3173 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
3174 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
3175 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
3176 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
3177 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
3178 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
3179 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
3181 /* Classify an INSN if it is indeed a load/store.
3183 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
3185 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
3188 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned.
3193 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rt2
,
3194 bfd_boolean
*pair
, bfd_boolean
*load
)
3202 /* Bail out quickly if INSN doesn't fall into the the load-store
3204 if (!AARCH64_LDST (insn
))
3209 if (AARCH64_LDST_EX (insn
))
3211 *rt
= AARCH64_RT (insn
);
3213 if (AARCH64_BIT (insn
, 21) == 1)
3216 *rt2
= AARCH64_RT2 (insn
);
3218 *load
= AARCH64_LD (insn
);
3221 else if (AARCH64_LDST_NAP (insn
)
3222 || AARCH64_LDSTP_PI (insn
)
3223 || AARCH64_LDSTP_O (insn
)
3224 || AARCH64_LDSTP_PRE (insn
))
3227 *rt
= AARCH64_RT (insn
);
3228 *rt2
= AARCH64_RT2 (insn
);
3229 *load
= AARCH64_LD (insn
);
3232 else if (AARCH64_LDST_PCREL (insn
)
3233 || AARCH64_LDST_UI (insn
)
3234 || AARCH64_LDST_PIIMM (insn
)
3235 || AARCH64_LDST_U (insn
)
3236 || AARCH64_LDST_PREIMM (insn
)
3237 || AARCH64_LDST_RO (insn
)
3238 || AARCH64_LDST_UIMM (insn
))
3240 *rt
= AARCH64_RT (insn
);
3242 if (AARCH64_LDST_PCREL (insn
))
3244 opc
= AARCH64_BITS (insn
, 22, 2);
3245 v
= AARCH64_BIT (insn
, 26);
3246 opc_v
= opc
| (v
<< 2);
3247 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
3248 || opc_v
== 5 || opc_v
== 7);
3251 else if (AARCH64_LDST_SIMD_M (insn
)
3252 || AARCH64_LDST_SIMD_M_PI (insn
))
3254 *rt
= AARCH64_RT (insn
);
3255 *load
= AARCH64_BIT (insn
, 22);
3256 opcode
= (insn
>> 12) & 0xf;
3283 else if (AARCH64_LDST_SIMD_S (insn
)
3284 || AARCH64_LDST_SIMD_S_PI (insn
))
3286 *rt
= AARCH64_RT (insn
);
3287 r
= (insn
>> 21) & 1;
3288 *load
= AARCH64_BIT (insn
, 22);
3289 opcode
= (insn
>> 13) & 0x7;
3301 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3309 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3321 /* Return TRUE if INSN is multiply-accumulate. */
3324 aarch64_mlxl_p (uint32_t insn
)
3326 uint32_t op31
= AARCH64_OP31 (insn
);
3328 if (AARCH64_MAC (insn
)
3329 && (op31
== 0 || op31
== 1 || op31
== 5)
3330 /* Exclude MUL instructions which are encoded as a multiple accumulate
3332 && AARCH64_RA (insn
) != AARCH64_ZR
)
3338 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3339 it is possible for a 64-bit multiply-accumulate instruction to generate an
3340 incorrect result. The details are quite complex and hard to
3341 determine statically, since branches in the code may exist in some
3342 circumstances, but all cases end with a memory (load, store, or
3343 prefetch) instruction followed immediately by the multiply-accumulate
3344 operation. We employ a linker patching technique, by moving the potentially
3345 affected multiply-accumulate instruction into a patch region and replacing
3346 the original instruction with a branch to the patch. This function checks
3347 if INSN_1 is the memory operation followed by a multiply-accumulate
3348 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3349 if INSN_1 and INSN_2 are safe. */
3352 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
3362 if (aarch64_mlxl_p (insn_2
)
3363 && aarch64_mem_op_p (insn_1
, &rt
, &rt2
, &pair
, &load
))
3365 /* Any SIMD memory op is independent of the subsequent MLA
3366 by definition of the erratum. */
3367 if (AARCH64_BIT (insn_1
, 26))
3370 /* If not SIMD, check for integer memory ops and MLA relationship. */
3371 rn
= AARCH64_RN (insn_2
);
3372 ra
= AARCH64_RA (insn_2
);
3373 rm
= AARCH64_RM (insn_2
);
3375 /* If this is a load and there's a true(RAW) dependency, we are safe
3376 and this is not an erratum sequence. */
3378 (rt
== rn
|| rt
== rm
|| rt
== ra
3379 || (pair
&& (rt2
== rn
|| rt2
== rm
|| rt2
== ra
))))
3382 /* We conservatively put out stubs for all other cases (including
3390 /* Used to order a list of mapping symbols by address. */
3393 elf_aarch64_compare_mapping (const void *a
, const void *b
)
3395 const elf_aarch64_section_map
*amap
= (const elf_aarch64_section_map
*) a
;
3396 const elf_aarch64_section_map
*bmap
= (const elf_aarch64_section_map
*) b
;
3398 if (amap
->vma
> bmap
->vma
)
3400 else if (amap
->vma
< bmap
->vma
)
3402 else if (amap
->type
> bmap
->type
)
3403 /* Ensure results do not depend on the host qsort for objects with
3404 multiple mapping symbols at the same address by sorting on type
3407 else if (amap
->type
< bmap
->type
)
3415 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes
)
3417 char *stub_name
= (char *) bfd_malloc
3418 (strlen ("__erratum_835769_veneer_") + 16);
3419 sprintf (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
3423 /* Scan for Cortex-A53 erratum 835769 sequence.
3425 Return TRUE else FALSE on abnormal termination. */
3428 _bfd_aarch64_erratum_835769_scan (bfd
*input_bfd
,
3429 struct bfd_link_info
*info
,
3430 unsigned int *num_fixes_p
)
3433 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3434 unsigned int num_fixes
= *num_fixes_p
;
3439 for (section
= input_bfd
->sections
;
3441 section
= section
->next
)
3443 bfd_byte
*contents
= NULL
;
3444 struct _aarch64_elf_section_data
*sec_data
;
3447 if (elf_section_type (section
) != SHT_PROGBITS
3448 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3449 || (section
->flags
& SEC_EXCLUDE
) != 0
3450 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3451 || (section
->output_section
== bfd_abs_section_ptr
))
3454 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3455 contents
= elf_section_data (section
)->this_hdr
.contents
;
3456 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3459 sec_data
= elf_aarch64_section_data (section
);
3461 qsort (sec_data
->map
, sec_data
->mapcount
,
3462 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3464 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3466 unsigned int span_start
= sec_data
->map
[span
].vma
;
3467 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3468 ? sec_data
->map
[0].vma
+ section
->size
3469 : sec_data
->map
[span
+ 1].vma
);
3471 char span_type
= sec_data
->map
[span
].type
;
3473 if (span_type
== 'd')
3476 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
3478 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3479 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3481 if (aarch64_erratum_sequence (insn_1
, insn_2
))
3483 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3484 char *stub_name
= _bfd_aarch64_erratum_835769_stub_name (num_fixes
);
3488 stub_entry
= _bfd_aarch64_add_stub_entry_in_group (stub_name
,
3494 stub_entry
->stub_type
= aarch64_stub_erratum_835769_veneer
;
3495 stub_entry
->target_section
= section
;
3496 stub_entry
->target_value
= i
+ 4;
3497 stub_entry
->veneered_insn
= insn_2
;
3498 stub_entry
->output_name
= stub_name
;
3503 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3507 *num_fixes_p
= num_fixes
;
3513 /* Test if instruction INSN is ADRP. */
3516 _bfd_aarch64_adrp_p (uint32_t insn
)
3518 return ((insn
& 0x9f000000) == 0x90000000);
3522 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
3525 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1
, uint32_t insn_2
,
3533 return (aarch64_mem_op_p (insn_2
, &rt
, &rt2
, &pair
, &load
)
3536 && AARCH64_LDST_UIMM (insn_3
)
3537 && AARCH64_RN (insn_3
) == AARCH64_RD (insn_1
));
3541 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
3543 Return TRUE if section CONTENTS at offset I contains one of the
3544 erratum 843419 sequences, otherwise return FALSE. If a sequence is
3545 seen set P_VENEER_I to the offset of the final LOAD/STORE
3546 instruction in the sequence.
3550 _bfd_aarch64_erratum_843419_p (bfd_byte
*contents
, bfd_vma vma
,
3551 bfd_vma i
, bfd_vma span_end
,
3552 bfd_vma
*p_veneer_i
)
3554 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3556 if (!_bfd_aarch64_adrp_p (insn_1
))
3559 if (span_end
< i
+ 12)
3562 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3563 uint32_t insn_3
= bfd_getl32 (contents
+ i
+ 8);
3565 if ((vma
& 0xfff) != 0xff8 && (vma
& 0xfff) != 0xffc)
3568 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_3
))
3570 *p_veneer_i
= i
+ 8;
3574 if (span_end
< i
+ 16)
3577 uint32_t insn_4
= bfd_getl32 (contents
+ i
+ 12);
3579 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_4
))
3581 *p_veneer_i
= i
+ 12;
3589 /* Resize all stub sections. */
3592 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table
*htab
)
3596 /* OK, we've added some stubs. Find out the new size of the
3598 for (section
= htab
->stub_bfd
->sections
;
3599 section
!= NULL
; section
= section
->next
)
3601 /* Ignore non-stub sections. */
3602 if (!strstr (section
->name
, STUB_SUFFIX
))
3607 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
3609 for (section
= htab
->stub_bfd
->sections
;
3610 section
!= NULL
; section
= section
->next
)
3612 if (!strstr (section
->name
, STUB_SUFFIX
))
3618 /* Ensure all stub sections have a size which is a multiple of
3619 4096. This is important in order to ensure that the insertion
3620 of stub sections does not in itself move existing code around
3621 in such a way that new errata sequences are created. */
3622 if (htab
->fix_erratum_843419
)
3624 section
->size
= BFD_ALIGN (section
->size
, 0x1000);
3629 /* Construct an erratum 843419 workaround stub name.
3633 _bfd_aarch64_erratum_843419_stub_name (asection
*input_section
,
3636 const bfd_size_type len
= 8 + 4 + 1 + 8 + 1 + 16 + 1;
3637 char *stub_name
= bfd_malloc (len
);
3639 if (stub_name
!= NULL
)
3640 snprintf (stub_name
, len
, "e843419@%04x_%08x_%" BFD_VMA_FMT
"x",
3641 input_section
->owner
->id
,
3647 /* Build a stub_entry structure describing an 843419 fixup.
3649 The stub_entry constructed is populated with the bit pattern INSN
3650 of the instruction located at OFFSET within input SECTION.
3652 Returns TRUE on success. */
3655 _bfd_aarch64_erratum_843419_fixup (uint32_t insn
,
3656 bfd_vma adrp_offset
,
3657 bfd_vma ldst_offset
,
3659 struct bfd_link_info
*info
)
3661 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3663 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3665 stub_name
= _bfd_aarch64_erratum_843419_stub_name (section
, ldst_offset
);
3666 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3674 /* We always place an 843419 workaround veneer in the stub section
3675 attached to the input section in which an erratum sequence has
3676 been found. This ensures that later in the link process (in
3677 elfNN_aarch64_write_section) when we copy the veneered
3678 instruction from the input section into the stub section the
3679 copied instruction will have had any relocations applied to it.
3680 If we placed workaround veneers in any other stub section then we
3681 could not assume that all relocations have been processed on the
3682 corresponding input section at the point we output the stub
3686 stub_entry
= _bfd_aarch64_add_stub_entry_after (stub_name
, section
, htab
);
3687 if (stub_entry
== NULL
)
3693 stub_entry
->adrp_offset
= adrp_offset
;
3694 stub_entry
->target_value
= ldst_offset
;
3695 stub_entry
->target_section
= section
;
3696 stub_entry
->stub_type
= aarch64_stub_erratum_843419_veneer
;
3697 stub_entry
->veneered_insn
= insn
;
3698 stub_entry
->output_name
= stub_name
;
3704 /* Scan an input section looking for the signature of erratum 843419.
3706 Scans input SECTION in INPUT_BFD looking for erratum 843419
3707 signatures, for each signature found a stub_entry is created
3708 describing the location of the erratum for subsequent fixup.
3710 Return TRUE on successful scan, FALSE on failure to scan.
3714 _bfd_aarch64_erratum_843419_scan (bfd
*input_bfd
, asection
*section
,
3715 struct bfd_link_info
*info
)
3717 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3722 if (elf_section_type (section
) != SHT_PROGBITS
3723 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3724 || (section
->flags
& SEC_EXCLUDE
) != 0
3725 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3726 || (section
->output_section
== bfd_abs_section_ptr
))
3731 bfd_byte
*contents
= NULL
;
3732 struct _aarch64_elf_section_data
*sec_data
;
3735 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3736 contents
= elf_section_data (section
)->this_hdr
.contents
;
3737 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3740 sec_data
= elf_aarch64_section_data (section
);
3742 qsort (sec_data
->map
, sec_data
->mapcount
,
3743 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3745 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3747 unsigned int span_start
= sec_data
->map
[span
].vma
;
3748 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3749 ? sec_data
->map
[0].vma
+ section
->size
3750 : sec_data
->map
[span
+ 1].vma
);
3752 char span_type
= sec_data
->map
[span
].type
;
3754 if (span_type
== 'd')
3757 for (i
= span_start
; i
+ 8 < span_end
; i
+= 4)
3759 bfd_vma vma
= (section
->output_section
->vma
3760 + section
->output_offset
3764 if (_bfd_aarch64_erratum_843419_p
3765 (contents
, vma
, i
, span_end
, &veneer_i
))
3767 uint32_t insn
= bfd_getl32 (contents
+ veneer_i
);
3769 if (!_bfd_aarch64_erratum_843419_fixup (insn
, i
, veneer_i
,
3776 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3785 /* Determine and set the size of the stub section for a final link.
3787 The basic idea here is to examine all the relocations looking for
3788 PC-relative calls to a target that is unreachable with a "bl"
3792 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
3794 struct bfd_link_info
*info
,
3795 bfd_signed_vma group_size
,
3796 asection
* (*add_stub_section
) (const char *,
3798 void (*layout_sections_again
) (void))
3800 bfd_size_type stub_group_size
;
3801 bfd_boolean stubs_always_before_branch
;
3802 bfd_boolean stub_changed
= FALSE
;
3803 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3804 unsigned int num_erratum_835769_fixes
= 0;
3806 /* Propagate mach to stub bfd, because it may not have been
3807 finalized when we created stub_bfd. */
3808 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
3809 bfd_get_mach (output_bfd
));
3811 /* Stash our params away. */
3812 htab
->stub_bfd
= stub_bfd
;
3813 htab
->add_stub_section
= add_stub_section
;
3814 htab
->layout_sections_again
= layout_sections_again
;
3815 stubs_always_before_branch
= group_size
< 0;
3817 stub_group_size
= -group_size
;
3819 stub_group_size
= group_size
;
3821 if (stub_group_size
== 1)
3823 /* Default values. */
3824 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
3825 stub_group_size
= 127 * 1024 * 1024;
3828 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
3830 (*htab
->layout_sections_again
) ();
3832 if (htab
->fix_erratum_835769
)
3836 for (input_bfd
= info
->input_bfds
;
3837 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3838 if (!_bfd_aarch64_erratum_835769_scan (input_bfd
, info
,
3839 &num_erratum_835769_fixes
))
3842 _bfd_aarch64_resize_stubs (htab
);
3843 (*htab
->layout_sections_again
) ();
3846 if (htab
->fix_erratum_843419
)
3850 for (input_bfd
= info
->input_bfds
;
3852 input_bfd
= input_bfd
->link
.next
)
3856 for (section
= input_bfd
->sections
;
3858 section
= section
->next
)
3859 if (!_bfd_aarch64_erratum_843419_scan (input_bfd
, section
, info
))
3863 _bfd_aarch64_resize_stubs (htab
);
3864 (*htab
->layout_sections_again
) ();
3871 for (input_bfd
= info
->input_bfds
;
3872 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3874 Elf_Internal_Shdr
*symtab_hdr
;
3876 Elf_Internal_Sym
*local_syms
= NULL
;
3878 /* We'll need the symbol table in a second. */
3879 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3880 if (symtab_hdr
->sh_info
== 0)
3883 /* Walk over each section attached to the input bfd. */
3884 for (section
= input_bfd
->sections
;
3885 section
!= NULL
; section
= section
->next
)
3887 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
3889 /* If there aren't any relocs, then there's nothing more
3891 if ((section
->flags
& SEC_RELOC
) == 0
3892 || section
->reloc_count
== 0
3893 || (section
->flags
& SEC_CODE
) == 0)
3896 /* If this section is a link-once section that will be
3897 discarded, then don't create any stubs. */
3898 if (section
->output_section
== NULL
3899 || section
->output_section
->owner
!= output_bfd
)
3902 /* Get the relocs. */
3904 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
3905 NULL
, info
->keep_memory
);
3906 if (internal_relocs
== NULL
)
3907 goto error_ret_free_local
;
3909 /* Now examine each relocation. */
3910 irela
= internal_relocs
;
3911 irelaend
= irela
+ section
->reloc_count
;
3912 for (; irela
< irelaend
; irela
++)
3914 unsigned int r_type
, r_indx
;
3915 enum elf_aarch64_stub_type stub_type
;
3916 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3919 bfd_vma destination
;
3920 struct elf_aarch64_link_hash_entry
*hash
;
3921 const char *sym_name
;
3923 const asection
*id_sec
;
3924 unsigned char st_type
;
3927 r_type
= ELFNN_R_TYPE (irela
->r_info
);
3928 r_indx
= ELFNN_R_SYM (irela
->r_info
);
3930 if (r_type
>= (unsigned int) R_AARCH64_end
)
3932 bfd_set_error (bfd_error_bad_value
);
3933 error_ret_free_internal
:
3934 if (elf_section_data (section
)->relocs
== NULL
)
3935 free (internal_relocs
);
3936 goto error_ret_free_local
;
3939 /* Only look for stubs on unconditional branch and
3940 branch and link instructions. */
3941 if (r_type
!= (unsigned int) AARCH64_R (CALL26
)
3942 && r_type
!= (unsigned int) AARCH64_R (JUMP26
))
3945 /* Now determine the call target, its name, value,
3952 if (r_indx
< symtab_hdr
->sh_info
)
3954 /* It's a local symbol. */
3955 Elf_Internal_Sym
*sym
;
3956 Elf_Internal_Shdr
*hdr
;
3958 if (local_syms
== NULL
)
3961 = (Elf_Internal_Sym
*) symtab_hdr
->contents
;
3962 if (local_syms
== NULL
)
3964 = bfd_elf_get_elf_syms (input_bfd
, symtab_hdr
,
3965 symtab_hdr
->sh_info
, 0,
3967 if (local_syms
== NULL
)
3968 goto error_ret_free_internal
;
3971 sym
= local_syms
+ r_indx
;
3972 hdr
= elf_elfsections (input_bfd
)[sym
->st_shndx
];
3973 sym_sec
= hdr
->bfd_section
;
3975 /* This is an undefined symbol. It can never
3979 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
3980 sym_value
= sym
->st_value
;
3981 destination
= (sym_value
+ irela
->r_addend
3982 + sym_sec
->output_offset
3983 + sym_sec
->output_section
->vma
);
3984 st_type
= ELF_ST_TYPE (sym
->st_info
);
3986 = bfd_elf_string_from_elf_section (input_bfd
,
3987 symtab_hdr
->sh_link
,
3994 e_indx
= r_indx
- symtab_hdr
->sh_info
;
3995 hash
= ((struct elf_aarch64_link_hash_entry
*)
3996 elf_sym_hashes (input_bfd
)[e_indx
]);
3998 while (hash
->root
.root
.type
== bfd_link_hash_indirect
3999 || hash
->root
.root
.type
== bfd_link_hash_warning
)
4000 hash
= ((struct elf_aarch64_link_hash_entry
*)
4001 hash
->root
.root
.u
.i
.link
);
4003 if (hash
->root
.root
.type
== bfd_link_hash_defined
4004 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
4006 struct elf_aarch64_link_hash_table
*globals
=
4007 elf_aarch64_hash_table (info
);
4008 sym_sec
= hash
->root
.root
.u
.def
.section
;
4009 sym_value
= hash
->root
.root
.u
.def
.value
;
4010 /* For a destination in a shared library,
4011 use the PLT stub as target address to
4012 decide whether a branch stub is
4014 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
4015 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
4017 sym_sec
= globals
->root
.splt
;
4018 sym_value
= hash
->root
.plt
.offset
;
4019 if (sym_sec
->output_section
!= NULL
)
4020 destination
= (sym_value
4021 + sym_sec
->output_offset
4023 sym_sec
->output_section
->vma
);
4025 else if (sym_sec
->output_section
!= NULL
)
4026 destination
= (sym_value
+ irela
->r_addend
4027 + sym_sec
->output_offset
4028 + sym_sec
->output_section
->vma
);
4030 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
4031 || (hash
->root
.root
.type
4032 == bfd_link_hash_undefweak
))
4034 /* For a shared library, use the PLT stub as
4035 target address to decide whether a long
4036 branch stub is needed.
4037 For absolute code, they cannot be handled. */
4038 struct elf_aarch64_link_hash_table
*globals
=
4039 elf_aarch64_hash_table (info
);
4041 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
4042 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
4044 sym_sec
= globals
->root
.splt
;
4045 sym_value
= hash
->root
.plt
.offset
;
4046 if (sym_sec
->output_section
!= NULL
)
4047 destination
= (sym_value
4048 + sym_sec
->output_offset
4050 sym_sec
->output_section
->vma
);
4057 bfd_set_error (bfd_error_bad_value
);
4058 goto error_ret_free_internal
;
4060 st_type
= ELF_ST_TYPE (hash
->root
.type
);
4061 sym_name
= hash
->root
.root
.root
.string
;
4064 /* Determine what (if any) linker stub is needed. */
4065 stub_type
= aarch64_type_of_stub
4066 (info
, section
, irela
, sym_sec
, st_type
, hash
, destination
);
4067 if (stub_type
== aarch64_stub_none
)
4070 /* Support for grouping stub sections. */
4071 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
4073 /* Get the name of this stub. */
4074 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
4077 goto error_ret_free_internal
;
4080 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
4081 stub_name
, FALSE
, FALSE
);
4082 if (stub_entry
!= NULL
)
4084 /* The proper stub has already been created. */
4089 stub_entry
= _bfd_aarch64_add_stub_entry_in_group
4090 (stub_name
, section
, htab
);
4091 if (stub_entry
== NULL
)
4094 goto error_ret_free_internal
;
4097 stub_entry
->target_value
= sym_value
;
4098 stub_entry
->target_section
= sym_sec
;
4099 stub_entry
->stub_type
= stub_type
;
4100 stub_entry
->h
= hash
;
4101 stub_entry
->st_type
= st_type
;
4103 if (sym_name
== NULL
)
4104 sym_name
= "unnamed";
4105 len
= sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
);
4106 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
4107 if (stub_entry
->output_name
== NULL
)
4110 goto error_ret_free_internal
;
4113 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
4116 stub_changed
= TRUE
;
4119 /* We're done with the internal relocs, free them. */
4120 if (elf_section_data (section
)->relocs
== NULL
)
4121 free (internal_relocs
);
4128 _bfd_aarch64_resize_stubs (htab
);
4130 /* Ask the linker to do its stuff. */
4131 (*htab
->layout_sections_again
) ();
4132 stub_changed
= FALSE
;
4137 error_ret_free_local
:
4141 /* Build all the stubs associated with the current output file. The
4142 stubs are kept in a hash table attached to the main linker hash
4143 table. We also set up the .plt entries for statically linked PIC
4144 functions here. This function is called via aarch64_elf_finish in the
4148 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
4151 struct bfd_hash_table
*table
;
4152 struct elf_aarch64_link_hash_table
*htab
;
4154 htab
= elf_aarch64_hash_table (info
);
4156 for (stub_sec
= htab
->stub_bfd
->sections
;
4157 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
4161 /* Ignore non-stub sections. */
4162 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
4165 /* Allocate memory to hold the linker stubs. */
4166 size
= stub_sec
->size
;
4167 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
4168 if (stub_sec
->contents
== NULL
&& size
!= 0)
4172 bfd_putl32 (0x14000000 | (size
>> 2), stub_sec
->contents
);
4173 stub_sec
->size
+= 4;
4176 /* Build the stubs as directed by the stub hash table. */
4177 table
= &htab
->stub_hash_table
;
4178 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
4184 /* Add an entry to the code/data map for section SEC. */
4187 elfNN_aarch64_section_map_add (asection
*sec
, char type
, bfd_vma vma
)
4189 struct _aarch64_elf_section_data
*sec_data
=
4190 elf_aarch64_section_data (sec
);
4191 unsigned int newidx
;
4193 if (sec_data
->map
== NULL
)
4195 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
4196 sec_data
->mapcount
= 0;
4197 sec_data
->mapsize
= 1;
4200 newidx
= sec_data
->mapcount
++;
4202 if (sec_data
->mapcount
> sec_data
->mapsize
)
4204 sec_data
->mapsize
*= 2;
4205 sec_data
->map
= bfd_realloc_or_free
4206 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
4211 sec_data
->map
[newidx
].vma
= vma
;
4212 sec_data
->map
[newidx
].type
= type
;
4217 /* Initialise maps of insn/data for input BFDs. */
4219 bfd_elfNN_aarch64_init_maps (bfd
*abfd
)
4221 Elf_Internal_Sym
*isymbuf
;
4222 Elf_Internal_Shdr
*hdr
;
4223 unsigned int i
, localsyms
;
4225 /* Make sure that we are dealing with an AArch64 elf binary. */
4226 if (!is_aarch64_elf (abfd
))
4229 if ((abfd
->flags
& DYNAMIC
) != 0)
4232 hdr
= &elf_symtab_hdr (abfd
);
4233 localsyms
= hdr
->sh_info
;
4235 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
4236 should contain the number of local symbols, which should come before any
4237 global symbols. Mapping symbols are always local. */
4238 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
4240 /* No internal symbols read? Skip this BFD. */
4241 if (isymbuf
== NULL
)
4244 for (i
= 0; i
< localsyms
; i
++)
4246 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
4247 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
4250 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
4252 name
= bfd_elf_string_from_elf_section (abfd
,
4256 if (bfd_is_aarch64_special_symbol_name
4257 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
4258 elfNN_aarch64_section_map_add (sec
, name
[1], isym
->st_value
);
4263 /* Set option values needed during linking. */
4265 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
4266 struct bfd_link_info
*link_info
,
4268 int no_wchar_warn
, int pic_veneer
,
4269 int fix_erratum_835769
,
4270 int fix_erratum_843419
)
4272 struct elf_aarch64_link_hash_table
*globals
;
4274 globals
= elf_aarch64_hash_table (link_info
);
4275 globals
->pic_veneer
= pic_veneer
;
4276 globals
->fix_erratum_835769
= fix_erratum_835769
;
4277 globals
->fix_erratum_843419
= fix_erratum_843419
;
4278 globals
->fix_erratum_843419_adr
= TRUE
;
4280 BFD_ASSERT (is_aarch64_elf (output_bfd
));
4281 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
4282 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
4286 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
4287 struct elf_aarch64_link_hash_table
4288 *globals
, struct bfd_link_info
*info
,
4289 bfd_vma value
, bfd
*output_bfd
,
4290 bfd_boolean
*unresolved_reloc_p
)
4292 bfd_vma off
= (bfd_vma
) - 1;
4293 asection
*basegot
= globals
->root
.sgot
;
4294 bfd_boolean dyn
= globals
->root
.dynamic_sections_created
;
4298 BFD_ASSERT (basegot
!= NULL
);
4299 off
= h
->got
.offset
;
4300 BFD_ASSERT (off
!= (bfd_vma
) - 1);
4301 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
4302 || (bfd_link_pic (info
)
4303 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4304 || (ELF_ST_VISIBILITY (h
->other
)
4305 && h
->root
.type
== bfd_link_hash_undefweak
))
4307 /* This is actually a static link, or it is a -Bsymbolic link
4308 and the symbol is defined locally. We must initialize this
4309 entry in the global offset table. Since the offset must
4310 always be a multiple of 8 (4 in the case of ILP32), we use
4311 the least significant bit to record whether we have
4312 initialized it already.
4313 When doing a dynamic link, we create a .rel(a).got relocation
4314 entry to initialize the value. This is done in the
4315 finish_dynamic_symbol routine. */
4320 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
4325 *unresolved_reloc_p
= FALSE
;
4327 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
4333 /* Change R_TYPE to a more efficient access model where possible,
4334 return the new reloc type. */
4336 static bfd_reloc_code_real_type
4337 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
4338 struct elf_link_hash_entry
*h
)
4340 bfd_boolean is_local
= h
== NULL
;
4344 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4345 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4347 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4348 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
4350 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
4352 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4355 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
4357 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4358 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
4360 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
4361 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4363 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4364 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
4366 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4367 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
4369 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
4370 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
4372 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4375 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4377 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
4378 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
4380 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4381 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4382 /* Instructions with these relocations will become NOPs. */
4383 return BFD_RELOC_AARCH64_NONE
;
4393 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
4397 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4398 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4399 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4400 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4401 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4402 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4405 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4406 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4407 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4408 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
4409 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
4410 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
4413 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4414 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4415 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
4416 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4417 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
4418 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
4419 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
4420 return GOT_TLSDESC_GD
;
4422 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4423 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
4424 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
4425 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4435 aarch64_can_relax_tls (bfd
*input_bfd
,
4436 struct bfd_link_info
*info
,
4437 bfd_reloc_code_real_type r_type
,
4438 struct elf_link_hash_entry
*h
,
4439 unsigned long r_symndx
)
4441 unsigned int symbol_got_type
;
4442 unsigned int reloc_got_type
;
4444 if (! IS_AARCH64_TLS_RELAX_RELOC (r_type
))
4447 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
4448 reloc_got_type
= aarch64_reloc_got_type (r_type
);
4450 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
4453 if (bfd_link_pic (info
))
4456 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
4462 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
4465 static bfd_reloc_code_real_type
4466 aarch64_tls_transition (bfd
*input_bfd
,
4467 struct bfd_link_info
*info
,
4468 unsigned int r_type
,
4469 struct elf_link_hash_entry
*h
,
4470 unsigned long r_symndx
)
4472 bfd_reloc_code_real_type bfd_r_type
4473 = elfNN_aarch64_bfd_reloc_from_type (r_type
);
4475 if (! aarch64_can_relax_tls (input_bfd
, info
, bfd_r_type
, h
, r_symndx
))
4478 return aarch64_tls_transition_without_check (bfd_r_type
, h
);
4481 /* Return the base VMA address which should be subtracted from real addresses
4482 when resolving R_AARCH64_TLS_DTPREL relocation. */
4485 dtpoff_base (struct bfd_link_info
*info
)
4487 /* If tls_sec is NULL, we should have signalled an error already. */
4488 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
4489 return elf_hash_table (info
)->tls_sec
->vma
;
4492 /* Return the base VMA address which should be subtracted from real addresses
4493 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
4496 tpoff_base (struct bfd_link_info
*info
)
4498 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
4500 /* If tls_sec is NULL, we should have signalled an error already. */
4501 BFD_ASSERT (htab
->tls_sec
!= NULL
);
4503 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE
,
4504 htab
->tls_sec
->alignment_power
);
4505 return htab
->tls_sec
->vma
- base
;
4509 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4510 unsigned long r_symndx
)
4512 /* Calculate the address of the GOT entry for symbol
4513 referred to in h. */
4515 return &h
->got
.offset
;
4519 struct elf_aarch64_local_symbol
*l
;
4521 l
= elf_aarch64_locals (input_bfd
);
4522 return &l
[r_symndx
].got_offset
;
4527 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4528 unsigned long r_symndx
)
4531 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4536 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4537 unsigned long r_symndx
)
4540 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4545 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4546 unsigned long r_symndx
)
4549 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4555 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4556 unsigned long r_symndx
)
4558 /* Calculate the address of the GOT entry for symbol
4559 referred to in h. */
4562 struct elf_aarch64_link_hash_entry
*eh
;
4563 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
4564 return &eh
->tlsdesc_got_jump_table_offset
;
4569 struct elf_aarch64_local_symbol
*l
;
4571 l
= elf_aarch64_locals (input_bfd
);
4572 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
4577 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4578 unsigned long r_symndx
)
4581 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4586 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
4587 struct elf_link_hash_entry
*h
,
4588 unsigned long r_symndx
)
4591 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4596 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4597 unsigned long r_symndx
)
4600 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4605 /* Data for make_branch_to_erratum_835769_stub(). */
4607 struct erratum_835769_branch_to_stub_data
4609 struct bfd_link_info
*info
;
4610 asection
*output_section
;
4614 /* Helper to insert branches to erratum 835769 stubs in the right
4615 places for a particular section. */
4618 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
4621 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4622 struct erratum_835769_branch_to_stub_data
*data
;
4624 unsigned long branch_insn
= 0;
4625 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
4626 bfd_signed_vma branch_offset
;
4627 unsigned int target
;
4630 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4631 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4633 if (stub_entry
->target_section
!= data
->output_section
4634 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
4637 contents
= data
->contents
;
4638 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4639 + stub_entry
->target_section
->output_offset
4640 + stub_entry
->target_value
;
4641 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4642 + stub_entry
->stub_sec
->output_offset
4643 + stub_entry
->stub_offset
;
4644 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4646 abfd
= stub_entry
->target_section
->owner
;
4647 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4648 (*_bfd_error_handler
)
4649 (_("%B: error: Erratum 835769 stub out "
4650 "of range (input file too large)"), abfd
);
4652 target
= stub_entry
->target_value
;
4653 branch_insn
= 0x14000000;
4654 branch_offset
>>= 2;
4655 branch_offset
&= 0x3ffffff;
4656 branch_insn
|= branch_offset
;
4657 bfd_putl32 (branch_insn
, &contents
[target
]);
4664 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry
*gen_entry
,
4667 struct elf_aarch64_stub_hash_entry
*stub_entry
4668 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4669 struct erratum_835769_branch_to_stub_data
*data
4670 = (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4671 struct bfd_link_info
*info
;
4672 struct elf_aarch64_link_hash_table
*htab
;
4680 contents
= data
->contents
;
4681 section
= data
->output_section
;
4683 htab
= elf_aarch64_hash_table (info
);
4685 if (stub_entry
->target_section
!= section
4686 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
)
4689 insn
= bfd_getl32 (contents
+ stub_entry
->target_value
);
4691 stub_entry
->stub_sec
->contents
+ stub_entry
->stub_offset
);
4693 place
= (section
->output_section
->vma
+ section
->output_offset
4694 + stub_entry
->adrp_offset
);
4695 insn
= bfd_getl32 (contents
+ stub_entry
->adrp_offset
);
4697 if ((insn
& AARCH64_ADRP_OP_MASK
) != AARCH64_ADRP_OP
)
4700 bfd_signed_vma imm
=
4701 (_bfd_aarch64_sign_extend
4702 ((bfd_vma
) _bfd_aarch64_decode_adrp_imm (insn
) << 12, 33)
4705 if (htab
->fix_erratum_843419_adr
4706 && (imm
>= AARCH64_MIN_ADRP_IMM
&& imm
<= AARCH64_MAX_ADRP_IMM
))
4708 insn
= (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP
, imm
)
4709 | AARCH64_RT (insn
));
4710 bfd_putl32 (insn
, contents
+ stub_entry
->adrp_offset
);
4714 bfd_vma veneered_insn_loc
;
4715 bfd_vma veneer_entry_loc
;
4716 bfd_signed_vma branch_offset
;
4717 uint32_t branch_insn
;
4719 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4720 + stub_entry
->target_section
->output_offset
4721 + stub_entry
->target_value
;
4722 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4723 + stub_entry
->stub_sec
->output_offset
4724 + stub_entry
->stub_offset
;
4725 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4727 abfd
= stub_entry
->target_section
->owner
;
4728 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4729 (*_bfd_error_handler
)
4730 (_("%B: error: Erratum 843419 stub out "
4731 "of range (input file too large)"), abfd
);
4733 branch_insn
= 0x14000000;
4734 branch_offset
>>= 2;
4735 branch_offset
&= 0x3ffffff;
4736 branch_insn
|= branch_offset
;
4737 bfd_putl32 (branch_insn
, contents
+ stub_entry
->target_value
);
4744 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4745 struct bfd_link_info
*link_info
,
4750 struct elf_aarch64_link_hash_table
*globals
=
4751 elf_aarch64_hash_table (link_info
);
4753 if (globals
== NULL
)
4756 /* Fix code to point to erratum 835769 stubs. */
4757 if (globals
->fix_erratum_835769
)
4759 struct erratum_835769_branch_to_stub_data data
;
4761 data
.info
= link_info
;
4762 data
.output_section
= sec
;
4763 data
.contents
= contents
;
4764 bfd_hash_traverse (&globals
->stub_hash_table
,
4765 make_branch_to_erratum_835769_stub
, &data
);
4768 if (globals
->fix_erratum_843419
)
4770 struct erratum_835769_branch_to_stub_data data
;
4772 data
.info
= link_info
;
4773 data
.output_section
= sec
;
4774 data
.contents
= contents
;
4775 bfd_hash_traverse (&globals
->stub_hash_table
,
4776 _bfd_aarch64_erratum_843419_branch_to_stub
, &data
);
4782 /* Perform a relocation as part of a final link. */
4783 static bfd_reloc_status_type
4784 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
4787 asection
*input_section
,
4789 Elf_Internal_Rela
*rel
,
4791 struct bfd_link_info
*info
,
4793 struct elf_link_hash_entry
*h
,
4794 bfd_boolean
*unresolved_reloc_p
,
4795 bfd_boolean save_addend
,
4796 bfd_vma
*saved_addend
,
4797 Elf_Internal_Sym
*sym
)
4799 Elf_Internal_Shdr
*symtab_hdr
;
4800 unsigned int r_type
= howto
->type
;
4801 bfd_reloc_code_real_type bfd_r_type
4802 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
4803 bfd_reloc_code_real_type new_bfd_r_type
;
4804 unsigned long r_symndx
;
4805 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
4807 bfd_signed_vma signed_addend
;
4808 struct elf_aarch64_link_hash_table
*globals
;
4809 bfd_boolean weak_undef_p
;
4812 globals
= elf_aarch64_hash_table (info
);
4814 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
4816 BFD_ASSERT (is_aarch64_elf (input_bfd
));
4818 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4820 /* It is possible to have linker relaxations on some TLS access
4821 models. Update our information here. */
4822 new_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
, h
, r_symndx
);
4823 if (new_bfd_r_type
!= bfd_r_type
)
4825 bfd_r_type
= new_bfd_r_type
;
4826 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
4827 BFD_ASSERT (howto
!= NULL
);
4828 r_type
= howto
->type
;
4831 place
= input_section
->output_section
->vma
4832 + input_section
->output_offset
+ rel
->r_offset
;
4834 /* Get addend, accumulating the addend for consecutive relocs
4835 which refer to the same offset. */
4836 signed_addend
= saved_addend
? *saved_addend
: 0;
4837 signed_addend
+= rel
->r_addend
;
4839 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
4840 : bfd_is_und_section (sym_sec
));
4842 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
4843 it here if it is defined in a non-shared object. */
4845 && h
->type
== STT_GNU_IFUNC
4852 if ((input_section
->flags
& SEC_ALLOC
) == 0
4853 || h
->plt
.offset
== (bfd_vma
) -1)
4856 /* STT_GNU_IFUNC symbol must go through PLT. */
4857 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
4858 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
4863 if (h
->root
.root
.string
)
4864 name
= h
->root
.root
.string
;
4866 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4868 (*_bfd_error_handler
)
4869 (_("%B: relocation %s against STT_GNU_IFUNC "
4870 "symbol `%s' isn't handled by %s"), input_bfd
,
4871 howto
->name
, name
, __FUNCTION__
);
4872 bfd_set_error (bfd_error_bad_value
);
4875 case BFD_RELOC_AARCH64_NN
:
4876 if (rel
->r_addend
!= 0)
4878 if (h
->root
.root
.string
)
4879 name
= h
->root
.root
.string
;
4881 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
4883 (*_bfd_error_handler
)
4884 (_("%B: relocation %s against STT_GNU_IFUNC "
4885 "symbol `%s' has non-zero addend: %d"),
4886 input_bfd
, howto
->name
, name
, rel
->r_addend
);
4887 bfd_set_error (bfd_error_bad_value
);
4891 /* Generate dynamic relocation only when there is a
4892 non-GOT reference in a shared object. */
4893 if (bfd_link_pic (info
) && h
->non_got_ref
)
4895 Elf_Internal_Rela outrel
;
4898 /* Need a dynamic relocation to get the real function
4900 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
4904 if (outrel
.r_offset
== (bfd_vma
) -1
4905 || outrel
.r_offset
== (bfd_vma
) -2)
4908 outrel
.r_offset
+= (input_section
->output_section
->vma
4909 + input_section
->output_offset
);
4911 if (h
->dynindx
== -1
4913 || bfd_link_executable (info
))
4915 /* This symbol is resolved locally. */
4916 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
4917 outrel
.r_addend
= (h
->root
.u
.def
.value
4918 + h
->root
.u
.def
.section
->output_section
->vma
4919 + h
->root
.u
.def
.section
->output_offset
);
4923 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
4924 outrel
.r_addend
= 0;
4927 sreloc
= globals
->root
.irelifunc
;
4928 elf_append_rela (output_bfd
, sreloc
, &outrel
);
4930 /* If this reloc is against an external symbol, we
4931 do not want to fiddle with the addend. Otherwise,
4932 we need to include the symbol value so that it
4933 becomes an addend for the dynamic reloc. For an
4934 internal symbol, we have updated addend. */
4935 return bfd_reloc_ok
;
4938 case BFD_RELOC_AARCH64_CALL26
:
4939 case BFD_RELOC_AARCH64_JUMP26
:
4940 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4943 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
4945 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4946 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4947 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4948 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4949 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4950 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4951 base_got
= globals
->root
.sgot
;
4952 off
= h
->got
.offset
;
4954 if (base_got
== NULL
)
4957 if (off
== (bfd_vma
) -1)
4961 /* We can't use h->got.offset here to save state, or
4962 even just remember the offset, as finish_dynamic_symbol
4963 would use that as offset into .got. */
4965 if (globals
->root
.splt
!= NULL
)
4967 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
4968 globals
->plt_entry_size
);
4969 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
4970 base_got
= globals
->root
.sgotplt
;
4974 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
4975 off
= plt_index
* GOT_ENTRY_SIZE
;
4976 base_got
= globals
->root
.igotplt
;
4979 if (h
->dynindx
== -1
4983 /* This references the local definition. We must
4984 initialize this entry in the global offset table.
4985 Since the offset must always be a multiple of 8,
4986 we use the least significant bit to record
4987 whether we have initialized it already.
4989 When doing a dynamic link, we create a .rela.got
4990 relocation entry to initialize the value. This
4991 is done in the finish_dynamic_symbol routine. */
4996 bfd_put_NN (output_bfd
, value
,
4997 base_got
->contents
+ off
);
4998 /* Note that this is harmless as -1 | 1 still is -1. */
5002 value
= (base_got
->output_section
->vma
5003 + base_got
->output_offset
+ off
);
5006 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
5008 unresolved_reloc_p
);
5009 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5010 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
5011 addend
= (globals
->root
.sgot
->output_section
->vma
5012 + globals
->root
.sgot
->output_offset
);
5013 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5014 addend
, weak_undef_p
);
5015 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
5016 case BFD_RELOC_AARCH64_ADD_LO12
:
5017 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5024 case BFD_RELOC_AARCH64_NONE
:
5025 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5026 *unresolved_reloc_p
= FALSE
;
5027 return bfd_reloc_ok
;
5029 case BFD_RELOC_AARCH64_NN
:
5031 /* When generating a shared object or relocatable executable, these
5032 relocations are copied into the output file to be resolved at
5034 if (((bfd_link_pic (info
) == TRUE
)
5035 || globals
->root
.is_relocatable_executable
)
5036 && (input_section
->flags
& SEC_ALLOC
)
5038 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5039 || h
->root
.type
!= bfd_link_hash_undefweak
))
5041 Elf_Internal_Rela outrel
;
5043 bfd_boolean skip
, relocate
;
5046 *unresolved_reloc_p
= FALSE
;
5051 outrel
.r_addend
= signed_addend
;
5053 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
5055 if (outrel
.r_offset
== (bfd_vma
) - 1)
5057 else if (outrel
.r_offset
== (bfd_vma
) - 2)
5063 outrel
.r_offset
+= (input_section
->output_section
->vma
5064 + input_section
->output_offset
);
5067 memset (&outrel
, 0, sizeof outrel
);
5070 && (!bfd_link_pic (info
)
5071 || !SYMBOLIC_BIND (info
, h
)
5072 || !h
->def_regular
))
5073 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
5078 /* On SVR4-ish systems, the dynamic loader cannot
5079 relocate the text and data segments independently,
5080 so the symbol does not matter. */
5082 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
5083 outrel
.r_addend
+= value
;
5086 sreloc
= elf_section_data (input_section
)->sreloc
;
5087 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
5088 return bfd_reloc_notsupported
;
5090 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
5091 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
5093 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
5095 /* Sanity to check that we have previously allocated
5096 sufficient space in the relocation section for the
5097 number of relocations we actually want to emit. */
5101 /* If this reloc is against an external symbol, we do not want to
5102 fiddle with the addend. Otherwise, we need to include the symbol
5103 value so that it becomes an addend for the dynamic reloc. */
5105 return bfd_reloc_ok
;
5107 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
5108 contents
, rel
->r_offset
, value
,
5112 value
+= signed_addend
;
5115 case BFD_RELOC_AARCH64_CALL26
:
5116 case BFD_RELOC_AARCH64_JUMP26
:
5118 asection
*splt
= globals
->root
.splt
;
5119 bfd_boolean via_plt_p
=
5120 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
5122 /* A call to an undefined weak symbol is converted to a jump to
5123 the next instruction unless a PLT entry will be created.
5124 The jump to the next instruction is optimized as a NOP.
5125 Do the same for local undefined symbols. */
5126 if (weak_undef_p
&& ! via_plt_p
)
5128 bfd_putl32 (INSN_NOP
, hit_data
);
5129 return bfd_reloc_ok
;
5132 /* If the call goes through a PLT entry, make sure to
5133 check distance to the right destination address. */
5135 value
= (splt
->output_section
->vma
5136 + splt
->output_offset
+ h
->plt
.offset
);
5138 /* Check if a stub has to be inserted because the destination
5140 struct elf_aarch64_stub_hash_entry
*stub_entry
= NULL
;
5141 if (! aarch64_valid_branch_p (value
, place
))
5142 /* The target is out of reach, so redirect the branch to
5143 the local stub for this function. */
5144 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
, sym_sec
, h
,
5146 if (stub_entry
!= NULL
)
5147 value
= (stub_entry
->stub_offset
5148 + stub_entry
->stub_sec
->output_offset
5149 + stub_entry
->stub_sec
->output_section
->vma
);
5151 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5152 signed_addend
, weak_undef_p
);
5153 *unresolved_reloc_p
= FALSE
;
5156 case BFD_RELOC_AARCH64_16_PCREL
:
5157 case BFD_RELOC_AARCH64_32_PCREL
:
5158 case BFD_RELOC_AARCH64_64_PCREL
:
5159 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
5160 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5161 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
5162 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
5163 if (bfd_link_pic (info
)
5164 && (input_section
->flags
& SEC_ALLOC
) != 0
5165 && (input_section
->flags
& SEC_READONLY
) != 0
5169 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
5171 (*_bfd_error_handler
)
5172 (_("%B: relocation %s against external symbol `%s' can not be used"
5173 " when making a shared object; recompile with -fPIC"),
5174 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
5175 h
->root
.root
.string
);
5176 bfd_set_error (bfd_error_bad_value
);
5180 case BFD_RELOC_AARCH64_16
:
5182 case BFD_RELOC_AARCH64_32
:
5184 case BFD_RELOC_AARCH64_ADD_LO12
:
5185 case BFD_RELOC_AARCH64_BRANCH19
:
5186 case BFD_RELOC_AARCH64_LDST128_LO12
:
5187 case BFD_RELOC_AARCH64_LDST16_LO12
:
5188 case BFD_RELOC_AARCH64_LDST32_LO12
:
5189 case BFD_RELOC_AARCH64_LDST64_LO12
:
5190 case BFD_RELOC_AARCH64_LDST8_LO12
:
5191 case BFD_RELOC_AARCH64_MOVW_G0
:
5192 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
5193 case BFD_RELOC_AARCH64_MOVW_G0_S
:
5194 case BFD_RELOC_AARCH64_MOVW_G1
:
5195 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
5196 case BFD_RELOC_AARCH64_MOVW_G1_S
:
5197 case BFD_RELOC_AARCH64_MOVW_G2
:
5198 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
5199 case BFD_RELOC_AARCH64_MOVW_G2_S
:
5200 case BFD_RELOC_AARCH64_MOVW_G3
:
5201 case BFD_RELOC_AARCH64_TSTBR14
:
5202 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5203 signed_addend
, weak_undef_p
);
5206 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5207 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5208 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5209 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5210 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5211 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5212 if (globals
->root
.sgot
== NULL
)
5213 BFD_ASSERT (h
!= NULL
);
5218 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
, value
,
5220 unresolved_reloc_p
);
5221 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5222 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
5223 addend
= (globals
->root
.sgot
->output_section
->vma
5224 + globals
->root
.sgot
->output_offset
);
5225 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5226 addend
, weak_undef_p
);
5231 struct elf_aarch64_local_symbol
*locals
5232 = elf_aarch64_locals (input_bfd
);
5236 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
5237 (*_bfd_error_handler
)
5238 (_("%B: Local symbol descriptor table be NULL when applying "
5239 "relocation %s against local symbol"),
5240 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
5244 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5245 base_got
= globals
->root
.sgot
;
5246 bfd_vma got_entry_addr
= (base_got
->output_section
->vma
5247 + base_got
->output_offset
+ off
);
5249 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5251 bfd_put_64 (output_bfd
, value
, base_got
->contents
+ off
);
5253 if (bfd_link_pic (info
))
5256 Elf_Internal_Rela outrel
;
5258 /* For local symbol, we have done absolute relocation in static
5259 linking stageh. While for share library, we need to update
5260 the content of GOT entry according to the share objects
5261 loading base address. So we need to generate a
5262 R_AARCH64_RELATIVE reloc for dynamic linker. */
5263 s
= globals
->root
.srelgot
;
5267 outrel
.r_offset
= got_entry_addr
;
5268 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
5269 outrel
.r_addend
= value
;
5270 elf_append_rela (output_bfd
, s
, &outrel
);
5273 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5276 /* Update the relocation value to GOT entry addr as we have transformed
5277 the direct data access into indirect data access through GOT. */
5278 value
= got_entry_addr
;
5280 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5281 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
5282 addend
= base_got
->output_section
->vma
+ base_got
->output_offset
;
5284 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5285 addend
, weak_undef_p
);
5290 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5291 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5292 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5293 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5294 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5295 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5296 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5297 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5298 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5299 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5300 if (globals
->root
.sgot
== NULL
)
5301 return bfd_reloc_notsupported
;
5303 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
5304 + globals
->root
.sgot
->output_section
->vma
5305 + globals
->root
.sgot
->output_offset
);
5307 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5309 *unresolved_reloc_p
= FALSE
;
5312 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
5313 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
5314 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
5315 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
5316 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
5317 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
5318 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
5319 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
5320 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5321 signed_addend
- dtpoff_base (info
),
5325 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5326 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5327 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5328 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5329 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5330 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5331 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5332 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5333 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5334 signed_addend
- tpoff_base (info
),
5336 *unresolved_reloc_p
= FALSE
;
5339 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5340 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5341 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5342 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5343 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5344 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
5345 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5346 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5347 if (globals
->root
.sgot
== NULL
)
5348 return bfd_reloc_notsupported
;
5349 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
5350 + globals
->root
.sgotplt
->output_section
->vma
5351 + globals
->root
.sgotplt
->output_offset
5352 + globals
->sgotplt_jump_table_size
);
5354 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5356 *unresolved_reloc_p
= FALSE
;
5360 return bfd_reloc_notsupported
;
5364 *saved_addend
= value
;
5366 /* Only apply the final relocation in a sequence. */
5368 return bfd_reloc_continue
;
5370 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
5374 /* Handle TLS relaxations. Relaxing is possible for symbols that use
5375 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
5378 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
5379 is to then call final_link_relocate. Return other values in the
5382 static bfd_reloc_status_type
5383 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table
*globals
,
5384 bfd
*input_bfd
, bfd_byte
*contents
,
5385 Elf_Internal_Rela
*rel
, struct elf_link_hash_entry
*h
)
5387 bfd_boolean is_local
= h
== NULL
;
5388 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
5391 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
5393 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
5395 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5396 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5399 /* GD->LE relaxation:
5400 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
5402 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
5404 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
5405 return bfd_reloc_continue
;
5409 /* GD->IE relaxation:
5410 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
5412 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
5414 return bfd_reloc_continue
;
5417 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5421 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5424 /* Tiny TLSDESC->LE relaxation:
5425 ldr x1, :tlsdesc:var => movz x0, #:tprel_g1:var
5426 adr x0, :tlsdesc:var => movk x0, #:tprel_g0_nc:var
5430 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
5431 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
5433 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5434 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
5435 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5437 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
5438 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
+ 4);
5439 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
5440 return bfd_reloc_continue
;
5444 /* Tiny TLSDESC->IE relaxation:
5445 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
5446 adr x0, :tlsdesc:var => nop
5450 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
5451 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
5453 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5454 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5456 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
5457 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
5458 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
5459 return bfd_reloc_continue
;
5462 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5465 /* Tiny GD->LE relaxation:
5466 adr x0, :tlsgd:var => mrs x1, tpidr_el0
5467 bl __tls_get_addr => add x0, x1, #:tprel_hi12:x, lsl #12
5468 nop => add x0, x0, #:tprel_lo12_nc:x
5471 /* First kill the tls_get_addr reloc on the bl instruction. */
5472 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5474 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
5475 bfd_putl32 (0x91400020, contents
+ rel
->r_offset
+ 4);
5476 bfd_putl32 (0x91000000, contents
+ rel
->r_offset
+ 8);
5478 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5479 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
5480 rel
[1].r_offset
= rel
->r_offset
+ 8;
5482 /* Move the current relocation to the second instruction in
5485 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5486 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
5487 return bfd_reloc_continue
;
5491 /* Tiny GD->IE relaxation:
5492 adr x0, :tlsgd:var => ldr x0, :gottprel:var
5493 bl __tls_get_addr => mrs x1, tpidr_el0
5494 nop => add x0, x0, x1
5497 /* First kill the tls_get_addr reloc on the bl instruction. */
5498 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5499 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5501 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
5502 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
5503 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
5504 return bfd_reloc_continue
;
5507 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5508 return bfd_reloc_continue
;
5510 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5513 /* GD->LE relaxation:
5514 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
5516 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
5517 return bfd_reloc_continue
;
5521 /* GD->IE relaxation:
5522 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
5524 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5526 bfd_putl32 (insn
, contents
+ rel
->r_offset
);
5527 return bfd_reloc_continue
;
5530 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5533 /* GD->LE relaxation
5534 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
5535 bl __tls_get_addr => mrs x1, tpidr_el0
5536 nop => add x0, x1, x0
5539 /* First kill the tls_get_addr reloc on the bl instruction. */
5540 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5541 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5543 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
5544 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
5545 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
5546 return bfd_reloc_continue
;
5550 /* GD->IE relaxation
5551 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
5552 BL __tls_get_addr => mrs x1, tpidr_el0
5554 NOP => add x0, x1, x0
5557 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
5559 /* Remove the relocation on the BL instruction. */
5560 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5562 bfd_putl32 (0xf9400000, contents
+ rel
->r_offset
);
5564 /* We choose to fixup the BL and NOP instructions using the
5565 offset from the second relocation to allow flexibility in
5566 scheduling instructions between the ADD and BL. */
5567 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
5568 bfd_putl32 (0x8b000020, contents
+ rel
[1].r_offset
+ 4);
5569 return bfd_reloc_continue
;
5572 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5573 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5574 /* GD->IE/LE relaxation:
5575 add x0, x0, #:tlsdesc_lo12:var => nop
5578 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
5579 return bfd_reloc_ok
;
5581 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5582 /* IE->LE relaxation:
5583 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
5587 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5588 bfd_putl32 (0xd2a00000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
5590 return bfd_reloc_continue
;
5592 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5593 /* IE->LE relaxation:
5594 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
5598 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5599 bfd_putl32 (0xf2800000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
5601 return bfd_reloc_continue
;
5604 return bfd_reloc_continue
;
5607 return bfd_reloc_ok
;
5610 /* Relocate an AArch64 ELF section. */
5613 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
5614 struct bfd_link_info
*info
,
5616 asection
*input_section
,
5618 Elf_Internal_Rela
*relocs
,
5619 Elf_Internal_Sym
*local_syms
,
5620 asection
**local_sections
)
5622 Elf_Internal_Shdr
*symtab_hdr
;
5623 struct elf_link_hash_entry
**sym_hashes
;
5624 Elf_Internal_Rela
*rel
;
5625 Elf_Internal_Rela
*relend
;
5627 struct elf_aarch64_link_hash_table
*globals
;
5628 bfd_boolean save_addend
= FALSE
;
5631 globals
= elf_aarch64_hash_table (info
);
5633 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
5634 sym_hashes
= elf_sym_hashes (input_bfd
);
5637 relend
= relocs
+ input_section
->reloc_count
;
5638 for (; rel
< relend
; rel
++)
5640 unsigned int r_type
;
5641 bfd_reloc_code_real_type bfd_r_type
;
5642 bfd_reloc_code_real_type relaxed_bfd_r_type
;
5643 reloc_howto_type
*howto
;
5644 unsigned long r_symndx
;
5645 Elf_Internal_Sym
*sym
;
5647 struct elf_link_hash_entry
*h
;
5649 bfd_reloc_status_type r
;
5652 bfd_boolean unresolved_reloc
= FALSE
;
5653 char *error_message
= NULL
;
5655 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5656 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5658 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (r_type
);
5659 howto
= bfd_reloc
.howto
;
5663 (*_bfd_error_handler
)
5664 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
5665 input_bfd
, input_section
, r_type
);
5668 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
5674 if (r_symndx
< symtab_hdr
->sh_info
)
5676 sym
= local_syms
+ r_symndx
;
5677 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
5678 sec
= local_sections
[r_symndx
];
5680 /* An object file might have a reference to a local
5681 undefined symbol. This is a daft object file, but we
5682 should at least do something about it. */
5683 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
5684 && bfd_is_und_section (sec
)
5685 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
5687 if (!info
->callbacks
->undefined_symbol
5688 (info
, bfd_elf_string_from_elf_section
5689 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
5690 input_bfd
, input_section
, rel
->r_offset
, TRUE
))
5694 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
5696 /* Relocate against local STT_GNU_IFUNC symbol. */
5697 if (!bfd_link_relocatable (info
)
5698 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
5700 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
5705 /* Set STT_GNU_IFUNC symbol value. */
5706 h
->root
.u
.def
.value
= sym
->st_value
;
5707 h
->root
.u
.def
.section
= sec
;
5712 bfd_boolean warned
, ignored
;
5714 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
5715 r_symndx
, symtab_hdr
, sym_hashes
,
5717 unresolved_reloc
, warned
, ignored
);
5722 if (sec
!= NULL
&& discarded_section (sec
))
5723 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
5724 rel
, 1, relend
, howto
, 0, contents
);
5726 if (bfd_link_relocatable (info
))
5730 name
= h
->root
.root
.string
;
5733 name
= (bfd_elf_string_from_elf_section
5734 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
5735 if (name
== NULL
|| *name
== '\0')
5736 name
= bfd_section_name (input_bfd
, sec
);
5740 && r_type
!= R_AARCH64_NONE
5741 && r_type
!= R_AARCH64_NULL
5743 || h
->root
.type
== bfd_link_hash_defined
5744 || h
->root
.type
== bfd_link_hash_defweak
)
5745 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
5747 (*_bfd_error_handler
)
5748 ((sym_type
== STT_TLS
5749 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
5750 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
5752 input_section
, (long) rel
->r_offset
, howto
->name
, name
);
5755 /* We relax only if we can see that there can be a valid transition
5756 from a reloc type to another.
5757 We call elfNN_aarch64_final_link_relocate unless we're completely
5758 done, i.e., the relaxation produced the final output we want. */
5760 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
,
5762 if (relaxed_bfd_r_type
!= bfd_r_type
)
5764 bfd_r_type
= relaxed_bfd_r_type
;
5765 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
5766 BFD_ASSERT (howto
!= NULL
);
5767 r_type
= howto
->type
;
5768 r
= elfNN_aarch64_tls_relax (globals
, input_bfd
, contents
, rel
, h
);
5769 unresolved_reloc
= 0;
5772 r
= bfd_reloc_continue
;
5774 /* There may be multiple consecutive relocations for the
5775 same offset. In that case we are supposed to treat the
5776 output of each relocation as the addend for the next. */
5777 if (rel
+ 1 < relend
5778 && rel
->r_offset
== rel
[1].r_offset
5779 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
5780 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
5783 save_addend
= FALSE
;
5785 if (r
== bfd_reloc_continue
)
5786 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
5787 input_section
, contents
, rel
,
5788 relocation
, info
, sec
,
5789 h
, &unresolved_reloc
,
5790 save_addend
, &addend
, sym
);
5792 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
5794 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5795 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5796 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5797 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5798 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5799 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5800 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5802 bfd_boolean need_relocs
= FALSE
;
5807 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5808 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5811 (bfd_link_pic (info
) || indx
!= 0) &&
5813 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5814 || h
->root
.type
!= bfd_link_hash_undefweak
);
5816 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5820 Elf_Internal_Rela rela
;
5821 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
5823 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
5824 globals
->root
.sgot
->output_offset
+ off
;
5827 loc
= globals
->root
.srelgot
->contents
;
5828 loc
+= globals
->root
.srelgot
->reloc_count
++
5829 * RELOC_SIZE (htab
);
5830 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5832 bfd_reloc_code_real_type real_type
=
5833 elfNN_aarch64_bfd_reloc_from_type (r_type
);
5835 if (real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
5836 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
5837 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
)
5839 /* For local dynamic, don't generate DTPREL in any case.
5840 Initialize the DTPREL slot into zero, so we get module
5841 base address when invoke runtime TLS resolver. */
5842 bfd_put_NN (output_bfd
, 0,
5843 globals
->root
.sgot
->contents
+ off
5848 bfd_put_NN (output_bfd
,
5849 relocation
- dtpoff_base (info
),
5850 globals
->root
.sgot
->contents
+ off
5855 /* This TLS symbol is global. We emit a
5856 relocation to fixup the tls offset at load
5859 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
5862 (globals
->root
.sgot
->output_section
->vma
5863 + globals
->root
.sgot
->output_offset
+ off
5866 loc
= globals
->root
.srelgot
->contents
;
5867 loc
+= globals
->root
.srelgot
->reloc_count
++
5868 * RELOC_SIZE (globals
);
5869 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5870 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5871 globals
->root
.sgot
->contents
+ off
5877 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
5878 globals
->root
.sgot
->contents
+ off
);
5879 bfd_put_NN (output_bfd
,
5880 relocation
- dtpoff_base (info
),
5881 globals
->root
.sgot
->contents
+ off
5885 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5889 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5890 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5891 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5892 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5894 bfd_boolean need_relocs
= FALSE
;
5899 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5901 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5904 (bfd_link_pic (info
) || indx
!= 0) &&
5906 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5907 || h
->root
.type
!= bfd_link_hash_undefweak
);
5909 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5913 Elf_Internal_Rela rela
;
5916 rela
.r_addend
= relocation
- dtpoff_base (info
);
5920 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
5921 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
5922 globals
->root
.sgot
->output_offset
+ off
;
5924 loc
= globals
->root
.srelgot
->contents
;
5925 loc
+= globals
->root
.srelgot
->reloc_count
++
5926 * RELOC_SIZE (htab
);
5928 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5930 bfd_put_NN (output_bfd
, rela
.r_addend
,
5931 globals
->root
.sgot
->contents
+ off
);
5934 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
5935 globals
->root
.sgot
->contents
+ off
);
5937 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5941 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5942 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5943 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5944 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5945 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5946 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5948 bfd_boolean need_relocs
= FALSE
;
5949 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5950 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
5952 need_relocs
= (h
== NULL
5953 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5954 || h
->root
.type
!= bfd_link_hash_undefweak
);
5956 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5957 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
5962 Elf_Internal_Rela rela
;
5963 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLSDESC
));
5966 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
5967 + globals
->root
.sgotplt
->output_offset
5968 + off
+ globals
->sgotplt_jump_table_size
);
5971 rela
.r_addend
= relocation
- dtpoff_base (info
);
5973 /* Allocate the next available slot in the PLT reloc
5974 section to hold our R_AARCH64_TLSDESC, the next
5975 available slot is determined from reloc_count,
5976 which we step. But note, reloc_count was
5977 artifically moved down while allocating slots for
5978 real PLT relocs such that all of the PLT relocs
5979 will fit above the initial reloc_count and the
5980 extra stuff will fit below. */
5981 loc
= globals
->root
.srelplt
->contents
;
5982 loc
+= globals
->root
.srelplt
->reloc_count
++
5983 * RELOC_SIZE (globals
);
5985 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5987 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5988 globals
->root
.sgotplt
->contents
+ off
+
5989 globals
->sgotplt_jump_table_size
);
5990 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
5991 globals
->root
.sgotplt
->contents
+ off
+
5992 globals
->sgotplt_jump_table_size
+
5996 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
6007 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
6008 because such sections are not SEC_ALLOC and thus ld.so will
6009 not process them. */
6010 if (unresolved_reloc
6011 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
6013 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
6014 +rel
->r_offset
) != (bfd_vma
) - 1)
6016 (*_bfd_error_handler
)
6018 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
6019 input_bfd
, input_section
, (long) rel
->r_offset
, howto
->name
,
6020 h
->root
.root
.string
);
6024 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
6026 bfd_reloc_code_real_type real_r_type
6027 = elfNN_aarch64_bfd_reloc_from_type (r_type
);
6031 case bfd_reloc_overflow
:
6032 if (!(*info
->callbacks
->reloc_overflow
)
6033 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
6034 input_bfd
, input_section
, rel
->r_offset
))
6036 if (real_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
6037 || real_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
6039 (*info
->callbacks
->warning
)
6041 _("Too many GOT entries for -fpic, "
6042 "please recompile with -fPIC"),
6043 name
, input_bfd
, input_section
, rel
->r_offset
);
6048 case bfd_reloc_undefined
:
6049 if (!((*info
->callbacks
->undefined_symbol
)
6050 (info
, name
, input_bfd
, input_section
,
6051 rel
->r_offset
, TRUE
)))
6055 case bfd_reloc_outofrange
:
6056 error_message
= _("out of range");
6059 case bfd_reloc_notsupported
:
6060 error_message
= _("unsupported relocation");
6063 case bfd_reloc_dangerous
:
6064 /* error_message should already be set. */
6068 error_message
= _("unknown error");
6072 BFD_ASSERT (error_message
!= NULL
);
6073 if (!((*info
->callbacks
->reloc_dangerous
)
6074 (info
, error_message
, input_bfd
, input_section
,
6085 /* Set the right machine number. */
6088 elfNN_aarch64_object_p (bfd
*abfd
)
6091 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
6093 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
6098 /* Function to keep AArch64 specific flags in the ELF header. */
6101 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
6103 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
6108 elf_elfheader (abfd
)->e_flags
= flags
;
6109 elf_flags_init (abfd
) = TRUE
;
6115 /* Merge backend specific data from an object file to the output
6116 object file when linking. */
6119 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
6123 bfd_boolean flags_compatible
= TRUE
;
6126 /* Check if we have the same endianess. */
6127 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
6130 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
6133 /* The input BFD must have had its flags initialised. */
6134 /* The following seems bogus to me -- The flags are initialized in
6135 the assembler but I don't think an elf_flags_init field is
6136 written into the object. */
6137 /* BFD_ASSERT (elf_flags_init (ibfd)); */
6139 in_flags
= elf_elfheader (ibfd
)->e_flags
;
6140 out_flags
= elf_elfheader (obfd
)->e_flags
;
6142 if (!elf_flags_init (obfd
))
6144 /* If the input is the default architecture and had the default
6145 flags then do not bother setting the flags for the output
6146 architecture, instead allow future merges to do this. If no
6147 future merges ever set these flags then they will retain their
6148 uninitialised values, which surprise surprise, correspond
6149 to the default values. */
6150 if (bfd_get_arch_info (ibfd
)->the_default
6151 && elf_elfheader (ibfd
)->e_flags
== 0)
6154 elf_flags_init (obfd
) = TRUE
;
6155 elf_elfheader (obfd
)->e_flags
= in_flags
;
6157 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
6158 && bfd_get_arch_info (obfd
)->the_default
)
6159 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
6160 bfd_get_mach (ibfd
));
6165 /* Identical flags must be compatible. */
6166 if (in_flags
== out_flags
)
6169 /* Check to see if the input BFD actually contains any sections. If
6170 not, its flags may not have been initialised either, but it
6171 cannot actually cause any incompatiblity. Do not short-circuit
6172 dynamic objects; their section list may be emptied by
6173 elf_link_add_object_symbols.
6175 Also check to see if there are no code sections in the input.
6176 In this case there is no need to check for code specific flags.
6177 XXX - do we need to worry about floating-point format compatability
6178 in data sections ? */
6179 if (!(ibfd
->flags
& DYNAMIC
))
6181 bfd_boolean null_input_bfd
= TRUE
;
6182 bfd_boolean only_data_sections
= TRUE
;
6184 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
6186 if ((bfd_get_section_flags (ibfd
, sec
)
6187 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
6188 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
6189 only_data_sections
= FALSE
;
6191 null_input_bfd
= FALSE
;
6195 if (null_input_bfd
|| only_data_sections
)
6199 return flags_compatible
;
6202 /* Display the flags field. */
6205 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
6207 FILE *file
= (FILE *) ptr
;
6208 unsigned long flags
;
6210 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
6212 /* Print normal ELF private data. */
6213 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
6215 flags
= elf_elfheader (abfd
)->e_flags
;
6216 /* Ignore init flag - it may not be set, despite the flags field
6217 containing valid data. */
6219 /* xgettext:c-format */
6220 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
6223 fprintf (file
, _("<Unrecognised flag bits set>"));
6230 /* Update the got entry reference counts for the section being removed. */
6233 elfNN_aarch64_gc_sweep_hook (bfd
*abfd
,
6234 struct bfd_link_info
*info
,
6236 const Elf_Internal_Rela
* relocs
)
6238 struct elf_aarch64_link_hash_table
*htab
;
6239 Elf_Internal_Shdr
*symtab_hdr
;
6240 struct elf_link_hash_entry
**sym_hashes
;
6241 struct elf_aarch64_local_symbol
*locals
;
6242 const Elf_Internal_Rela
*rel
, *relend
;
6244 if (bfd_link_relocatable (info
))
6247 htab
= elf_aarch64_hash_table (info
);
6252 elf_section_data (sec
)->local_dynrel
= NULL
;
6254 symtab_hdr
= &elf_symtab_hdr (abfd
);
6255 sym_hashes
= elf_sym_hashes (abfd
);
6257 locals
= elf_aarch64_locals (abfd
);
6259 relend
= relocs
+ sec
->reloc_count
;
6260 for (rel
= relocs
; rel
< relend
; rel
++)
6262 unsigned long r_symndx
;
6263 unsigned int r_type
;
6264 struct elf_link_hash_entry
*h
= NULL
;
6266 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6268 if (r_symndx
>= symtab_hdr
->sh_info
)
6271 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
6272 while (h
->root
.type
== bfd_link_hash_indirect
6273 || h
->root
.type
== bfd_link_hash_warning
)
6274 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6278 Elf_Internal_Sym
*isym
;
6280 /* A local symbol. */
6281 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6284 /* Check relocation against local STT_GNU_IFUNC symbol. */
6286 && ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
6288 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
, FALSE
);
6296 struct elf_aarch64_link_hash_entry
*eh
;
6297 struct elf_dyn_relocs
**pp
;
6298 struct elf_dyn_relocs
*p
;
6300 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6302 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
; pp
= &p
->next
)
6305 /* Everything must go for SEC. */
6311 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6312 switch (aarch64_tls_transition (abfd
,info
, r_type
, h
,r_symndx
))
6314 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6315 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6316 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6317 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6318 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6319 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6320 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6321 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6322 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6323 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6324 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
6325 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6326 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6327 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6328 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6329 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6330 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6331 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6332 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6333 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6334 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6335 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6338 if (h
->got
.refcount
> 0)
6339 h
->got
.refcount
-= 1;
6341 if (h
->type
== STT_GNU_IFUNC
)
6343 if (h
->plt
.refcount
> 0)
6344 h
->plt
.refcount
-= 1;
6347 else if (locals
!= NULL
)
6349 if (locals
[r_symndx
].got_refcount
> 0)
6350 locals
[r_symndx
].got_refcount
-= 1;
6354 case BFD_RELOC_AARCH64_CALL26
:
6355 case BFD_RELOC_AARCH64_JUMP26
:
6356 /* If this is a local symbol then we resolve it
6357 directly without creating a PLT entry. */
6361 if (h
->plt
.refcount
> 0)
6362 h
->plt
.refcount
-= 1;
6365 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6366 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6367 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6368 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6369 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6370 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6371 case BFD_RELOC_AARCH64_MOVW_G3
:
6372 case BFD_RELOC_AARCH64_NN
:
6373 if (h
!= NULL
&& bfd_link_executable (info
))
6375 if (h
->plt
.refcount
> 0)
6376 h
->plt
.refcount
-= 1;
6388 /* Adjust a symbol defined by a dynamic object and referenced by a
6389 regular object. The current definition is in some section of the
6390 dynamic object, but we're not including those sections. We have to
6391 change the definition to something the rest of the link can
6395 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
6396 struct elf_link_hash_entry
*h
)
6398 struct elf_aarch64_link_hash_table
*htab
;
6401 /* If this is a function, put it in the procedure linkage table. We
6402 will fill in the contents of the procedure linkage table later,
6403 when we know the address of the .got section. */
6404 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
6406 if (h
->plt
.refcount
<= 0
6407 || (h
->type
!= STT_GNU_IFUNC
6408 && (SYMBOL_CALLS_LOCAL (info
, h
)
6409 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
6410 && h
->root
.type
== bfd_link_hash_undefweak
))))
6412 /* This case can occur if we saw a CALL26 reloc in
6413 an input file, but the symbol wasn't referred to
6414 by a dynamic object or all references were
6415 garbage collected. In which case we can end up
6417 h
->plt
.offset
= (bfd_vma
) - 1;
6424 /* Otherwise, reset to -1. */
6425 h
->plt
.offset
= (bfd_vma
) - 1;
6428 /* If this is a weak symbol, and there is a real definition, the
6429 processor independent code will have arranged for us to see the
6430 real definition first, and we can just use the same value. */
6431 if (h
->u
.weakdef
!= NULL
)
6433 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
6434 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
6435 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
6436 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
6437 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
6438 h
->non_got_ref
= h
->u
.weakdef
->non_got_ref
;
6442 /* If we are creating a shared library, we must presume that the
6443 only references to the symbol are via the global offset table.
6444 For such cases we need not do anything here; the relocations will
6445 be handled correctly by relocate_section. */
6446 if (bfd_link_pic (info
))
6449 /* If there are no references to this symbol that do not use the
6450 GOT, we don't need to generate a copy reloc. */
6451 if (!h
->non_got_ref
)
6454 /* If -z nocopyreloc was given, we won't generate them either. */
6455 if (info
->nocopyreloc
)
6461 /* We must allocate the symbol in our .dynbss section, which will
6462 become part of the .bss section of the executable. There will be
6463 an entry for this symbol in the .dynsym section. The dynamic
6464 object will contain position independent code, so all references
6465 from the dynamic object to this symbol will go through the global
6466 offset table. The dynamic linker will use the .dynsym entry to
6467 determine the address it must put in the global offset table, so
6468 both the dynamic object and the regular object will refer to the
6469 same memory location for the variable. */
6471 htab
= elf_aarch64_hash_table (info
);
6473 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
6474 to copy the initial value out of the dynamic object and into the
6475 runtime process image. */
6476 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
6478 htab
->srelbss
->size
+= RELOC_SIZE (htab
);
6484 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
6489 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
6491 struct elf_aarch64_local_symbol
*locals
;
6492 locals
= elf_aarch64_locals (abfd
);
6495 locals
= (struct elf_aarch64_local_symbol
*)
6496 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
6499 elf_aarch64_locals (abfd
) = locals
;
6504 /* Create the .got section to hold the global offset table. */
6507 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
6509 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
6512 struct elf_link_hash_entry
*h
;
6513 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
6515 /* This function may be called more than once. */
6516 s
= bfd_get_linker_section (abfd
, ".got");
6520 flags
= bed
->dynamic_sec_flags
;
6522 s
= bfd_make_section_anyway_with_flags (abfd
,
6523 (bed
->rela_plts_and_copies_p
6524 ? ".rela.got" : ".rel.got"),
6525 (bed
->dynamic_sec_flags
6528 || ! bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
6532 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
6534 || !bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
6537 htab
->sgot
->size
+= GOT_ENTRY_SIZE
;
6539 if (bed
->want_got_sym
)
6541 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
6542 (or .got.plt) section. We don't do this in the linker script
6543 because we don't want to define the symbol if we are not creating
6544 a global offset table. */
6545 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
6546 "_GLOBAL_OFFSET_TABLE_");
6547 elf_hash_table (info
)->hgot
= h
;
6552 if (bed
->want_got_plt
)
6554 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
6556 || !bfd_set_section_alignment (abfd
, s
,
6557 bed
->s
->log_file_align
))
6562 /* The first bit of the global offset table is the header. */
6563 s
->size
+= bed
->got_header_size
;
6568 /* Look through the relocs for a section during the first phase. */
6571 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
6572 asection
*sec
, const Elf_Internal_Rela
*relocs
)
6574 Elf_Internal_Shdr
*symtab_hdr
;
6575 struct elf_link_hash_entry
**sym_hashes
;
6576 const Elf_Internal_Rela
*rel
;
6577 const Elf_Internal_Rela
*rel_end
;
6580 struct elf_aarch64_link_hash_table
*htab
;
6582 if (bfd_link_relocatable (info
))
6585 BFD_ASSERT (is_aarch64_elf (abfd
));
6587 htab
= elf_aarch64_hash_table (info
);
6590 symtab_hdr
= &elf_symtab_hdr (abfd
);
6591 sym_hashes
= elf_sym_hashes (abfd
);
6593 rel_end
= relocs
+ sec
->reloc_count
;
6594 for (rel
= relocs
; rel
< rel_end
; rel
++)
6596 struct elf_link_hash_entry
*h
;
6597 unsigned long r_symndx
;
6598 unsigned int r_type
;
6599 bfd_reloc_code_real_type bfd_r_type
;
6600 Elf_Internal_Sym
*isym
;
6602 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6603 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6605 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
6607 (*_bfd_error_handler
) (_("%B: bad symbol index: %d"), abfd
,
6612 if (r_symndx
< symtab_hdr
->sh_info
)
6614 /* A local symbol. */
6615 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6620 /* Check relocation against local STT_GNU_IFUNC symbol. */
6621 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
6623 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
6628 /* Fake a STT_GNU_IFUNC symbol. */
6629 h
->type
= STT_GNU_IFUNC
;
6632 h
->forced_local
= 1;
6633 h
->root
.type
= bfd_link_hash_defined
;
6640 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
6641 while (h
->root
.type
== bfd_link_hash_indirect
6642 || h
->root
.type
== bfd_link_hash_warning
)
6643 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6645 /* PR15323, ref flags aren't set for references in the same
6647 h
->root
.non_ir_ref
= 1;
6650 /* Could be done earlier, if h were already available. */
6651 bfd_r_type
= aarch64_tls_transition (abfd
, info
, r_type
, h
, r_symndx
);
6655 /* Create the ifunc sections for static executables. If we
6656 never see an indirect function symbol nor we are building
6657 a static executable, those sections will be empty and
6658 won't appear in output. */
6664 case BFD_RELOC_AARCH64_ADD_LO12
:
6665 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6666 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6667 case BFD_RELOC_AARCH64_CALL26
:
6668 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6669 case BFD_RELOC_AARCH64_JUMP26
:
6670 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6671 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6672 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6673 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6674 case BFD_RELOC_AARCH64_NN
:
6675 if (htab
->root
.dynobj
== NULL
)
6676 htab
->root
.dynobj
= abfd
;
6677 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
6682 /* It is referenced by a non-shared object. */
6684 h
->root
.non_ir_ref
= 1;
6689 case BFD_RELOC_AARCH64_NN
:
6691 /* We don't need to handle relocs into sections not going into
6692 the "real" output. */
6693 if ((sec
->flags
& SEC_ALLOC
) == 0)
6698 if (!bfd_link_pic (info
))
6701 h
->plt
.refcount
+= 1;
6702 h
->pointer_equality_needed
= 1;
6705 /* No need to do anything if we're not creating a shared
6707 if (! bfd_link_pic (info
))
6711 struct elf_dyn_relocs
*p
;
6712 struct elf_dyn_relocs
**head
;
6714 /* We must copy these reloc types into the output file.
6715 Create a reloc section in dynobj and make room for
6719 if (htab
->root
.dynobj
== NULL
)
6720 htab
->root
.dynobj
= abfd
;
6722 sreloc
= _bfd_elf_make_dynamic_reloc_section
6723 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ TRUE
);
6729 /* If this is a global symbol, we count the number of
6730 relocations we need for this symbol. */
6733 struct elf_aarch64_link_hash_entry
*eh
;
6734 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6735 head
= &eh
->dyn_relocs
;
6739 /* Track dynamic relocs needed for local syms too.
6740 We really need local syms available to do this
6746 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6751 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
6755 /* Beware of type punned pointers vs strict aliasing
6757 vpp
= &(elf_section_data (s
)->local_dynrel
);
6758 head
= (struct elf_dyn_relocs
**) vpp
;
6762 if (p
== NULL
|| p
->sec
!= sec
)
6764 bfd_size_type amt
= sizeof *p
;
6765 p
= ((struct elf_dyn_relocs
*)
6766 bfd_zalloc (htab
->root
.dynobj
, amt
));
6779 /* RR: We probably want to keep a consistency check that
6780 there are no dangling GOT_PAGE relocs. */
6781 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6782 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6783 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6784 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6785 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6786 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6787 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6788 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6789 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6790 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6791 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
6792 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6793 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6794 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6795 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6796 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6797 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6798 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6799 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6800 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6801 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6802 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6805 unsigned old_got_type
;
6807 got_type
= aarch64_reloc_got_type (bfd_r_type
);
6811 h
->got
.refcount
+= 1;
6812 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
6816 struct elf_aarch64_local_symbol
*locals
;
6818 if (!elfNN_aarch64_allocate_local_symbols
6819 (abfd
, symtab_hdr
->sh_info
))
6822 locals
= elf_aarch64_locals (abfd
);
6823 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
6824 locals
[r_symndx
].got_refcount
+= 1;
6825 old_got_type
= locals
[r_symndx
].got_type
;
6828 /* If a variable is accessed with both general dynamic TLS
6829 methods, two slots may be created. */
6830 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
6831 got_type
|= old_got_type
;
6833 /* We will already have issued an error message if there
6834 is a TLS/non-TLS mismatch, based on the symbol type.
6835 So just combine any TLS types needed. */
6836 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
6837 && got_type
!= GOT_NORMAL
)
6838 got_type
|= old_got_type
;
6840 /* If the symbol is accessed by both IE and GD methods, we
6841 are able to relax. Turn off the GD flag, without
6842 messing up with any other kind of TLS types that may be
6844 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
6845 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
6847 if (old_got_type
!= got_type
)
6850 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
6853 struct elf_aarch64_local_symbol
*locals
;
6854 locals
= elf_aarch64_locals (abfd
);
6855 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
6856 locals
[r_symndx
].got_type
= got_type
;
6860 if (htab
->root
.dynobj
== NULL
)
6861 htab
->root
.dynobj
= abfd
;
6862 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
6867 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6868 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6869 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6870 case BFD_RELOC_AARCH64_MOVW_G3
:
6871 if (bfd_link_pic (info
))
6873 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6874 (*_bfd_error_handler
)
6875 (_("%B: relocation %s against `%s' can not be used when making "
6876 "a shared object; recompile with -fPIC"),
6877 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
6878 (h
) ? h
->root
.root
.string
: "a local symbol");
6879 bfd_set_error (bfd_error_bad_value
);
6883 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6884 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6885 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6886 if (h
!= NULL
&& bfd_link_executable (info
))
6888 /* If this reloc is in a read-only section, we might
6889 need a copy reloc. We can't check reliably at this
6890 stage whether the section is read-only, as input
6891 sections have not yet been mapped to output sections.
6892 Tentatively set the flag for now, and correct in
6893 adjust_dynamic_symbol. */
6895 h
->plt
.refcount
+= 1;
6896 h
->pointer_equality_needed
= 1;
6898 /* FIXME:: RR need to handle these in shared libraries
6899 and essentially bomb out as these being non-PIC
6900 relocations in shared libraries. */
6903 case BFD_RELOC_AARCH64_CALL26
:
6904 case BFD_RELOC_AARCH64_JUMP26
:
6905 /* If this is a local symbol then we resolve it
6906 directly without creating a PLT entry. */
6911 if (h
->plt
.refcount
<= 0)
6912 h
->plt
.refcount
= 1;
6914 h
->plt
.refcount
+= 1;
6925 /* Treat mapping symbols as special target symbols. */
6928 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
6931 return bfd_is_aarch64_special_symbol_name (sym
->name
,
6932 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
6935 /* This is a copy of elf_find_function () from elf.c except that
6936 AArch64 mapping symbols are ignored when looking for function names. */
6939 aarch64_elf_find_function (bfd
*abfd ATTRIBUTE_UNUSED
,
6943 const char **filename_ptr
,
6944 const char **functionname_ptr
)
6946 const char *filename
= NULL
;
6947 asymbol
*func
= NULL
;
6948 bfd_vma low_func
= 0;
6951 for (p
= symbols
; *p
!= NULL
; p
++)
6955 q
= (elf_symbol_type
*) * p
;
6957 switch (ELF_ST_TYPE (q
->internal_elf_sym
.st_info
))
6962 filename
= bfd_asymbol_name (&q
->symbol
);
6966 /* Skip mapping symbols. */
6967 if ((q
->symbol
.flags
& BSF_LOCAL
)
6968 && (bfd_is_aarch64_special_symbol_name
6969 (q
->symbol
.name
, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
)))
6972 if (bfd_get_section (&q
->symbol
) == section
6973 && q
->symbol
.value
>= low_func
&& q
->symbol
.value
<= offset
)
6975 func
= (asymbol
*) q
;
6976 low_func
= q
->symbol
.value
;
6986 *filename_ptr
= filename
;
6987 if (functionname_ptr
)
6988 *functionname_ptr
= bfd_asymbol_name (func
);
6994 /* Find the nearest line to a particular section and offset, for error
6995 reporting. This code is a duplicate of the code in elf.c, except
6996 that it uses aarch64_elf_find_function. */
6999 elfNN_aarch64_find_nearest_line (bfd
*abfd
,
7003 const char **filename_ptr
,
7004 const char **functionname_ptr
,
7005 unsigned int *line_ptr
,
7006 unsigned int *discriminator_ptr
)
7008 bfd_boolean found
= FALSE
;
7010 if (_bfd_dwarf2_find_nearest_line (abfd
, symbols
, NULL
, section
, offset
,
7011 filename_ptr
, functionname_ptr
,
7012 line_ptr
, discriminator_ptr
,
7013 dwarf_debug_sections
, 0,
7014 &elf_tdata (abfd
)->dwarf2_find_line_info
))
7016 if (!*functionname_ptr
)
7017 aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
7018 *filename_ptr
? NULL
: filename_ptr
,
7024 /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
7025 toolchain uses DWARF1. */
7027 if (!_bfd_stab_section_find_nearest_line (abfd
, symbols
, section
, offset
,
7028 &found
, filename_ptr
,
7029 functionname_ptr
, line_ptr
,
7030 &elf_tdata (abfd
)->line_info
))
7033 if (found
&& (*functionname_ptr
|| *line_ptr
))
7036 if (symbols
== NULL
)
7039 if (!aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
7040 filename_ptr
, functionname_ptr
))
7048 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
7049 const char **filename_ptr
,
7050 const char **functionname_ptr
,
7051 unsigned int *line_ptr
)
7054 found
= _bfd_dwarf2_find_inliner_info
7055 (abfd
, filename_ptr
,
7056 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
7062 elfNN_aarch64_post_process_headers (bfd
*abfd
,
7063 struct bfd_link_info
*link_info
)
7065 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
7067 i_ehdrp
= elf_elfheader (abfd
);
7068 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
7070 _bfd_elf_post_process_headers (abfd
, link_info
);
7073 static enum elf_reloc_type_class
7074 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
7075 const asection
*rel_sec ATTRIBUTE_UNUSED
,
7076 const Elf_Internal_Rela
*rela
)
7078 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
7080 case AARCH64_R (RELATIVE
):
7081 return reloc_class_relative
;
7082 case AARCH64_R (JUMP_SLOT
):
7083 return reloc_class_plt
;
7084 case AARCH64_R (COPY
):
7085 return reloc_class_copy
;
7087 return reloc_class_normal
;
7091 /* Handle an AArch64 specific section when reading an object file. This is
7092 called when bfd_section_from_shdr finds a section with an unknown
7096 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
7097 Elf_Internal_Shdr
*hdr
,
7098 const char *name
, int shindex
)
7100 /* There ought to be a place to keep ELF backend specific flags, but
7101 at the moment there isn't one. We just keep track of the
7102 sections by their name, instead. Fortunately, the ABI gives
7103 names for all the AArch64 specific sections, so we will probably get
7105 switch (hdr
->sh_type
)
7107 case SHT_AARCH64_ATTRIBUTES
:
7114 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
7120 /* A structure used to record a list of sections, independently
7121 of the next and prev fields in the asection structure. */
7122 typedef struct section_list
7125 struct section_list
*next
;
7126 struct section_list
*prev
;
7130 /* Unfortunately we need to keep a list of sections for which
7131 an _aarch64_elf_section_data structure has been allocated. This
7132 is because it is possible for functions like elfNN_aarch64_write_section
7133 to be called on a section which has had an elf_data_structure
7134 allocated for it (and so the used_by_bfd field is valid) but
7135 for which the AArch64 extended version of this structure - the
7136 _aarch64_elf_section_data structure - has not been allocated. */
7137 static section_list
*sections_with_aarch64_elf_section_data
= NULL
;
7140 record_section_with_aarch64_elf_section_data (asection
*sec
)
7142 struct section_list
*entry
;
7144 entry
= bfd_malloc (sizeof (*entry
));
7148 entry
->next
= sections_with_aarch64_elf_section_data
;
7150 if (entry
->next
!= NULL
)
7151 entry
->next
->prev
= entry
;
7152 sections_with_aarch64_elf_section_data
= entry
;
7155 static struct section_list
*
7156 find_aarch64_elf_section_entry (asection
*sec
)
7158 struct section_list
*entry
;
7159 static struct section_list
*last_entry
= NULL
;
7161 /* This is a short cut for the typical case where the sections are added
7162 to the sections_with_aarch64_elf_section_data list in forward order and
7163 then looked up here in backwards order. This makes a real difference
7164 to the ld-srec/sec64k.exp linker test. */
7165 entry
= sections_with_aarch64_elf_section_data
;
7166 if (last_entry
!= NULL
)
7168 if (last_entry
->sec
== sec
)
7170 else if (last_entry
->next
!= NULL
&& last_entry
->next
->sec
== sec
)
7171 entry
= last_entry
->next
;
7174 for (; entry
; entry
= entry
->next
)
7175 if (entry
->sec
== sec
)
7179 /* Record the entry prior to this one - it is the entry we are
7180 most likely to want to locate next time. Also this way if we
7181 have been called from
7182 unrecord_section_with_aarch64_elf_section_data () we will not
7183 be caching a pointer that is about to be freed. */
7184 last_entry
= entry
->prev
;
7190 unrecord_section_with_aarch64_elf_section_data (asection
*sec
)
7192 struct section_list
*entry
;
7194 entry
= find_aarch64_elf_section_entry (sec
);
7198 if (entry
->prev
!= NULL
)
7199 entry
->prev
->next
= entry
->next
;
7200 if (entry
->next
!= NULL
)
7201 entry
->next
->prev
= entry
->prev
;
7202 if (entry
== sections_with_aarch64_elf_section_data
)
7203 sections_with_aarch64_elf_section_data
= entry
->next
;
7212 struct bfd_link_info
*info
;
7215 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
7216 asection
*, struct elf_link_hash_entry
*);
7217 } output_arch_syminfo
;
7219 enum map_symbol_type
7226 /* Output a single mapping symbol. */
7229 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
7230 enum map_symbol_type type
, bfd_vma offset
)
7232 static const char *names
[2] = { "$x", "$d" };
7233 Elf_Internal_Sym sym
;
7235 sym
.st_value
= (osi
->sec
->output_section
->vma
7236 + osi
->sec
->output_offset
+ offset
);
7239 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
7240 sym
.st_shndx
= osi
->sec_shndx
;
7241 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
7246 /* Output mapping symbols for PLT entries associated with H. */
7249 elfNN_aarch64_output_plt_map (struct elf_link_hash_entry
*h
, void *inf
)
7251 output_arch_syminfo
*osi
= (output_arch_syminfo
*) inf
;
7254 if (h
->root
.type
== bfd_link_hash_indirect
)
7257 if (h
->root
.type
== bfd_link_hash_warning
)
7258 /* When warning symbols are created, they **replace** the "real"
7259 entry in the hash table, thus we never get to see the real
7260 symbol in a hash traversal. So look at it now. */
7261 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7263 if (h
->plt
.offset
== (bfd_vma
) - 1)
7266 addr
= h
->plt
.offset
;
7269 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7276 /* Output a single local symbol for a generated stub. */
7279 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
7280 bfd_vma offset
, bfd_vma size
)
7282 Elf_Internal_Sym sym
;
7284 sym
.st_value
= (osi
->sec
->output_section
->vma
7285 + osi
->sec
->output_offset
+ offset
);
7288 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
7289 sym
.st_shndx
= osi
->sec_shndx
;
7290 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
7294 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
7296 struct elf_aarch64_stub_hash_entry
*stub_entry
;
7300 output_arch_syminfo
*osi
;
7302 /* Massage our args to the form they really have. */
7303 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
7304 osi
= (output_arch_syminfo
*) in_arg
;
7306 stub_sec
= stub_entry
->stub_sec
;
7308 /* Ensure this stub is attached to the current section being
7310 if (stub_sec
!= osi
->sec
)
7313 addr
= (bfd_vma
) stub_entry
->stub_offset
;
7315 stub_name
= stub_entry
->output_name
;
7317 switch (stub_entry
->stub_type
)
7319 case aarch64_stub_adrp_branch
:
7320 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7321 sizeof (aarch64_adrp_branch_stub
)))
7323 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7326 case aarch64_stub_long_branch
:
7327 if (!elfNN_aarch64_output_stub_sym
7328 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
7330 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7332 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
7335 case aarch64_stub_erratum_835769_veneer
:
7336 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7337 sizeof (aarch64_erratum_835769_stub
)))
7339 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7342 case aarch64_stub_erratum_843419_veneer
:
7343 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7344 sizeof (aarch64_erratum_843419_stub
)))
7346 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7357 /* Output mapping symbols for linker generated sections. */
7360 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
7361 struct bfd_link_info
*info
,
7363 int (*func
) (void *, const char *,
7366 struct elf_link_hash_entry
7369 output_arch_syminfo osi
;
7370 struct elf_aarch64_link_hash_table
*htab
;
7372 htab
= elf_aarch64_hash_table (info
);
7378 /* Long calls stubs. */
7379 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
7383 for (stub_sec
= htab
->stub_bfd
->sections
;
7384 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
7386 /* Ignore non-stub sections. */
7387 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
7392 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
7393 (output_bfd
, osi
.sec
->output_section
);
7395 /* The first instruction in a stub is always a branch. */
7396 if (!elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0))
7399 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
7404 /* Finally, output mapping symbols for the PLT. */
7405 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
7408 /* For now live without mapping symbols for the plt. */
7409 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
7410 (output_bfd
, htab
->root
.splt
->output_section
);
7411 osi
.sec
= htab
->root
.splt
;
7413 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_output_plt_map
,
7420 /* Allocate target specific section data. */
7423 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
7425 if (!sec
->used_by_bfd
)
7427 _aarch64_elf_section_data
*sdata
;
7428 bfd_size_type amt
= sizeof (*sdata
);
7430 sdata
= bfd_zalloc (abfd
, amt
);
7433 sec
->used_by_bfd
= sdata
;
7436 record_section_with_aarch64_elf_section_data (sec
);
7438 return _bfd_elf_new_section_hook (abfd
, sec
);
7443 unrecord_section_via_map_over_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
7445 void *ignore ATTRIBUTE_UNUSED
)
7447 unrecord_section_with_aarch64_elf_section_data (sec
);
7451 elfNN_aarch64_close_and_cleanup (bfd
*abfd
)
7454 bfd_map_over_sections (abfd
,
7455 unrecord_section_via_map_over_sections
, NULL
);
7457 return _bfd_elf_close_and_cleanup (abfd
);
7461 elfNN_aarch64_bfd_free_cached_info (bfd
*abfd
)
7464 bfd_map_over_sections (abfd
,
7465 unrecord_section_via_map_over_sections
, NULL
);
7467 return _bfd_free_cached_info (abfd
);
7470 /* Create dynamic sections. This is different from the ARM backend in that
7471 the got, plt, gotplt and their relocation sections are all created in the
7472 standard part of the bfd elf backend. */
7475 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
7476 struct bfd_link_info
*info
)
7478 struct elf_aarch64_link_hash_table
*htab
;
7480 /* We need to create .got section. */
7481 if (!aarch64_elf_create_got_section (dynobj
, info
))
7484 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
7487 htab
= elf_aarch64_hash_table (info
);
7488 htab
->sdynbss
= bfd_get_linker_section (dynobj
, ".dynbss");
7489 if (!bfd_link_pic (info
))
7490 htab
->srelbss
= bfd_get_linker_section (dynobj
, ".rela.bss");
7492 if (!htab
->sdynbss
|| (!bfd_link_pic (info
) && !htab
->srelbss
))
7499 /* Allocate space in .plt, .got and associated reloc sections for
7503 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
7505 struct bfd_link_info
*info
;
7506 struct elf_aarch64_link_hash_table
*htab
;
7507 struct elf_aarch64_link_hash_entry
*eh
;
7508 struct elf_dyn_relocs
*p
;
7510 /* An example of a bfd_link_hash_indirect symbol is versioned
7511 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7512 -> __gxx_personality_v0(bfd_link_hash_defined)
7514 There is no need to process bfd_link_hash_indirect symbols here
7515 because we will also be presented with the concrete instance of
7516 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7517 called to copy all relevant data from the generic to the concrete
7520 if (h
->root
.type
== bfd_link_hash_indirect
)
7523 if (h
->root
.type
== bfd_link_hash_warning
)
7524 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7526 info
= (struct bfd_link_info
*) inf
;
7527 htab
= elf_aarch64_hash_table (info
);
7529 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7530 here if it is defined and referenced in a non-shared object. */
7531 if (h
->type
== STT_GNU_IFUNC
7534 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
7536 /* Make sure this symbol is output as a dynamic symbol.
7537 Undefined weak syms won't yet be marked as dynamic. */
7538 if (h
->dynindx
== -1 && !h
->forced_local
)
7540 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
7544 if (bfd_link_pic (info
) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
7546 asection
*s
= htab
->root
.splt
;
7548 /* If this is the first .plt entry, make room for the special
7551 s
->size
+= htab
->plt_header_size
;
7553 h
->plt
.offset
= s
->size
;
7555 /* If this symbol is not defined in a regular file, and we are
7556 not generating a shared library, then set the symbol to this
7557 location in the .plt. This is required to make function
7558 pointers compare as equal between the normal executable and
7559 the shared library. */
7560 if (!bfd_link_pic (info
) && !h
->def_regular
)
7562 h
->root
.u
.def
.section
= s
;
7563 h
->root
.u
.def
.value
= h
->plt
.offset
;
7566 /* Make room for this entry. For now we only create the
7567 small model PLT entries. We later need to find a way
7568 of relaxing into these from the large model PLT entries. */
7569 s
->size
+= PLT_SMALL_ENTRY_SIZE
;
7571 /* We also need to make an entry in the .got.plt section, which
7572 will be placed in the .got section by the linker script. */
7573 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
;
7575 /* We also need to make an entry in the .rela.plt section. */
7576 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7578 /* We need to ensure that all GOT entries that serve the PLT
7579 are consecutive with the special GOT slots [0] [1] and
7580 [2]. Any addtional relocations, such as
7581 R_AARCH64_TLSDESC, must be placed after the PLT related
7582 entries. We abuse the reloc_count such that during
7583 sizing we adjust reloc_count to indicate the number of
7584 PLT related reserved entries. In subsequent phases when
7585 filling in the contents of the reloc entries, PLT related
7586 entries are placed by computing their PLT index (0
7587 .. reloc_count). While other none PLT relocs are placed
7588 at the slot indicated by reloc_count and reloc_count is
7591 htab
->root
.srelplt
->reloc_count
++;
7595 h
->plt
.offset
= (bfd_vma
) - 1;
7601 h
->plt
.offset
= (bfd_vma
) - 1;
7605 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7606 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
7608 if (h
->got
.refcount
> 0)
7611 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
7613 h
->got
.offset
= (bfd_vma
) - 1;
7615 dyn
= htab
->root
.dynamic_sections_created
;
7617 /* Make sure this symbol is output as a dynamic symbol.
7618 Undefined weak syms won't yet be marked as dynamic. */
7619 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
)
7621 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
7625 if (got_type
== GOT_UNKNOWN
)
7628 else if (got_type
== GOT_NORMAL
)
7630 h
->got
.offset
= htab
->root
.sgot
->size
;
7631 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7632 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7633 || h
->root
.type
!= bfd_link_hash_undefweak
)
7634 && (bfd_link_pic (info
)
7635 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
7637 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7643 if (got_type
& GOT_TLSDESC_GD
)
7645 eh
->tlsdesc_got_jump_table_offset
=
7646 (htab
->root
.sgotplt
->size
7647 - aarch64_compute_jump_table_size (htab
));
7648 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
7649 h
->got
.offset
= (bfd_vma
) - 2;
7652 if (got_type
& GOT_TLS_GD
)
7654 h
->got
.offset
= htab
->root
.sgot
->size
;
7655 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
7658 if (got_type
& GOT_TLS_IE
)
7660 h
->got
.offset
= htab
->root
.sgot
->size
;
7661 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7664 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
7665 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7666 || h
->root
.type
!= bfd_link_hash_undefweak
)
7667 && (bfd_link_pic (info
)
7669 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
7671 if (got_type
& GOT_TLSDESC_GD
)
7673 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7674 /* Note reloc_count not incremented here! We have
7675 already adjusted reloc_count for this relocation
7678 /* TLSDESC PLT is now needed, but not yet determined. */
7679 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
7682 if (got_type
& GOT_TLS_GD
)
7683 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
7685 if (got_type
& GOT_TLS_IE
)
7686 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7692 h
->got
.offset
= (bfd_vma
) - 1;
7695 if (eh
->dyn_relocs
== NULL
)
7698 /* In the shared -Bsymbolic case, discard space allocated for
7699 dynamic pc-relative relocs against symbols which turn out to be
7700 defined in regular objects. For the normal shared case, discard
7701 space for pc-relative relocs that have become local due to symbol
7702 visibility changes. */
7704 if (bfd_link_pic (info
))
7706 /* Relocs that use pc_count are those that appear on a call
7707 insn, or certain REL relocs that can generated via assembly.
7708 We want calls to protected symbols to resolve directly to the
7709 function rather than going via the plt. If people want
7710 function pointer comparisons to work as expected then they
7711 should avoid writing weird assembly. */
7712 if (SYMBOL_CALLS_LOCAL (info
, h
))
7714 struct elf_dyn_relocs
**pp
;
7716 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
;)
7718 p
->count
-= p
->pc_count
;
7727 /* Also discard relocs on undefined weak syms with non-default
7729 if (eh
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
7731 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
7732 eh
->dyn_relocs
= NULL
;
7734 /* Make sure undefined weak symbols are output as a dynamic
7736 else if (h
->dynindx
== -1
7738 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
7743 else if (ELIMINATE_COPY_RELOCS
)
7745 /* For the non-shared case, discard space for relocs against
7746 symbols which turn out to need copy relocs or are not
7752 || (htab
->root
.dynamic_sections_created
7753 && (h
->root
.type
== bfd_link_hash_undefweak
7754 || h
->root
.type
== bfd_link_hash_undefined
))))
7756 /* Make sure this symbol is output as a dynamic symbol.
7757 Undefined weak syms won't yet be marked as dynamic. */
7758 if (h
->dynindx
== -1
7760 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
7763 /* If that succeeded, we know we'll be keeping all the
7765 if (h
->dynindx
!= -1)
7769 eh
->dyn_relocs
= NULL
;
7774 /* Finally, allocate space. */
7775 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
7779 sreloc
= elf_section_data (p
->sec
)->sreloc
;
7781 BFD_ASSERT (sreloc
!= NULL
);
7783 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
7789 /* Allocate space in .plt, .got and associated reloc sections for
7790 ifunc dynamic relocs. */
7793 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
7796 struct bfd_link_info
*info
;
7797 struct elf_aarch64_link_hash_table
*htab
;
7798 struct elf_aarch64_link_hash_entry
*eh
;
7800 /* An example of a bfd_link_hash_indirect symbol is versioned
7801 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7802 -> __gxx_personality_v0(bfd_link_hash_defined)
7804 There is no need to process bfd_link_hash_indirect symbols here
7805 because we will also be presented with the concrete instance of
7806 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7807 called to copy all relevant data from the generic to the concrete
7810 if (h
->root
.type
== bfd_link_hash_indirect
)
7813 if (h
->root
.type
== bfd_link_hash_warning
)
7814 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7816 info
= (struct bfd_link_info
*) inf
;
7817 htab
= elf_aarch64_hash_table (info
);
7819 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7821 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7822 here if it is defined and referenced in a non-shared object. */
7823 if (h
->type
== STT_GNU_IFUNC
7825 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
7827 htab
->plt_entry_size
,
7828 htab
->plt_header_size
,
7833 /* Allocate space in .plt, .got and associated reloc sections for
7834 local dynamic relocs. */
7837 elfNN_aarch64_allocate_local_dynrelocs (void **slot
, void *inf
)
7839 struct elf_link_hash_entry
*h
7840 = (struct elf_link_hash_entry
*) *slot
;
7842 if (h
->type
!= STT_GNU_IFUNC
7846 || h
->root
.type
!= bfd_link_hash_defined
)
7849 return elfNN_aarch64_allocate_dynrelocs (h
, inf
);
7852 /* Allocate space in .plt, .got and associated reloc sections for
7853 local ifunc dynamic relocs. */
7856 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
7858 struct elf_link_hash_entry
*h
7859 = (struct elf_link_hash_entry
*) *slot
;
7861 if (h
->type
!= STT_GNU_IFUNC
7865 || h
->root
.type
!= bfd_link_hash_defined
)
7868 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
7871 /* Find any dynamic relocs that apply to read-only sections. */
7874 aarch64_readonly_dynrelocs (struct elf_link_hash_entry
* h
, void * inf
)
7876 struct elf_aarch64_link_hash_entry
* eh
;
7877 struct elf_dyn_relocs
* p
;
7879 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7880 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
7882 asection
*s
= p
->sec
;
7884 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
7886 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
7888 info
->flags
|= DF_TEXTREL
;
7890 /* Not an error, just cut short the traversal. */
7897 /* This is the most important function of all . Innocuosly named
7900 elfNN_aarch64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
7901 struct bfd_link_info
*info
)
7903 struct elf_aarch64_link_hash_table
*htab
;
7909 htab
= elf_aarch64_hash_table ((info
));
7910 dynobj
= htab
->root
.dynobj
;
7912 BFD_ASSERT (dynobj
!= NULL
);
7914 if (htab
->root
.dynamic_sections_created
)
7916 if (bfd_link_executable (info
))
7918 s
= bfd_get_linker_section (dynobj
, ".interp");
7921 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
7922 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
7926 /* Set up .got offsets for local syms, and space for local dynamic
7928 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
7930 struct elf_aarch64_local_symbol
*locals
= NULL
;
7931 Elf_Internal_Shdr
*symtab_hdr
;
7935 if (!is_aarch64_elf (ibfd
))
7938 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
7940 struct elf_dyn_relocs
*p
;
7942 for (p
= (struct elf_dyn_relocs
*)
7943 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
7945 if (!bfd_is_abs_section (p
->sec
)
7946 && bfd_is_abs_section (p
->sec
->output_section
))
7948 /* Input section has been discarded, either because
7949 it is a copy of a linkonce section or due to
7950 linker script /DISCARD/, so we'll be discarding
7953 else if (p
->count
!= 0)
7955 srel
= elf_section_data (p
->sec
)->sreloc
;
7956 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
7957 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
7958 info
->flags
|= DF_TEXTREL
;
7963 locals
= elf_aarch64_locals (ibfd
);
7967 symtab_hdr
= &elf_symtab_hdr (ibfd
);
7968 srel
= htab
->root
.srelgot
;
7969 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
7971 locals
[i
].got_offset
= (bfd_vma
) - 1;
7972 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
7973 if (locals
[i
].got_refcount
> 0)
7975 unsigned got_type
= locals
[i
].got_type
;
7976 if (got_type
& GOT_TLSDESC_GD
)
7978 locals
[i
].tlsdesc_got_jump_table_offset
=
7979 (htab
->root
.sgotplt
->size
7980 - aarch64_compute_jump_table_size (htab
));
7981 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
7982 locals
[i
].got_offset
= (bfd_vma
) - 2;
7985 if (got_type
& GOT_TLS_GD
)
7987 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
7988 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
7991 if (got_type
& GOT_TLS_IE
7992 || got_type
& GOT_NORMAL
)
7994 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
7995 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7998 if (got_type
== GOT_UNKNOWN
)
8002 if (bfd_link_pic (info
))
8004 if (got_type
& GOT_TLSDESC_GD
)
8006 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
8007 /* Note RELOC_COUNT not incremented here! */
8008 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
8011 if (got_type
& GOT_TLS_GD
)
8012 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
8014 if (got_type
& GOT_TLS_IE
8015 || got_type
& GOT_NORMAL
)
8016 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
8021 locals
[i
].got_refcount
= (bfd_vma
) - 1;
8027 /* Allocate global sym .plt and .got entries, and space for global
8028 sym dynamic relocs. */
8029 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
8032 /* Allocate global ifunc sym .plt and .got entries, and space for global
8033 ifunc sym dynamic relocs. */
8034 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
8037 /* Allocate .plt and .got entries, and space for local symbols. */
8038 htab_traverse (htab
->loc_hash_table
,
8039 elfNN_aarch64_allocate_local_dynrelocs
,
8042 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
8043 htab_traverse (htab
->loc_hash_table
,
8044 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
8047 /* For every jump slot reserved in the sgotplt, reloc_count is
8048 incremented. However, when we reserve space for TLS descriptors,
8049 it's not incremented, so in order to compute the space reserved
8050 for them, it suffices to multiply the reloc count by the jump
8053 if (htab
->root
.srelplt
)
8054 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
8056 if (htab
->tlsdesc_plt
)
8058 if (htab
->root
.splt
->size
== 0)
8059 htab
->root
.splt
->size
+= PLT_ENTRY_SIZE
;
8061 htab
->tlsdesc_plt
= htab
->root
.splt
->size
;
8062 htab
->root
.splt
->size
+= PLT_TLSDESC_ENTRY_SIZE
;
8064 /* If we're not using lazy TLS relocations, don't generate the
8065 GOT entry required. */
8066 if (!(info
->flags
& DF_BIND_NOW
))
8068 htab
->dt_tlsdesc_got
= htab
->root
.sgot
->size
;
8069 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
8073 /* Init mapping symbols information to use later to distingush between
8074 code and data while scanning for errata. */
8075 if (htab
->fix_erratum_835769
|| htab
->fix_erratum_843419
)
8076 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
8078 if (!is_aarch64_elf (ibfd
))
8080 bfd_elfNN_aarch64_init_maps (ibfd
);
8083 /* We now have determined the sizes of the various dynamic sections.
8084 Allocate memory for them. */
8086 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
8088 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
8091 if (s
== htab
->root
.splt
8092 || s
== htab
->root
.sgot
8093 || s
== htab
->root
.sgotplt
8094 || s
== htab
->root
.iplt
8095 || s
== htab
->root
.igotplt
|| s
== htab
->sdynbss
)
8097 /* Strip this section if we don't need it; see the
8100 else if (CONST_STRNEQ (bfd_get_section_name (dynobj
, s
), ".rela"))
8102 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
8105 /* We use the reloc_count field as a counter if we need
8106 to copy relocs into the output file. */
8107 if (s
!= htab
->root
.srelplt
)
8112 /* It's not one of our sections, so don't allocate space. */
8118 /* If we don't need this section, strip it from the
8119 output file. This is mostly to handle .rela.bss and
8120 .rela.plt. We must create both sections in
8121 create_dynamic_sections, because they must be created
8122 before the linker maps input sections to output
8123 sections. The linker does that before
8124 adjust_dynamic_symbol is called, and it is that
8125 function which decides whether anything needs to go
8126 into these sections. */
8128 s
->flags
|= SEC_EXCLUDE
;
8132 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
8135 /* Allocate memory for the section contents. We use bfd_zalloc
8136 here in case unused entries are not reclaimed before the
8137 section's contents are written out. This should not happen,
8138 but this way if it does, we get a R_AARCH64_NONE reloc instead
8140 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
8141 if (s
->contents
== NULL
)
8145 if (htab
->root
.dynamic_sections_created
)
8147 /* Add some entries to the .dynamic section. We fill in the
8148 values later, in elfNN_aarch64_finish_dynamic_sections, but we
8149 must add the entries now so that we get the correct size for
8150 the .dynamic section. The DT_DEBUG entry is filled in by the
8151 dynamic linker and used by the debugger. */
8152 #define add_dynamic_entry(TAG, VAL) \
8153 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
8155 if (bfd_link_executable (info
))
8157 if (!add_dynamic_entry (DT_DEBUG
, 0))
8161 if (htab
->root
.splt
->size
!= 0)
8163 if (!add_dynamic_entry (DT_PLTGOT
, 0)
8164 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
8165 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
8166 || !add_dynamic_entry (DT_JMPREL
, 0))
8169 if (htab
->tlsdesc_plt
8170 && (!add_dynamic_entry (DT_TLSDESC_PLT
, 0)
8171 || !add_dynamic_entry (DT_TLSDESC_GOT
, 0)))
8177 if (!add_dynamic_entry (DT_RELA
, 0)
8178 || !add_dynamic_entry (DT_RELASZ
, 0)
8179 || !add_dynamic_entry (DT_RELAENT
, RELOC_SIZE (htab
)))
8182 /* If any dynamic relocs apply to a read-only section,
8183 then we need a DT_TEXTREL entry. */
8184 if ((info
->flags
& DF_TEXTREL
) == 0)
8185 elf_link_hash_traverse (& htab
->root
, aarch64_readonly_dynrelocs
,
8188 if ((info
->flags
& DF_TEXTREL
) != 0)
8190 if (!add_dynamic_entry (DT_TEXTREL
, 0))
8195 #undef add_dynamic_entry
8201 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
8202 bfd_reloc_code_real_type r_type
,
8203 bfd_byte
*plt_entry
, bfd_vma value
)
8205 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
8207 _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
8211 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
8212 struct elf_aarch64_link_hash_table
8213 *htab
, bfd
*output_bfd
,
8214 struct bfd_link_info
*info
)
8216 bfd_byte
*plt_entry
;
8219 bfd_vma gotplt_entry_address
;
8220 bfd_vma plt_entry_address
;
8221 Elf_Internal_Rela rela
;
8223 asection
*plt
, *gotplt
, *relplt
;
8225 /* When building a static executable, use .iplt, .igot.plt and
8226 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8227 if (htab
->root
.splt
!= NULL
)
8229 plt
= htab
->root
.splt
;
8230 gotplt
= htab
->root
.sgotplt
;
8231 relplt
= htab
->root
.srelplt
;
8235 plt
= htab
->root
.iplt
;
8236 gotplt
= htab
->root
.igotplt
;
8237 relplt
= htab
->root
.irelplt
;
8240 /* Get the index in the procedure linkage table which
8241 corresponds to this symbol. This is the index of this symbol
8242 in all the symbols for which we are making plt entries. The
8243 first entry in the procedure linkage table is reserved.
8245 Get the offset into the .got table of the entry that
8246 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
8247 bytes. The first three are reserved for the dynamic linker.
8249 For static executables, we don't reserve anything. */
8251 if (plt
== htab
->root
.splt
)
8253 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
8254 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
8258 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
8259 got_offset
= plt_index
* GOT_ENTRY_SIZE
;
8262 plt_entry
= plt
->contents
+ h
->plt
.offset
;
8263 plt_entry_address
= plt
->output_section
->vma
8264 + plt
->output_offset
+ h
->plt
.offset
;
8265 gotplt_entry_address
= gotplt
->output_section
->vma
+
8266 gotplt
->output_offset
+ got_offset
;
8268 /* Copy in the boiler-plate for the PLTn entry. */
8269 memcpy (plt_entry
, elfNN_aarch64_small_plt_entry
, PLT_SMALL_ENTRY_SIZE
);
8271 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8272 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8273 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8275 PG (gotplt_entry_address
) -
8276 PG (plt_entry_address
));
8278 /* Fill in the lo12 bits for the load from the pltgot. */
8279 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
8281 PG_OFFSET (gotplt_entry_address
));
8283 /* Fill in the lo12 bits for the add from the pltgot entry. */
8284 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
8286 PG_OFFSET (gotplt_entry_address
));
8288 /* All the GOTPLT Entries are essentially initialized to PLT0. */
8289 bfd_put_NN (output_bfd
,
8290 plt
->output_section
->vma
+ plt
->output_offset
,
8291 gotplt
->contents
+ got_offset
);
8293 rela
.r_offset
= gotplt_entry_address
;
8295 if (h
->dynindx
== -1
8296 || ((bfd_link_executable (info
)
8297 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
8299 && h
->type
== STT_GNU_IFUNC
))
8301 /* If an STT_GNU_IFUNC symbol is locally defined, generate
8302 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
8303 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
8304 rela
.r_addend
= (h
->root
.u
.def
.value
8305 + h
->root
.u
.def
.section
->output_section
->vma
8306 + h
->root
.u
.def
.section
->output_offset
);
8310 /* Fill in the entry in the .rela.plt section. */
8311 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
));
8315 /* Compute the relocation entry to used based on PLT index and do
8316 not adjust reloc_count. The reloc_count has already been adjusted
8317 to account for this entry. */
8318 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
8319 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8322 /* Size sections even though they're not dynamic. We use it to setup
8323 _TLS_MODULE_BASE_, if needed. */
8326 elfNN_aarch64_always_size_sections (bfd
*output_bfd
,
8327 struct bfd_link_info
*info
)
8331 if (bfd_link_relocatable (info
))
8334 tls_sec
= elf_hash_table (info
)->tls_sec
;
8338 struct elf_link_hash_entry
*tlsbase
;
8340 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
8341 "_TLS_MODULE_BASE_", TRUE
, TRUE
, FALSE
);
8345 struct bfd_link_hash_entry
*h
= NULL
;
8346 const struct elf_backend_data
*bed
=
8347 get_elf_backend_data (output_bfd
);
8349 if (!(_bfd_generic_link_add_one_symbol
8350 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
8351 tls_sec
, 0, NULL
, FALSE
, bed
->collect
, &h
)))
8354 tlsbase
->type
= STT_TLS
;
8355 tlsbase
= (struct elf_link_hash_entry
*) h
;
8356 tlsbase
->def_regular
= 1;
8357 tlsbase
->other
= STV_HIDDEN
;
8358 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, TRUE
);
8365 /* Finish up dynamic symbol handling. We set the contents of various
8366 dynamic sections here. */
8368 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
8369 struct bfd_link_info
*info
,
8370 struct elf_link_hash_entry
*h
,
8371 Elf_Internal_Sym
*sym
)
8373 struct elf_aarch64_link_hash_table
*htab
;
8374 htab
= elf_aarch64_hash_table (info
);
8376 if (h
->plt
.offset
!= (bfd_vma
) - 1)
8378 asection
*plt
, *gotplt
, *relplt
;
8380 /* This symbol has an entry in the procedure linkage table. Set
8383 /* When building a static executable, use .iplt, .igot.plt and
8384 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8385 if (htab
->root
.splt
!= NULL
)
8387 plt
= htab
->root
.splt
;
8388 gotplt
= htab
->root
.sgotplt
;
8389 relplt
= htab
->root
.srelplt
;
8393 plt
= htab
->root
.iplt
;
8394 gotplt
= htab
->root
.igotplt
;
8395 relplt
= htab
->root
.irelplt
;
8398 /* This symbol has an entry in the procedure linkage table. Set
8400 if ((h
->dynindx
== -1
8401 && !((h
->forced_local
|| bfd_link_executable (info
))
8403 && h
->type
== STT_GNU_IFUNC
))
8409 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
8410 if (!h
->def_regular
)
8412 /* Mark the symbol as undefined, rather than as defined in
8413 the .plt section. */
8414 sym
->st_shndx
= SHN_UNDEF
;
8415 /* If the symbol is weak we need to clear the value.
8416 Otherwise, the PLT entry would provide a definition for
8417 the symbol even if the symbol wasn't defined anywhere,
8418 and so the symbol would never be NULL. Leave the value if
8419 there were any relocations where pointer equality matters
8420 (this is a clue for the dynamic linker, to make function
8421 pointer comparisons work between an application and shared
8423 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
8428 if (h
->got
.offset
!= (bfd_vma
) - 1
8429 && elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
)
8431 Elf_Internal_Rela rela
;
8434 /* This symbol has an entry in the global offset table. Set it
8436 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
8439 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
8440 + htab
->root
.sgot
->output_offset
8441 + (h
->got
.offset
& ~(bfd_vma
) 1));
8444 && h
->type
== STT_GNU_IFUNC
)
8446 if (bfd_link_pic (info
))
8448 /* Generate R_AARCH64_GLOB_DAT. */
8455 if (!h
->pointer_equality_needed
)
8458 /* For non-shared object, we can't use .got.plt, which
8459 contains the real function address if we need pointer
8460 equality. We load the GOT entry with the PLT entry. */
8461 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
8462 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
8463 + plt
->output_offset
8465 htab
->root
.sgot
->contents
8466 + (h
->got
.offset
& ~(bfd_vma
) 1));
8470 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
8472 if (!h
->def_regular
)
8475 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
8476 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
8477 rela
.r_addend
= (h
->root
.u
.def
.value
8478 + h
->root
.u
.def
.section
->output_section
->vma
8479 + h
->root
.u
.def
.section
->output_offset
);
8484 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
8485 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8486 htab
->root
.sgot
->contents
+ h
->got
.offset
);
8487 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (GLOB_DAT
));
8491 loc
= htab
->root
.srelgot
->contents
;
8492 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
8493 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8498 Elf_Internal_Rela rela
;
8501 /* This symbol needs a copy reloc. Set it up. */
8503 if (h
->dynindx
== -1
8504 || (h
->root
.type
!= bfd_link_hash_defined
8505 && h
->root
.type
!= bfd_link_hash_defweak
)
8506 || htab
->srelbss
== NULL
)
8509 rela
.r_offset
= (h
->root
.u
.def
.value
8510 + h
->root
.u
.def
.section
->output_section
->vma
8511 + h
->root
.u
.def
.section
->output_offset
);
8512 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
8514 loc
= htab
->srelbss
->contents
;
8515 loc
+= htab
->srelbss
->reloc_count
++ * RELOC_SIZE (htab
);
8516 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8519 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
8520 be NULL for local symbols. */
8522 && (h
== elf_hash_table (info
)->hdynamic
8523 || h
== elf_hash_table (info
)->hgot
))
8524 sym
->st_shndx
= SHN_ABS
;
8529 /* Finish up local dynamic symbol handling. We set the contents of
8530 various dynamic sections here. */
8533 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
8535 struct elf_link_hash_entry
*h
8536 = (struct elf_link_hash_entry
*) *slot
;
8537 struct bfd_link_info
*info
8538 = (struct bfd_link_info
*) inf
;
8540 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
8545 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
8546 struct elf_aarch64_link_hash_table
8549 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
8550 small and large plts and at the minute just generates
8553 /* PLT0 of the small PLT looks like this in ELF64 -
8554 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
8555 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
8556 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
8558 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
8559 // GOTPLT entry for this.
8561 PLT0 will be slightly different in ELF32 due to different got entry
8564 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
8568 memcpy (htab
->root
.splt
->contents
, elfNN_aarch64_small_plt0_entry
,
8570 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
=
8573 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
8574 + htab
->root
.sgotplt
->output_offset
8575 + GOT_ENTRY_SIZE
* 2);
8577 plt_base
= htab
->root
.splt
->output_section
->vma
+
8578 htab
->root
.splt
->output_offset
;
8580 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8581 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8582 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8583 htab
->root
.splt
->contents
+ 4,
8584 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
8586 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
8587 htab
->root
.splt
->contents
+ 8,
8588 PG_OFFSET (plt_got_2nd_ent
));
8590 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
8591 htab
->root
.splt
->contents
+ 12,
8592 PG_OFFSET (plt_got_2nd_ent
));
8596 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
8597 struct bfd_link_info
*info
)
8599 struct elf_aarch64_link_hash_table
*htab
;
8603 htab
= elf_aarch64_hash_table (info
);
8604 dynobj
= htab
->root
.dynobj
;
8605 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
8607 if (htab
->root
.dynamic_sections_created
)
8609 ElfNN_External_Dyn
*dyncon
, *dynconend
;
8611 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
8614 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
8615 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
8616 for (; dyncon
< dynconend
; dyncon
++)
8618 Elf_Internal_Dyn dyn
;
8621 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
8629 s
= htab
->root
.sgotplt
;
8630 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
8634 dyn
.d_un
.d_ptr
= htab
->root
.srelplt
->output_section
->vma
;
8638 s
= htab
->root
.srelplt
;
8639 dyn
.d_un
.d_val
= s
->size
;
8643 /* The procedure linkage table relocs (DT_JMPREL) should
8644 not be included in the overall relocs (DT_RELA).
8645 Therefore, we override the DT_RELASZ entry here to
8646 make it not include the JMPREL relocs. Since the
8647 linker script arranges for .rela.plt to follow all
8648 other relocation sections, we don't have to worry
8649 about changing the DT_RELA entry. */
8650 if (htab
->root
.srelplt
!= NULL
)
8652 s
= htab
->root
.srelplt
;
8653 dyn
.d_un
.d_val
-= s
->size
;
8657 case DT_TLSDESC_PLT
:
8658 s
= htab
->root
.splt
;
8659 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
8660 + htab
->tlsdesc_plt
;
8663 case DT_TLSDESC_GOT
:
8664 s
= htab
->root
.sgot
;
8665 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
8666 + htab
->dt_tlsdesc_got
;
8670 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
8675 /* Fill in the special first entry in the procedure linkage table. */
8676 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
8678 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
8680 elf_section_data (htab
->root
.splt
->output_section
)->
8681 this_hdr
.sh_entsize
= htab
->plt_entry_size
;
8684 if (htab
->tlsdesc_plt
)
8686 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8687 htab
->root
.sgot
->contents
+ htab
->dt_tlsdesc_got
);
8689 memcpy (htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
,
8690 elfNN_aarch64_tlsdesc_small_plt_entry
,
8691 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry
));
8694 bfd_vma adrp1_addr
=
8695 htab
->root
.splt
->output_section
->vma
8696 + htab
->root
.splt
->output_offset
+ htab
->tlsdesc_plt
+ 4;
8698 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
8701 htab
->root
.sgot
->output_section
->vma
8702 + htab
->root
.sgot
->output_offset
;
8704 bfd_vma pltgot_addr
=
8705 htab
->root
.sgotplt
->output_section
->vma
8706 + htab
->root
.sgotplt
->output_offset
;
8708 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->dt_tlsdesc_got
;
8710 bfd_byte
*plt_entry
=
8711 htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
;
8713 /* adrp x2, DT_TLSDESC_GOT */
8714 elf_aarch64_update_plt_entry (output_bfd
,
8715 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8717 (PG (dt_tlsdesc_got
)
8718 - PG (adrp1_addr
)));
8721 elf_aarch64_update_plt_entry (output_bfd
,
8722 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8725 - PG (adrp2_addr
)));
8727 /* ldr x2, [x2, #0] */
8728 elf_aarch64_update_plt_entry (output_bfd
,
8729 BFD_RELOC_AARCH64_LDSTNN_LO12
,
8731 PG_OFFSET (dt_tlsdesc_got
));
8734 elf_aarch64_update_plt_entry (output_bfd
,
8735 BFD_RELOC_AARCH64_ADD_LO12
,
8737 PG_OFFSET (pltgot_addr
));
8742 if (htab
->root
.sgotplt
)
8744 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
8746 (*_bfd_error_handler
)
8747 (_("discarded output section: `%A'"), htab
->root
.sgotplt
);
8751 /* Fill in the first three entries in the global offset table. */
8752 if (htab
->root
.sgotplt
->size
> 0)
8754 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
8756 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
8757 bfd_put_NN (output_bfd
,
8759 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
8760 bfd_put_NN (output_bfd
,
8762 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
* 2);
8765 if (htab
->root
.sgot
)
8767 if (htab
->root
.sgot
->size
> 0)
8770 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
8771 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
8775 elf_section_data (htab
->root
.sgotplt
->output_section
)->
8776 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
8779 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
8780 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
8783 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
8784 htab_traverse (htab
->loc_hash_table
,
8785 elfNN_aarch64_finish_local_dynamic_symbol
,
8791 /* Return address for Ith PLT stub in section PLT, for relocation REL
8792 or (bfd_vma) -1 if it should not be included. */
8795 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
8796 const arelent
*rel ATTRIBUTE_UNUSED
)
8798 return plt
->vma
+ PLT_ENTRY_SIZE
+ i
* PLT_SMALL_ENTRY_SIZE
;
8802 /* We use this so we can override certain functions
8803 (though currently we don't). */
8805 const struct elf_size_info elfNN_aarch64_size_info
=
8807 sizeof (ElfNN_External_Ehdr
),
8808 sizeof (ElfNN_External_Phdr
),
8809 sizeof (ElfNN_External_Shdr
),
8810 sizeof (ElfNN_External_Rel
),
8811 sizeof (ElfNN_External_Rela
),
8812 sizeof (ElfNN_External_Sym
),
8813 sizeof (ElfNN_External_Dyn
),
8814 sizeof (Elf_External_Note
),
8815 4, /* Hash table entry size. */
8816 1, /* Internal relocs per external relocs. */
8817 ARCH_SIZE
, /* Arch size. */
8818 LOG_FILE_ALIGN
, /* Log_file_align. */
8819 ELFCLASSNN
, EV_CURRENT
,
8820 bfd_elfNN_write_out_phdrs
,
8821 bfd_elfNN_write_shdrs_and_ehdr
,
8822 bfd_elfNN_checksum_contents
,
8823 bfd_elfNN_write_relocs
,
8824 bfd_elfNN_swap_symbol_in
,
8825 bfd_elfNN_swap_symbol_out
,
8826 bfd_elfNN_slurp_reloc_table
,
8827 bfd_elfNN_slurp_symbol_table
,
8828 bfd_elfNN_swap_dyn_in
,
8829 bfd_elfNN_swap_dyn_out
,
8830 bfd_elfNN_swap_reloc_in
,
8831 bfd_elfNN_swap_reloc_out
,
8832 bfd_elfNN_swap_reloca_in
,
8833 bfd_elfNN_swap_reloca_out
8836 #define ELF_ARCH bfd_arch_aarch64
8837 #define ELF_MACHINE_CODE EM_AARCH64
8838 #define ELF_MAXPAGESIZE 0x10000
8839 #define ELF_MINPAGESIZE 0x1000
8840 #define ELF_COMMONPAGESIZE 0x1000
8842 #define bfd_elfNN_close_and_cleanup \
8843 elfNN_aarch64_close_and_cleanup
8845 #define bfd_elfNN_bfd_free_cached_info \
8846 elfNN_aarch64_bfd_free_cached_info
8848 #define bfd_elfNN_bfd_is_target_special_symbol \
8849 elfNN_aarch64_is_target_special_symbol
8851 #define bfd_elfNN_bfd_link_hash_table_create \
8852 elfNN_aarch64_link_hash_table_create
8854 #define bfd_elfNN_bfd_merge_private_bfd_data \
8855 elfNN_aarch64_merge_private_bfd_data
8857 #define bfd_elfNN_bfd_print_private_bfd_data \
8858 elfNN_aarch64_print_private_bfd_data
8860 #define bfd_elfNN_bfd_reloc_type_lookup \
8861 elfNN_aarch64_reloc_type_lookup
8863 #define bfd_elfNN_bfd_reloc_name_lookup \
8864 elfNN_aarch64_reloc_name_lookup
8866 #define bfd_elfNN_bfd_set_private_flags \
8867 elfNN_aarch64_set_private_flags
8869 #define bfd_elfNN_find_inliner_info \
8870 elfNN_aarch64_find_inliner_info
8872 #define bfd_elfNN_find_nearest_line \
8873 elfNN_aarch64_find_nearest_line
8875 #define bfd_elfNN_mkobject \
8876 elfNN_aarch64_mkobject
8878 #define bfd_elfNN_new_section_hook \
8879 elfNN_aarch64_new_section_hook
8881 #define elf_backend_adjust_dynamic_symbol \
8882 elfNN_aarch64_adjust_dynamic_symbol
8884 #define elf_backend_always_size_sections \
8885 elfNN_aarch64_always_size_sections
8887 #define elf_backend_check_relocs \
8888 elfNN_aarch64_check_relocs
8890 #define elf_backend_copy_indirect_symbol \
8891 elfNN_aarch64_copy_indirect_symbol
8893 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
8894 to them in our hash. */
8895 #define elf_backend_create_dynamic_sections \
8896 elfNN_aarch64_create_dynamic_sections
8898 #define elf_backend_init_index_section \
8899 _bfd_elf_init_2_index_sections
8901 #define elf_backend_finish_dynamic_sections \
8902 elfNN_aarch64_finish_dynamic_sections
8904 #define elf_backend_finish_dynamic_symbol \
8905 elfNN_aarch64_finish_dynamic_symbol
8907 #define elf_backend_gc_sweep_hook \
8908 elfNN_aarch64_gc_sweep_hook
8910 #define elf_backend_object_p \
8911 elfNN_aarch64_object_p
8913 #define elf_backend_output_arch_local_syms \
8914 elfNN_aarch64_output_arch_local_syms
8916 #define elf_backend_plt_sym_val \
8917 elfNN_aarch64_plt_sym_val
8919 #define elf_backend_post_process_headers \
8920 elfNN_aarch64_post_process_headers
8922 #define elf_backend_relocate_section \
8923 elfNN_aarch64_relocate_section
8925 #define elf_backend_reloc_type_class \
8926 elfNN_aarch64_reloc_type_class
8928 #define elf_backend_section_from_shdr \
8929 elfNN_aarch64_section_from_shdr
8931 #define elf_backend_size_dynamic_sections \
8932 elfNN_aarch64_size_dynamic_sections
8934 #define elf_backend_size_info \
8935 elfNN_aarch64_size_info
8937 #define elf_backend_write_section \
8938 elfNN_aarch64_write_section
8940 #define elf_backend_can_refcount 1
8941 #define elf_backend_can_gc_sections 1
8942 #define elf_backend_plt_readonly 1
8943 #define elf_backend_want_got_plt 1
8944 #define elf_backend_want_plt_sym 0
8945 #define elf_backend_may_use_rel_p 0
8946 #define elf_backend_may_use_rela_p 1
8947 #define elf_backend_default_use_rela_p 1
8948 #define elf_backend_rela_normal 1
8949 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
8950 #define elf_backend_default_execstack 0
8951 #define elf_backend_extern_protected_data 1
8953 #undef elf_backend_obj_attrs_section
8954 #define elf_backend_obj_attrs_section ".ARM.attributes"
8956 #include "elfNN-target.h"