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_LDST16_DTPREL_LO12 \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12 \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12 \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12 \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0 \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1 \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2 \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
207 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
209 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
210 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
212 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
213 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
214 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
215 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
216 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
220 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
221 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
222 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
223 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
224 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
226 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
227 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
228 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
229 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
230 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
231 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
232 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
233 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
234 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
235 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
236 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
237 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
238 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
240 #define ELIMINATE_COPY_RELOCS 0
242 /* Return size of a relocation entry. HTAB is the bfd's
243 elf_aarch64_link_hash_entry. */
244 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
246 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
247 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
248 #define PLT_ENTRY_SIZE (32)
249 #define PLT_SMALL_ENTRY_SIZE (16)
250 #define PLT_TLSDESC_ENTRY_SIZE (32)
252 /* Encoding of the nop instruction */
253 #define INSN_NOP 0xd503201f
255 #define aarch64_compute_jump_table_size(htab) \
256 (((htab)->root.srelplt == NULL) ? 0 \
257 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
259 /* The first entry in a procedure linkage table looks like this
260 if the distance between the PLTGOT and the PLT is < 4GB use
261 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
262 in x16 and needs to work out PLTGOT[1] by using an address of
263 [x16,#-GOT_ENTRY_SIZE]. */
264 static const bfd_byte elfNN_aarch64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
266 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
267 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
269 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
270 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
272 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
273 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
275 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
276 0x1f, 0x20, 0x03, 0xd5, /* nop */
277 0x1f, 0x20, 0x03, 0xd5, /* nop */
278 0x1f, 0x20, 0x03, 0xd5, /* nop */
281 /* Per function entry in a procedure linkage table looks like this
282 if the distance between the PLTGOT and the PLT is < 4GB use
283 these PLT entries. */
284 static const bfd_byte elfNN_aarch64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
286 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
288 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
289 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
291 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
292 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
294 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
297 static const bfd_byte
298 elfNN_aarch64_tlsdesc_small_plt_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
300 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
301 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
302 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
304 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
305 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
307 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
308 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
310 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
311 0x1f, 0x20, 0x03, 0xd5, /* nop */
312 0x1f, 0x20, 0x03, 0xd5, /* nop */
315 #define elf_info_to_howto elfNN_aarch64_info_to_howto
316 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
318 #define AARCH64_ELF_ABI_VERSION 0
320 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
321 #define ALL_ONES (~ (bfd_vma) 0)
323 /* Indexed by the bfd interal reloc enumerators.
324 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
327 static reloc_howto_type elfNN_aarch64_howto_table
[] =
331 /* Basic data relocations. */
334 HOWTO (R_AARCH64_NULL
, /* type */
336 3, /* size (0 = byte, 1 = short, 2 = long) */
338 FALSE
, /* pc_relative */
340 complain_overflow_dont
, /* complain_on_overflow */
341 bfd_elf_generic_reloc
, /* special_function */
342 "R_AARCH64_NULL", /* name */
343 FALSE
, /* partial_inplace */
346 FALSE
), /* pcrel_offset */
348 HOWTO (R_AARCH64_NONE
, /* type */
350 3, /* size (0 = byte, 1 = short, 2 = long) */
352 FALSE
, /* pc_relative */
354 complain_overflow_dont
, /* complain_on_overflow */
355 bfd_elf_generic_reloc
, /* special_function */
356 "R_AARCH64_NONE", /* name */
357 FALSE
, /* partial_inplace */
360 FALSE
), /* pcrel_offset */
364 HOWTO64 (AARCH64_R (ABS64
), /* type */
366 4, /* size (4 = long long) */
368 FALSE
, /* pc_relative */
370 complain_overflow_unsigned
, /* complain_on_overflow */
371 bfd_elf_generic_reloc
, /* special_function */
372 AARCH64_R_STR (ABS64
), /* name */
373 FALSE
, /* partial_inplace */
374 ALL_ONES
, /* src_mask */
375 ALL_ONES
, /* dst_mask */
376 FALSE
), /* pcrel_offset */
379 HOWTO (AARCH64_R (ABS32
), /* type */
381 2, /* size (0 = byte, 1 = short, 2 = long) */
383 FALSE
, /* pc_relative */
385 complain_overflow_unsigned
, /* complain_on_overflow */
386 bfd_elf_generic_reloc
, /* special_function */
387 AARCH64_R_STR (ABS32
), /* name */
388 FALSE
, /* partial_inplace */
389 0xffffffff, /* src_mask */
390 0xffffffff, /* dst_mask */
391 FALSE
), /* pcrel_offset */
394 HOWTO (AARCH64_R (ABS16
), /* type */
396 1, /* size (0 = byte, 1 = short, 2 = long) */
398 FALSE
, /* pc_relative */
400 complain_overflow_unsigned
, /* complain_on_overflow */
401 bfd_elf_generic_reloc
, /* special_function */
402 AARCH64_R_STR (ABS16
), /* name */
403 FALSE
, /* partial_inplace */
404 0xffff, /* src_mask */
405 0xffff, /* dst_mask */
406 FALSE
), /* pcrel_offset */
408 /* .xword: (S+A-P) */
409 HOWTO64 (AARCH64_R (PREL64
), /* type */
411 4, /* size (4 = long long) */
413 TRUE
, /* pc_relative */
415 complain_overflow_signed
, /* complain_on_overflow */
416 bfd_elf_generic_reloc
, /* special_function */
417 AARCH64_R_STR (PREL64
), /* name */
418 FALSE
, /* partial_inplace */
419 ALL_ONES
, /* src_mask */
420 ALL_ONES
, /* dst_mask */
421 TRUE
), /* pcrel_offset */
424 HOWTO (AARCH64_R (PREL32
), /* type */
426 2, /* size (0 = byte, 1 = short, 2 = long) */
428 TRUE
, /* pc_relative */
430 complain_overflow_signed
, /* complain_on_overflow */
431 bfd_elf_generic_reloc
, /* special_function */
432 AARCH64_R_STR (PREL32
), /* name */
433 FALSE
, /* partial_inplace */
434 0xffffffff, /* src_mask */
435 0xffffffff, /* dst_mask */
436 TRUE
), /* pcrel_offset */
439 HOWTO (AARCH64_R (PREL16
), /* type */
441 1, /* size (0 = byte, 1 = short, 2 = long) */
443 TRUE
, /* pc_relative */
445 complain_overflow_signed
, /* complain_on_overflow */
446 bfd_elf_generic_reloc
, /* special_function */
447 AARCH64_R_STR (PREL16
), /* name */
448 FALSE
, /* partial_inplace */
449 0xffff, /* src_mask */
450 0xffff, /* dst_mask */
451 TRUE
), /* pcrel_offset */
453 /* Group relocations to create a 16, 32, 48 or 64 bit
454 unsigned data or abs address inline. */
456 /* MOVZ: ((S+A) >> 0) & 0xffff */
457 HOWTO (AARCH64_R (MOVW_UABS_G0
), /* type */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
461 FALSE
, /* pc_relative */
463 complain_overflow_unsigned
, /* complain_on_overflow */
464 bfd_elf_generic_reloc
, /* special_function */
465 AARCH64_R_STR (MOVW_UABS_G0
), /* name */
466 FALSE
, /* partial_inplace */
467 0xffff, /* src_mask */
468 0xffff, /* dst_mask */
469 FALSE
), /* pcrel_offset */
471 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
472 HOWTO (AARCH64_R (MOVW_UABS_G0_NC
), /* type */
474 2, /* size (0 = byte, 1 = short, 2 = long) */
476 FALSE
, /* pc_relative */
478 complain_overflow_dont
, /* complain_on_overflow */
479 bfd_elf_generic_reloc
, /* special_function */
480 AARCH64_R_STR (MOVW_UABS_G0_NC
), /* name */
481 FALSE
, /* partial_inplace */
482 0xffff, /* src_mask */
483 0xffff, /* dst_mask */
484 FALSE
), /* pcrel_offset */
486 /* MOVZ: ((S+A) >> 16) & 0xffff */
487 HOWTO (AARCH64_R (MOVW_UABS_G1
), /* type */
489 2, /* size (0 = byte, 1 = short, 2 = long) */
491 FALSE
, /* pc_relative */
493 complain_overflow_unsigned
, /* complain_on_overflow */
494 bfd_elf_generic_reloc
, /* special_function */
495 AARCH64_R_STR (MOVW_UABS_G1
), /* name */
496 FALSE
, /* partial_inplace */
497 0xffff, /* src_mask */
498 0xffff, /* dst_mask */
499 FALSE
), /* pcrel_offset */
501 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
502 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC
), /* type */
504 2, /* size (0 = byte, 1 = short, 2 = long) */
506 FALSE
, /* pc_relative */
508 complain_overflow_dont
, /* complain_on_overflow */
509 bfd_elf_generic_reloc
, /* special_function */
510 AARCH64_R_STR (MOVW_UABS_G1_NC
), /* name */
511 FALSE
, /* partial_inplace */
512 0xffff, /* src_mask */
513 0xffff, /* dst_mask */
514 FALSE
), /* pcrel_offset */
516 /* MOVZ: ((S+A) >> 32) & 0xffff */
517 HOWTO64 (AARCH64_R (MOVW_UABS_G2
), /* type */
519 2, /* size (0 = byte, 1 = short, 2 = long) */
521 FALSE
, /* pc_relative */
523 complain_overflow_unsigned
, /* complain_on_overflow */
524 bfd_elf_generic_reloc
, /* special_function */
525 AARCH64_R_STR (MOVW_UABS_G2
), /* name */
526 FALSE
, /* partial_inplace */
527 0xffff, /* src_mask */
528 0xffff, /* dst_mask */
529 FALSE
), /* pcrel_offset */
531 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
532 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC
), /* type */
534 2, /* size (0 = byte, 1 = short, 2 = long) */
536 FALSE
, /* pc_relative */
538 complain_overflow_dont
, /* complain_on_overflow */
539 bfd_elf_generic_reloc
, /* special_function */
540 AARCH64_R_STR (MOVW_UABS_G2_NC
), /* name */
541 FALSE
, /* partial_inplace */
542 0xffff, /* src_mask */
543 0xffff, /* dst_mask */
544 FALSE
), /* pcrel_offset */
546 /* MOVZ: ((S+A) >> 48) & 0xffff */
547 HOWTO64 (AARCH64_R (MOVW_UABS_G3
), /* type */
549 2, /* size (0 = byte, 1 = short, 2 = long) */
551 FALSE
, /* pc_relative */
553 complain_overflow_unsigned
, /* complain_on_overflow */
554 bfd_elf_generic_reloc
, /* special_function */
555 AARCH64_R_STR (MOVW_UABS_G3
), /* name */
556 FALSE
, /* partial_inplace */
557 0xffff, /* src_mask */
558 0xffff, /* dst_mask */
559 FALSE
), /* pcrel_offset */
561 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
562 signed data or abs address inline. Will change instruction
563 to MOVN or MOVZ depending on sign of calculated value. */
565 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
566 HOWTO (AARCH64_R (MOVW_SABS_G0
), /* type */
568 2, /* size (0 = byte, 1 = short, 2 = long) */
570 FALSE
, /* pc_relative */
572 complain_overflow_signed
, /* complain_on_overflow */
573 bfd_elf_generic_reloc
, /* special_function */
574 AARCH64_R_STR (MOVW_SABS_G0
), /* name */
575 FALSE
, /* partial_inplace */
576 0xffff, /* src_mask */
577 0xffff, /* dst_mask */
578 FALSE
), /* pcrel_offset */
580 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
581 HOWTO64 (AARCH64_R (MOVW_SABS_G1
), /* type */
583 2, /* size (0 = byte, 1 = short, 2 = long) */
585 FALSE
, /* pc_relative */
587 complain_overflow_signed
, /* complain_on_overflow */
588 bfd_elf_generic_reloc
, /* special_function */
589 AARCH64_R_STR (MOVW_SABS_G1
), /* name */
590 FALSE
, /* partial_inplace */
591 0xffff, /* src_mask */
592 0xffff, /* dst_mask */
593 FALSE
), /* pcrel_offset */
595 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
596 HOWTO64 (AARCH64_R (MOVW_SABS_G2
), /* type */
598 2, /* size (0 = byte, 1 = short, 2 = long) */
600 FALSE
, /* pc_relative */
602 complain_overflow_signed
, /* complain_on_overflow */
603 bfd_elf_generic_reloc
, /* special_function */
604 AARCH64_R_STR (MOVW_SABS_G2
), /* name */
605 FALSE
, /* partial_inplace */
606 0xffff, /* src_mask */
607 0xffff, /* dst_mask */
608 FALSE
), /* pcrel_offset */
610 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
611 addresses: PG(x) is (x & ~0xfff). */
613 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
614 HOWTO (AARCH64_R (LD_PREL_LO19
), /* type */
616 2, /* size (0 = byte, 1 = short, 2 = long) */
618 TRUE
, /* pc_relative */
620 complain_overflow_signed
, /* complain_on_overflow */
621 bfd_elf_generic_reloc
, /* special_function */
622 AARCH64_R_STR (LD_PREL_LO19
), /* name */
623 FALSE
, /* partial_inplace */
624 0x7ffff, /* src_mask */
625 0x7ffff, /* dst_mask */
626 TRUE
), /* pcrel_offset */
628 /* ADR: (S+A-P) & 0x1fffff */
629 HOWTO (AARCH64_R (ADR_PREL_LO21
), /* type */
631 2, /* size (0 = byte, 1 = short, 2 = long) */
633 TRUE
, /* pc_relative */
635 complain_overflow_signed
, /* complain_on_overflow */
636 bfd_elf_generic_reloc
, /* special_function */
637 AARCH64_R_STR (ADR_PREL_LO21
), /* name */
638 FALSE
, /* partial_inplace */
639 0x1fffff, /* src_mask */
640 0x1fffff, /* dst_mask */
641 TRUE
), /* pcrel_offset */
643 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
644 HOWTO (AARCH64_R (ADR_PREL_PG_HI21
), /* type */
646 2, /* size (0 = byte, 1 = short, 2 = long) */
648 TRUE
, /* pc_relative */
650 complain_overflow_signed
, /* complain_on_overflow */
651 bfd_elf_generic_reloc
, /* special_function */
652 AARCH64_R_STR (ADR_PREL_PG_HI21
), /* name */
653 FALSE
, /* partial_inplace */
654 0x1fffff, /* src_mask */
655 0x1fffff, /* dst_mask */
656 TRUE
), /* pcrel_offset */
658 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
659 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC
), /* type */
661 2, /* size (0 = byte, 1 = short, 2 = long) */
663 TRUE
, /* pc_relative */
665 complain_overflow_dont
, /* complain_on_overflow */
666 bfd_elf_generic_reloc
, /* special_function */
667 AARCH64_R_STR (ADR_PREL_PG_HI21_NC
), /* name */
668 FALSE
, /* partial_inplace */
669 0x1fffff, /* src_mask */
670 0x1fffff, /* dst_mask */
671 TRUE
), /* pcrel_offset */
673 /* ADD: (S+A) & 0xfff [no overflow check] */
674 HOWTO (AARCH64_R (ADD_ABS_LO12_NC
), /* type */
676 2, /* size (0 = byte, 1 = short, 2 = long) */
678 FALSE
, /* pc_relative */
680 complain_overflow_dont
, /* complain_on_overflow */
681 bfd_elf_generic_reloc
, /* special_function */
682 AARCH64_R_STR (ADD_ABS_LO12_NC
), /* name */
683 FALSE
, /* partial_inplace */
684 0x3ffc00, /* src_mask */
685 0x3ffc00, /* dst_mask */
686 FALSE
), /* pcrel_offset */
688 /* LD/ST8: (S+A) & 0xfff */
689 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC
), /* type */
691 2, /* size (0 = byte, 1 = short, 2 = long) */
693 FALSE
, /* pc_relative */
695 complain_overflow_dont
, /* complain_on_overflow */
696 bfd_elf_generic_reloc
, /* special_function */
697 AARCH64_R_STR (LDST8_ABS_LO12_NC
), /* name */
698 FALSE
, /* partial_inplace */
699 0xfff, /* src_mask */
700 0xfff, /* dst_mask */
701 FALSE
), /* pcrel_offset */
703 /* Relocations for control-flow instructions. */
705 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
706 HOWTO (AARCH64_R (TSTBR14
), /* type */
708 2, /* size (0 = byte, 1 = short, 2 = long) */
710 TRUE
, /* pc_relative */
712 complain_overflow_signed
, /* complain_on_overflow */
713 bfd_elf_generic_reloc
, /* special_function */
714 AARCH64_R_STR (TSTBR14
), /* name */
715 FALSE
, /* partial_inplace */
716 0x3fff, /* src_mask */
717 0x3fff, /* dst_mask */
718 TRUE
), /* pcrel_offset */
720 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
721 HOWTO (AARCH64_R (CONDBR19
), /* type */
723 2, /* size (0 = byte, 1 = short, 2 = long) */
725 TRUE
, /* pc_relative */
727 complain_overflow_signed
, /* complain_on_overflow */
728 bfd_elf_generic_reloc
, /* special_function */
729 AARCH64_R_STR (CONDBR19
), /* name */
730 FALSE
, /* partial_inplace */
731 0x7ffff, /* src_mask */
732 0x7ffff, /* dst_mask */
733 TRUE
), /* pcrel_offset */
735 /* B: ((S+A-P) >> 2) & 0x3ffffff */
736 HOWTO (AARCH64_R (JUMP26
), /* type */
738 2, /* size (0 = byte, 1 = short, 2 = long) */
740 TRUE
, /* pc_relative */
742 complain_overflow_signed
, /* complain_on_overflow */
743 bfd_elf_generic_reloc
, /* special_function */
744 AARCH64_R_STR (JUMP26
), /* name */
745 FALSE
, /* partial_inplace */
746 0x3ffffff, /* src_mask */
747 0x3ffffff, /* dst_mask */
748 TRUE
), /* pcrel_offset */
750 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
751 HOWTO (AARCH64_R (CALL26
), /* type */
753 2, /* size (0 = byte, 1 = short, 2 = long) */
755 TRUE
, /* pc_relative */
757 complain_overflow_signed
, /* complain_on_overflow */
758 bfd_elf_generic_reloc
, /* special_function */
759 AARCH64_R_STR (CALL26
), /* name */
760 FALSE
, /* partial_inplace */
761 0x3ffffff, /* src_mask */
762 0x3ffffff, /* dst_mask */
763 TRUE
), /* pcrel_offset */
765 /* LD/ST16: (S+A) & 0xffe */
766 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC
), /* type */
768 2, /* size (0 = byte, 1 = short, 2 = long) */
770 FALSE
, /* pc_relative */
772 complain_overflow_dont
, /* complain_on_overflow */
773 bfd_elf_generic_reloc
, /* special_function */
774 AARCH64_R_STR (LDST16_ABS_LO12_NC
), /* name */
775 FALSE
, /* partial_inplace */
776 0xffe, /* src_mask */
777 0xffe, /* dst_mask */
778 FALSE
), /* pcrel_offset */
780 /* LD/ST32: (S+A) & 0xffc */
781 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC
), /* type */
783 2, /* size (0 = byte, 1 = short, 2 = long) */
785 FALSE
, /* pc_relative */
787 complain_overflow_dont
, /* complain_on_overflow */
788 bfd_elf_generic_reloc
, /* special_function */
789 AARCH64_R_STR (LDST32_ABS_LO12_NC
), /* name */
790 FALSE
, /* partial_inplace */
791 0xffc, /* src_mask */
792 0xffc, /* dst_mask */
793 FALSE
), /* pcrel_offset */
795 /* LD/ST64: (S+A) & 0xff8 */
796 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC
), /* type */
798 2, /* size (0 = byte, 1 = short, 2 = long) */
800 FALSE
, /* pc_relative */
802 complain_overflow_dont
, /* complain_on_overflow */
803 bfd_elf_generic_reloc
, /* special_function */
804 AARCH64_R_STR (LDST64_ABS_LO12_NC
), /* name */
805 FALSE
, /* partial_inplace */
806 0xff8, /* src_mask */
807 0xff8, /* dst_mask */
808 FALSE
), /* pcrel_offset */
810 /* LD/ST128: (S+A) & 0xff0 */
811 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC
), /* type */
813 2, /* size (0 = byte, 1 = short, 2 = long) */
815 FALSE
, /* pc_relative */
817 complain_overflow_dont
, /* complain_on_overflow */
818 bfd_elf_generic_reloc
, /* special_function */
819 AARCH64_R_STR (LDST128_ABS_LO12_NC
), /* name */
820 FALSE
, /* partial_inplace */
821 0xff0, /* src_mask */
822 0xff0, /* dst_mask */
823 FALSE
), /* pcrel_offset */
825 /* Set a load-literal immediate field to bits
826 0x1FFFFC of G(S)-P */
827 HOWTO (AARCH64_R (GOT_LD_PREL19
), /* type */
829 2, /* size (0 = byte,1 = short,2 = long) */
831 TRUE
, /* pc_relative */
833 complain_overflow_signed
, /* complain_on_overflow */
834 bfd_elf_generic_reloc
, /* special_function */
835 AARCH64_R_STR (GOT_LD_PREL19
), /* name */
836 FALSE
, /* partial_inplace */
837 0xffffe0, /* src_mask */
838 0xffffe0, /* dst_mask */
839 TRUE
), /* pcrel_offset */
841 /* Get to the page for the GOT entry for the symbol
842 (G(S) - P) using an ADRP instruction. */
843 HOWTO (AARCH64_R (ADR_GOT_PAGE
), /* type */
845 2, /* size (0 = byte, 1 = short, 2 = long) */
847 TRUE
, /* pc_relative */
849 complain_overflow_dont
, /* complain_on_overflow */
850 bfd_elf_generic_reloc
, /* special_function */
851 AARCH64_R_STR (ADR_GOT_PAGE
), /* name */
852 FALSE
, /* partial_inplace */
853 0x1fffff, /* src_mask */
854 0x1fffff, /* dst_mask */
855 TRUE
), /* pcrel_offset */
857 /* LD64: GOT offset G(S) & 0xff8 */
858 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC
), /* type */
860 2, /* size (0 = byte, 1 = short, 2 = long) */
862 FALSE
, /* pc_relative */
864 complain_overflow_dont
, /* complain_on_overflow */
865 bfd_elf_generic_reloc
, /* special_function */
866 AARCH64_R_STR (LD64_GOT_LO12_NC
), /* name */
867 FALSE
, /* partial_inplace */
868 0xff8, /* src_mask */
869 0xff8, /* dst_mask */
870 FALSE
), /* pcrel_offset */
872 /* LD32: GOT offset G(S) & 0xffc */
873 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC
), /* type */
875 2, /* size (0 = byte, 1 = short, 2 = long) */
877 FALSE
, /* pc_relative */
879 complain_overflow_dont
, /* complain_on_overflow */
880 bfd_elf_generic_reloc
, /* special_function */
881 AARCH64_R_STR (LD32_GOT_LO12_NC
), /* name */
882 FALSE
, /* partial_inplace */
883 0xffc, /* src_mask */
884 0xffc, /* dst_mask */
885 FALSE
), /* pcrel_offset */
887 /* Higher 16 bits of GOT offset for the symbol. */
888 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G1
), /* type */
890 2, /* size (0 = byte, 1 = short, 2 = long) */
892 FALSE
, /* pc_relative */
894 complain_overflow_unsigned
, /* complain_on_overflow */
895 bfd_elf_generic_reloc
, /* special_function */
896 AARCH64_R_STR (MOVW_GOTOFF_G1
), /* name */
897 FALSE
, /* partial_inplace */
898 0xffff, /* src_mask */
899 0xffff, /* dst_mask */
900 FALSE
), /* pcrel_offset */
902 /* LD64: GOT offset for the symbol. */
903 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15
), /* type */
905 2, /* size (0 = byte, 1 = short, 2 = long) */
907 FALSE
, /* pc_relative */
909 complain_overflow_unsigned
, /* complain_on_overflow */
910 bfd_elf_generic_reloc
, /* special_function */
911 AARCH64_R_STR (LD64_GOTOFF_LO15
), /* name */
912 FALSE
, /* partial_inplace */
913 0x7ff8, /* src_mask */
914 0x7ff8, /* dst_mask */
915 FALSE
), /* pcrel_offset */
917 /* LD32: GOT offset to the page address of GOT table.
918 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
919 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14
), /* type */
921 2, /* size (0 = byte, 1 = short, 2 = long) */
923 FALSE
, /* pc_relative */
925 complain_overflow_unsigned
, /* complain_on_overflow */
926 bfd_elf_generic_reloc
, /* special_function */
927 AARCH64_R_STR (LD32_GOTPAGE_LO14
), /* name */
928 FALSE
, /* partial_inplace */
929 0x5ffc, /* src_mask */
930 0x5ffc, /* dst_mask */
931 FALSE
), /* pcrel_offset */
933 /* LD64: GOT offset to the page address of GOT table.
934 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
935 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15
), /* type */
937 2, /* size (0 = byte, 1 = short, 2 = long) */
939 FALSE
, /* pc_relative */
941 complain_overflow_unsigned
, /* complain_on_overflow */
942 bfd_elf_generic_reloc
, /* special_function */
943 AARCH64_R_STR (LD64_GOTPAGE_LO15
), /* name */
944 FALSE
, /* partial_inplace */
945 0x7ff8, /* src_mask */
946 0x7ff8, /* dst_mask */
947 FALSE
), /* pcrel_offset */
949 /* Get to the page for the GOT entry for the symbol
950 (G(S) - P) using an ADRP instruction. */
951 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21
), /* type */
953 2, /* size (0 = byte, 1 = short, 2 = long) */
955 TRUE
, /* pc_relative */
957 complain_overflow_dont
, /* complain_on_overflow */
958 bfd_elf_generic_reloc
, /* special_function */
959 AARCH64_R_STR (TLSGD_ADR_PAGE21
), /* name */
960 FALSE
, /* partial_inplace */
961 0x1fffff, /* src_mask */
962 0x1fffff, /* dst_mask */
963 TRUE
), /* pcrel_offset */
965 HOWTO (AARCH64_R (TLSGD_ADR_PREL21
), /* type */
967 2, /* size (0 = byte, 1 = short, 2 = long) */
969 TRUE
, /* pc_relative */
971 complain_overflow_dont
, /* complain_on_overflow */
972 bfd_elf_generic_reloc
, /* special_function */
973 AARCH64_R_STR (TLSGD_ADR_PREL21
), /* name */
974 FALSE
, /* partial_inplace */
975 0x1fffff, /* src_mask */
976 0x1fffff, /* dst_mask */
977 TRUE
), /* pcrel_offset */
979 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
980 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC
), /* type */
982 2, /* size (0 = byte, 1 = short, 2 = long) */
984 FALSE
, /* pc_relative */
986 complain_overflow_dont
, /* complain_on_overflow */
987 bfd_elf_generic_reloc
, /* special_function */
988 AARCH64_R_STR (TLSGD_ADD_LO12_NC
), /* name */
989 FALSE
, /* partial_inplace */
990 0xfff, /* src_mask */
991 0xfff, /* dst_mask */
992 FALSE
), /* pcrel_offset */
994 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1
), /* type */
996 2, /* size (0 = byte, 1 = short, 2 = long) */
998 FALSE
, /* pc_relative */
1000 complain_overflow_dont
, /* complain_on_overflow */
1001 bfd_elf_generic_reloc
, /* special_function */
1002 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1
), /* name */
1003 FALSE
, /* partial_inplace */
1004 0xffff, /* src_mask */
1005 0xffff, /* dst_mask */
1006 FALSE
), /* pcrel_offset */
1008 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC
), /* type */
1010 2, /* size (0 = byte, 1 = short, 2 = long) */
1012 FALSE
, /* pc_relative */
1014 complain_overflow_dont
, /* complain_on_overflow */
1015 bfd_elf_generic_reloc
, /* special_function */
1016 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC
), /* name */
1017 FALSE
, /* partial_inplace */
1018 0xffff, /* src_mask */
1019 0xffff, /* dst_mask */
1020 FALSE
), /* pcrel_offset */
1022 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21
), /* type */
1023 12, /* rightshift */
1024 2, /* size (0 = byte, 1 = short, 2 = long) */
1026 FALSE
, /* pc_relative */
1028 complain_overflow_dont
, /* complain_on_overflow */
1029 bfd_elf_generic_reloc
, /* special_function */
1030 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21
), /* name */
1031 FALSE
, /* partial_inplace */
1032 0x1fffff, /* src_mask */
1033 0x1fffff, /* dst_mask */
1034 FALSE
), /* pcrel_offset */
1036 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC
), /* type */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1040 FALSE
, /* pc_relative */
1042 complain_overflow_dont
, /* complain_on_overflow */
1043 bfd_elf_generic_reloc
, /* special_function */
1044 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC
), /* name */
1045 FALSE
, /* partial_inplace */
1046 0xff8, /* src_mask */
1047 0xff8, /* dst_mask */
1048 FALSE
), /* pcrel_offset */
1050 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC
), /* type */
1052 2, /* size (0 = byte, 1 = short, 2 = long) */
1054 FALSE
, /* pc_relative */
1056 complain_overflow_dont
, /* complain_on_overflow */
1057 bfd_elf_generic_reloc
, /* special_function */
1058 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC
), /* name */
1059 FALSE
, /* partial_inplace */
1060 0xffc, /* src_mask */
1061 0xffc, /* dst_mask */
1062 FALSE
), /* pcrel_offset */
1064 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19
), /* type */
1066 2, /* size (0 = byte, 1 = short, 2 = long) */
1068 FALSE
, /* pc_relative */
1070 complain_overflow_dont
, /* complain_on_overflow */
1071 bfd_elf_generic_reloc
, /* special_function */
1072 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19
), /* name */
1073 FALSE
, /* partial_inplace */
1074 0x1ffffc, /* src_mask */
1075 0x1ffffc, /* dst_mask */
1076 FALSE
), /* pcrel_offset */
1078 /* ADD: bit[23:12] of byte offset to module TLS base address. */
1079 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12
), /* type */
1080 12, /* rightshift */
1081 2, /* size (0 = byte, 1 = short, 2 = long) */
1083 FALSE
, /* pc_relative */
1085 complain_overflow_unsigned
, /* complain_on_overflow */
1086 bfd_elf_generic_reloc
, /* special_function */
1087 AARCH64_R_STR (TLSLD_ADD_DTPREL_HI12
), /* name */
1088 FALSE
, /* partial_inplace */
1089 0xfff, /* src_mask */
1090 0xfff, /* dst_mask */
1091 FALSE
), /* pcrel_offset */
1093 /* Unsigned 12 bit byte offset to module TLS base address. */
1094 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12
), /* type */
1096 2, /* size (0 = byte, 1 = short, 2 = long) */
1098 FALSE
, /* pc_relative */
1100 complain_overflow_unsigned
, /* complain_on_overflow */
1101 bfd_elf_generic_reloc
, /* special_function */
1102 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12
), /* name */
1103 FALSE
, /* partial_inplace */
1104 0xfff, /* src_mask */
1105 0xfff, /* dst_mask */
1106 FALSE
), /* pcrel_offset */
1108 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1109 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC
), /* type */
1111 2, /* size (0 = byte, 1 = short, 2 = long) */
1113 FALSE
, /* pc_relative */
1115 complain_overflow_dont
, /* complain_on_overflow */
1116 bfd_elf_generic_reloc
, /* special_function */
1117 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC
), /* name */
1118 FALSE
, /* partial_inplace */
1119 0xfff, /* src_mask */
1120 0xfff, /* dst_mask */
1121 FALSE
), /* pcrel_offset */
1123 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1124 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC
), /* type */
1126 2, /* size (0 = byte, 1 = short, 2 = long) */
1128 FALSE
, /* pc_relative */
1130 complain_overflow_dont
, /* complain_on_overflow */
1131 bfd_elf_generic_reloc
, /* special_function */
1132 AARCH64_R_STR (TLSLD_ADD_LO12_NC
), /* name */
1133 FALSE
, /* partial_inplace */
1134 0xfff, /* src_mask */
1135 0xfff, /* dst_mask */
1136 FALSE
), /* pcrel_offset */
1138 /* Get to the page for the GOT entry for the symbol
1139 (G(S) - P) using an ADRP instruction. */
1140 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21
), /* type */
1141 12, /* rightshift */
1142 2, /* size (0 = byte, 1 = short, 2 = long) */
1144 TRUE
, /* pc_relative */
1146 complain_overflow_signed
, /* complain_on_overflow */
1147 bfd_elf_generic_reloc
, /* special_function */
1148 AARCH64_R_STR (TLSLD_ADR_PAGE21
), /* name */
1149 FALSE
, /* partial_inplace */
1150 0x1fffff, /* src_mask */
1151 0x1fffff, /* dst_mask */
1152 TRUE
), /* pcrel_offset */
1154 HOWTO (AARCH64_R (TLSLD_ADR_PREL21
), /* type */
1156 2, /* size (0 = byte, 1 = short, 2 = long) */
1158 TRUE
, /* pc_relative */
1160 complain_overflow_signed
, /* complain_on_overflow */
1161 bfd_elf_generic_reloc
, /* special_function */
1162 AARCH64_R_STR (TLSLD_ADR_PREL21
), /* name */
1163 FALSE
, /* partial_inplace */
1164 0x1fffff, /* src_mask */
1165 0x1fffff, /* dst_mask */
1166 TRUE
), /* pcrel_offset */
1168 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1169 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12
), /* type */
1171 2, /* size (0 = byte, 1 = short, 2 = long) */
1173 FALSE
, /* pc_relative */
1175 complain_overflow_unsigned
, /* complain_on_overflow */
1176 bfd_elf_generic_reloc
, /* special_function */
1177 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12
), /* name */
1178 FALSE
, /* partial_inplace */
1179 0x1ffc00, /* src_mask */
1180 0x1ffc00, /* dst_mask */
1181 FALSE
), /* pcrel_offset */
1183 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, but no overflow check. */
1184 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12_NC
), /* type */
1186 2, /* size (0 = byte, 1 = short, 2 = long) */
1188 FALSE
, /* pc_relative */
1190 complain_overflow_dont
, /* complain_on_overflow */
1191 bfd_elf_generic_reloc
, /* special_function */
1192 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12_NC
), /* name */
1193 FALSE
, /* partial_inplace */
1194 0x1ffc00, /* src_mask */
1195 0x1ffc00, /* dst_mask */
1196 FALSE
), /* pcrel_offset */
1198 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1199 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12
), /* type */
1201 2, /* size (0 = byte, 1 = short, 2 = long) */
1203 FALSE
, /* pc_relative */
1205 complain_overflow_unsigned
, /* complain_on_overflow */
1206 bfd_elf_generic_reloc
, /* special_function */
1207 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12
), /* name */
1208 FALSE
, /* partial_inplace */
1209 0x3ffc00, /* src_mask */
1210 0x3ffc00, /* dst_mask */
1211 FALSE
), /* pcrel_offset */
1213 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no overflow check. */
1214 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12_NC
), /* type */
1216 2, /* size (0 = byte, 1 = short, 2 = long) */
1218 FALSE
, /* pc_relative */
1220 complain_overflow_dont
, /* complain_on_overflow */
1221 bfd_elf_generic_reloc
, /* special_function */
1222 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12_NC
), /* name */
1223 FALSE
, /* partial_inplace */
1224 0xffc00, /* src_mask */
1225 0xffc00, /* dst_mask */
1226 FALSE
), /* pcrel_offset */
1228 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1229 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12
), /* type */
1231 2, /* size (0 = byte, 1 = short, 2 = long) */
1233 FALSE
, /* pc_relative */
1235 complain_overflow_unsigned
, /* complain_on_overflow */
1236 bfd_elf_generic_reloc
, /* special_function */
1237 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12
), /* name */
1238 FALSE
, /* partial_inplace */
1239 0x3ffc00, /* src_mask */
1240 0x3ffc00, /* dst_mask */
1241 FALSE
), /* pcrel_offset */
1243 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, but no overflow check. */
1244 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12_NC
), /* type */
1246 2, /* size (0 = byte, 1 = short, 2 = long) */
1248 FALSE
, /* pc_relative */
1250 complain_overflow_dont
, /* complain_on_overflow */
1251 bfd_elf_generic_reloc
, /* special_function */
1252 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12_NC
), /* name */
1253 FALSE
, /* partial_inplace */
1254 0x7fc00, /* src_mask */
1255 0x7fc00, /* dst_mask */
1256 FALSE
), /* pcrel_offset */
1258 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1259 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12
), /* type */
1261 2, /* size (0 = byte, 1 = short, 2 = long) */
1263 FALSE
, /* pc_relative */
1265 complain_overflow_unsigned
, /* complain_on_overflow */
1266 bfd_elf_generic_reloc
, /* special_function */
1267 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12
), /* name */
1268 FALSE
, /* partial_inplace */
1269 0x3ffc00, /* src_mask */
1270 0x3ffc00, /* dst_mask */
1271 FALSE
), /* pcrel_offset */
1273 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, but no overflow check. */
1274 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12_NC
), /* type */
1276 2, /* size (0 = byte, 1 = short, 2 = long) */
1278 FALSE
, /* pc_relative */
1280 complain_overflow_dont
, /* complain_on_overflow */
1281 bfd_elf_generic_reloc
, /* special_function */
1282 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12_NC
), /* name */
1283 FALSE
, /* partial_inplace */
1284 0x3ffc00, /* src_mask */
1285 0x3ffc00, /* dst_mask */
1286 FALSE
), /* pcrel_offset */
1288 /* MOVZ: bit[15:0] of byte offset to module TLS base address. */
1289 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0
), /* type */
1291 2, /* size (0 = byte, 1 = short, 2 = long) */
1293 FALSE
, /* pc_relative */
1295 complain_overflow_unsigned
, /* complain_on_overflow */
1296 bfd_elf_generic_reloc
, /* special_function */
1297 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0
), /* name */
1298 FALSE
, /* partial_inplace */
1299 0xffff, /* src_mask */
1300 0xffff, /* dst_mask */
1301 FALSE
), /* pcrel_offset */
1303 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */
1304 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0_NC
), /* type */
1306 2, /* size (0 = byte, 1 = short, 2 = long) */
1308 FALSE
, /* pc_relative */
1310 complain_overflow_dont
, /* complain_on_overflow */
1311 bfd_elf_generic_reloc
, /* special_function */
1312 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0_NC
), /* name */
1313 FALSE
, /* partial_inplace */
1314 0xffff, /* src_mask */
1315 0xffff, /* dst_mask */
1316 FALSE
), /* pcrel_offset */
1318 /* MOVZ: bit[31:16] of byte offset to module TLS base address. */
1319 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G1
), /* type */
1320 16, /* rightshift */
1321 2, /* size (0 = byte, 1 = short, 2 = long) */
1323 FALSE
, /* pc_relative */
1325 complain_overflow_unsigned
, /* complain_on_overflow */
1326 bfd_elf_generic_reloc
, /* special_function */
1327 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1
), /* name */
1328 FALSE
, /* partial_inplace */
1329 0xffff, /* src_mask */
1330 0xffff, /* dst_mask */
1331 FALSE
), /* pcrel_offset */
1333 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */
1334 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G1_NC
), /* type */
1335 16, /* rightshift */
1336 2, /* size (0 = byte, 1 = short, 2 = long) */
1338 FALSE
, /* pc_relative */
1340 complain_overflow_dont
, /* complain_on_overflow */
1341 bfd_elf_generic_reloc
, /* special_function */
1342 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1_NC
), /* name */
1343 FALSE
, /* partial_inplace */
1344 0xffff, /* src_mask */
1345 0xffff, /* dst_mask */
1346 FALSE
), /* pcrel_offset */
1348 /* MOVZ: bit[47:32] of byte offset to module TLS base address. */
1349 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G2
), /* type */
1350 32, /* rightshift */
1351 2, /* size (0 = byte, 1 = short, 2 = long) */
1353 FALSE
, /* pc_relative */
1355 complain_overflow_unsigned
, /* complain_on_overflow */
1356 bfd_elf_generic_reloc
, /* special_function */
1357 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G2
), /* name */
1358 FALSE
, /* partial_inplace */
1359 0xffff, /* src_mask */
1360 0xffff, /* dst_mask */
1361 FALSE
), /* pcrel_offset */
1363 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2
), /* type */
1364 32, /* rightshift */
1365 2, /* size (0 = byte, 1 = short, 2 = long) */
1367 FALSE
, /* pc_relative */
1369 complain_overflow_unsigned
, /* complain_on_overflow */
1370 bfd_elf_generic_reloc
, /* special_function */
1371 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2
), /* name */
1372 FALSE
, /* partial_inplace */
1373 0xffff, /* src_mask */
1374 0xffff, /* dst_mask */
1375 FALSE
), /* pcrel_offset */
1377 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1
), /* type */
1378 16, /* rightshift */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1381 FALSE
, /* pc_relative */
1383 complain_overflow_dont
, /* complain_on_overflow */
1384 bfd_elf_generic_reloc
, /* special_function */
1385 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1
), /* name */
1386 FALSE
, /* partial_inplace */
1387 0xffff, /* src_mask */
1388 0xffff, /* dst_mask */
1389 FALSE
), /* pcrel_offset */
1391 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC
), /* type */
1392 16, /* rightshift */
1393 2, /* size (0 = byte, 1 = short, 2 = long) */
1395 FALSE
, /* pc_relative */
1397 complain_overflow_dont
, /* complain_on_overflow */
1398 bfd_elf_generic_reloc
, /* special_function */
1399 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC
), /* name */
1400 FALSE
, /* partial_inplace */
1401 0xffff, /* src_mask */
1402 0xffff, /* dst_mask */
1403 FALSE
), /* pcrel_offset */
1405 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0
), /* type */
1407 2, /* size (0 = byte, 1 = short, 2 = long) */
1409 FALSE
, /* pc_relative */
1411 complain_overflow_dont
, /* complain_on_overflow */
1412 bfd_elf_generic_reloc
, /* special_function */
1413 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0
), /* name */
1414 FALSE
, /* partial_inplace */
1415 0xffff, /* src_mask */
1416 0xffff, /* dst_mask */
1417 FALSE
), /* pcrel_offset */
1419 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
), /* type */
1421 2, /* size (0 = byte, 1 = short, 2 = long) */
1423 FALSE
, /* pc_relative */
1425 complain_overflow_dont
, /* complain_on_overflow */
1426 bfd_elf_generic_reloc
, /* special_function */
1427 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC
), /* name */
1428 FALSE
, /* partial_inplace */
1429 0xffff, /* src_mask */
1430 0xffff, /* dst_mask */
1431 FALSE
), /* pcrel_offset */
1433 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12
), /* type */
1434 12, /* rightshift */
1435 2, /* size (0 = byte, 1 = short, 2 = long) */
1437 FALSE
, /* pc_relative */
1439 complain_overflow_unsigned
, /* complain_on_overflow */
1440 bfd_elf_generic_reloc
, /* special_function */
1441 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12
), /* name */
1442 FALSE
, /* partial_inplace */
1443 0xfff, /* src_mask */
1444 0xfff, /* dst_mask */
1445 FALSE
), /* pcrel_offset */
1447 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12
), /* type */
1449 2, /* size (0 = byte, 1 = short, 2 = long) */
1451 FALSE
, /* pc_relative */
1453 complain_overflow_unsigned
, /* complain_on_overflow */
1454 bfd_elf_generic_reloc
, /* special_function */
1455 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12
), /* name */
1456 FALSE
, /* partial_inplace */
1457 0xfff, /* src_mask */
1458 0xfff, /* dst_mask */
1459 FALSE
), /* pcrel_offset */
1461 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
), /* type */
1463 2, /* size (0 = byte, 1 = short, 2 = long) */
1465 FALSE
, /* pc_relative */
1467 complain_overflow_dont
, /* complain_on_overflow */
1468 bfd_elf_generic_reloc
, /* special_function */
1469 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC
), /* name */
1470 FALSE
, /* partial_inplace */
1471 0xfff, /* src_mask */
1472 0xfff, /* dst_mask */
1473 FALSE
), /* pcrel_offset */
1475 HOWTO (AARCH64_R (TLSDESC_LD_PREL19
), /* type */
1477 2, /* size (0 = byte, 1 = short, 2 = long) */
1479 TRUE
, /* pc_relative */
1481 complain_overflow_dont
, /* complain_on_overflow */
1482 bfd_elf_generic_reloc
, /* special_function */
1483 AARCH64_R_STR (TLSDESC_LD_PREL19
), /* name */
1484 FALSE
, /* partial_inplace */
1485 0x0ffffe0, /* src_mask */
1486 0x0ffffe0, /* dst_mask */
1487 TRUE
), /* pcrel_offset */
1489 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21
), /* type */
1491 2, /* size (0 = byte, 1 = short, 2 = long) */
1493 TRUE
, /* pc_relative */
1495 complain_overflow_dont
, /* complain_on_overflow */
1496 bfd_elf_generic_reloc
, /* special_function */
1497 AARCH64_R_STR (TLSDESC_ADR_PREL21
), /* name */
1498 FALSE
, /* partial_inplace */
1499 0x1fffff, /* src_mask */
1500 0x1fffff, /* dst_mask */
1501 TRUE
), /* pcrel_offset */
1503 /* Get to the page for the GOT entry for the symbol
1504 (G(S) - P) using an ADRP instruction. */
1505 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21
), /* type */
1506 12, /* rightshift */
1507 2, /* size (0 = byte, 1 = short, 2 = long) */
1509 TRUE
, /* pc_relative */
1511 complain_overflow_dont
, /* complain_on_overflow */
1512 bfd_elf_generic_reloc
, /* special_function */
1513 AARCH64_R_STR (TLSDESC_ADR_PAGE21
), /* name */
1514 FALSE
, /* partial_inplace */
1515 0x1fffff, /* src_mask */
1516 0x1fffff, /* dst_mask */
1517 TRUE
), /* pcrel_offset */
1519 /* LD64: GOT offset G(S) & 0xff8. */
1520 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC
), /* type */
1522 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 FALSE
, /* pc_relative */
1526 complain_overflow_dont
, /* complain_on_overflow */
1527 bfd_elf_generic_reloc
, /* special_function */
1528 AARCH64_R_STR (TLSDESC_LD64_LO12_NC
), /* name */
1529 FALSE
, /* partial_inplace */
1530 0xff8, /* src_mask */
1531 0xff8, /* dst_mask */
1532 FALSE
), /* pcrel_offset */
1534 /* LD32: GOT offset G(S) & 0xffc. */
1535 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC
), /* type */
1537 2, /* size (0 = byte, 1 = short, 2 = long) */
1539 FALSE
, /* pc_relative */
1541 complain_overflow_dont
, /* complain_on_overflow */
1542 bfd_elf_generic_reloc
, /* special_function */
1543 AARCH64_R_STR (TLSDESC_LD32_LO12_NC
), /* name */
1544 FALSE
, /* partial_inplace */
1545 0xffc, /* src_mask */
1546 0xffc, /* dst_mask */
1547 FALSE
), /* pcrel_offset */
1549 /* ADD: GOT offset G(S) & 0xfff. */
1550 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC
), /* type */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1554 FALSE
, /* pc_relative */
1556 complain_overflow_dont
, /* complain_on_overflow */
1557 bfd_elf_generic_reloc
, /* special_function */
1558 AARCH64_R_STR (TLSDESC_ADD_LO12_NC
), /* name */
1559 FALSE
, /* partial_inplace */
1560 0xfff, /* src_mask */
1561 0xfff, /* dst_mask */
1562 FALSE
), /* pcrel_offset */
1564 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1
), /* type */
1565 16, /* rightshift */
1566 2, /* size (0 = byte, 1 = short, 2 = long) */
1568 FALSE
, /* pc_relative */
1570 complain_overflow_dont
, /* complain_on_overflow */
1571 bfd_elf_generic_reloc
, /* special_function */
1572 AARCH64_R_STR (TLSDESC_OFF_G1
), /* name */
1573 FALSE
, /* partial_inplace */
1574 0xffff, /* src_mask */
1575 0xffff, /* dst_mask */
1576 FALSE
), /* pcrel_offset */
1578 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC
), /* type */
1580 2, /* size (0 = byte, 1 = short, 2 = long) */
1582 FALSE
, /* pc_relative */
1584 complain_overflow_dont
, /* complain_on_overflow */
1585 bfd_elf_generic_reloc
, /* special_function */
1586 AARCH64_R_STR (TLSDESC_OFF_G0_NC
), /* name */
1587 FALSE
, /* partial_inplace */
1588 0xffff, /* src_mask */
1589 0xffff, /* dst_mask */
1590 FALSE
), /* pcrel_offset */
1592 HOWTO64 (AARCH64_R (TLSDESC_LDR
), /* type */
1594 2, /* size (0 = byte, 1 = short, 2 = long) */
1596 FALSE
, /* pc_relative */
1598 complain_overflow_dont
, /* complain_on_overflow */
1599 bfd_elf_generic_reloc
, /* special_function */
1600 AARCH64_R_STR (TLSDESC_LDR
), /* name */
1601 FALSE
, /* partial_inplace */
1604 FALSE
), /* pcrel_offset */
1606 HOWTO64 (AARCH64_R (TLSDESC_ADD
), /* type */
1608 2, /* size (0 = byte, 1 = short, 2 = long) */
1610 FALSE
, /* pc_relative */
1612 complain_overflow_dont
, /* complain_on_overflow */
1613 bfd_elf_generic_reloc
, /* special_function */
1614 AARCH64_R_STR (TLSDESC_ADD
), /* name */
1615 FALSE
, /* partial_inplace */
1618 FALSE
), /* pcrel_offset */
1620 HOWTO (AARCH64_R (TLSDESC_CALL
), /* type */
1622 2, /* size (0 = byte, 1 = short, 2 = long) */
1624 FALSE
, /* pc_relative */
1626 complain_overflow_dont
, /* complain_on_overflow */
1627 bfd_elf_generic_reloc
, /* special_function */
1628 AARCH64_R_STR (TLSDESC_CALL
), /* name */
1629 FALSE
, /* partial_inplace */
1632 FALSE
), /* pcrel_offset */
1634 HOWTO (AARCH64_R (COPY
), /* type */
1636 2, /* size (0 = byte, 1 = short, 2 = long) */
1638 FALSE
, /* pc_relative */
1640 complain_overflow_bitfield
, /* complain_on_overflow */
1641 bfd_elf_generic_reloc
, /* special_function */
1642 AARCH64_R_STR (COPY
), /* name */
1643 TRUE
, /* partial_inplace */
1644 0xffffffff, /* src_mask */
1645 0xffffffff, /* dst_mask */
1646 FALSE
), /* pcrel_offset */
1648 HOWTO (AARCH64_R (GLOB_DAT
), /* type */
1650 2, /* size (0 = byte, 1 = short, 2 = long) */
1652 FALSE
, /* pc_relative */
1654 complain_overflow_bitfield
, /* complain_on_overflow */
1655 bfd_elf_generic_reloc
, /* special_function */
1656 AARCH64_R_STR (GLOB_DAT
), /* name */
1657 TRUE
, /* partial_inplace */
1658 0xffffffff, /* src_mask */
1659 0xffffffff, /* dst_mask */
1660 FALSE
), /* pcrel_offset */
1662 HOWTO (AARCH64_R (JUMP_SLOT
), /* type */
1664 2, /* size (0 = byte, 1 = short, 2 = long) */
1666 FALSE
, /* pc_relative */
1668 complain_overflow_bitfield
, /* complain_on_overflow */
1669 bfd_elf_generic_reloc
, /* special_function */
1670 AARCH64_R_STR (JUMP_SLOT
), /* name */
1671 TRUE
, /* partial_inplace */
1672 0xffffffff, /* src_mask */
1673 0xffffffff, /* dst_mask */
1674 FALSE
), /* pcrel_offset */
1676 HOWTO (AARCH64_R (RELATIVE
), /* type */
1678 2, /* size (0 = byte, 1 = short, 2 = long) */
1680 FALSE
, /* pc_relative */
1682 complain_overflow_bitfield
, /* complain_on_overflow */
1683 bfd_elf_generic_reloc
, /* special_function */
1684 AARCH64_R_STR (RELATIVE
), /* name */
1685 TRUE
, /* partial_inplace */
1686 ALL_ONES
, /* src_mask */
1687 ALL_ONES
, /* dst_mask */
1688 FALSE
), /* pcrel_offset */
1690 HOWTO (AARCH64_R (TLS_DTPMOD
), /* type */
1692 2, /* size (0 = byte, 1 = short, 2 = long) */
1694 FALSE
, /* pc_relative */
1696 complain_overflow_dont
, /* complain_on_overflow */
1697 bfd_elf_generic_reloc
, /* special_function */
1699 AARCH64_R_STR (TLS_DTPMOD64
), /* name */
1701 AARCH64_R_STR (TLS_DTPMOD
), /* name */
1703 FALSE
, /* partial_inplace */
1705 ALL_ONES
, /* dst_mask */
1706 FALSE
), /* pc_reloffset */
1708 HOWTO (AARCH64_R (TLS_DTPREL
), /* type */
1710 2, /* size (0 = byte, 1 = short, 2 = long) */
1712 FALSE
, /* pc_relative */
1714 complain_overflow_dont
, /* complain_on_overflow */
1715 bfd_elf_generic_reloc
, /* special_function */
1717 AARCH64_R_STR (TLS_DTPREL64
), /* name */
1719 AARCH64_R_STR (TLS_DTPREL
), /* name */
1721 FALSE
, /* partial_inplace */
1723 ALL_ONES
, /* dst_mask */
1724 FALSE
), /* pcrel_offset */
1726 HOWTO (AARCH64_R (TLS_TPREL
), /* type */
1728 2, /* size (0 = byte, 1 = short, 2 = long) */
1730 FALSE
, /* pc_relative */
1732 complain_overflow_dont
, /* complain_on_overflow */
1733 bfd_elf_generic_reloc
, /* special_function */
1735 AARCH64_R_STR (TLS_TPREL64
), /* name */
1737 AARCH64_R_STR (TLS_TPREL
), /* name */
1739 FALSE
, /* partial_inplace */
1741 ALL_ONES
, /* dst_mask */
1742 FALSE
), /* pcrel_offset */
1744 HOWTO (AARCH64_R (TLSDESC
), /* type */
1746 2, /* size (0 = byte, 1 = short, 2 = long) */
1748 FALSE
, /* pc_relative */
1750 complain_overflow_dont
, /* complain_on_overflow */
1751 bfd_elf_generic_reloc
, /* special_function */
1752 AARCH64_R_STR (TLSDESC
), /* name */
1753 FALSE
, /* partial_inplace */
1755 ALL_ONES
, /* dst_mask */
1756 FALSE
), /* pcrel_offset */
1758 HOWTO (AARCH64_R (IRELATIVE
), /* type */
1760 2, /* size (0 = byte, 1 = short, 2 = long) */
1762 FALSE
, /* pc_relative */
1764 complain_overflow_bitfield
, /* complain_on_overflow */
1765 bfd_elf_generic_reloc
, /* special_function */
1766 AARCH64_R_STR (IRELATIVE
), /* name */
1767 FALSE
, /* partial_inplace */
1769 ALL_ONES
, /* dst_mask */
1770 FALSE
), /* pcrel_offset */
1775 static reloc_howto_type elfNN_aarch64_howto_none
=
1776 HOWTO (R_AARCH64_NONE
, /* type */
1778 3, /* size (0 = byte, 1 = short, 2 = long) */
1780 FALSE
, /* pc_relative */
1782 complain_overflow_dont
,/* complain_on_overflow */
1783 bfd_elf_generic_reloc
, /* special_function */
1784 "R_AARCH64_NONE", /* name */
1785 FALSE
, /* partial_inplace */
1788 FALSE
); /* pcrel_offset */
1790 /* Given HOWTO, return the bfd internal relocation enumerator. */
1792 static bfd_reloc_code_real_type
1793 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type
*howto
)
1796 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table
);
1797 const ptrdiff_t offset
1798 = howto
- elfNN_aarch64_howto_table
;
1800 if (offset
> 0 && offset
< size
- 1)
1801 return BFD_RELOC_AARCH64_RELOC_START
+ offset
;
1803 if (howto
== &elfNN_aarch64_howto_none
)
1804 return BFD_RELOC_AARCH64_NONE
;
1806 return BFD_RELOC_AARCH64_RELOC_START
;
1809 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1811 static bfd_reloc_code_real_type
1812 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type
)
1814 static bfd_boolean initialized_p
= FALSE
;
1815 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1816 static unsigned int offsets
[R_AARCH64_end
];
1818 if (initialized_p
== FALSE
)
1822 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1823 if (elfNN_aarch64_howto_table
[i
].type
!= 0)
1824 offsets
[elfNN_aarch64_howto_table
[i
].type
] = i
;
1826 initialized_p
= TRUE
;
1829 if (r_type
== R_AARCH64_NONE
|| r_type
== R_AARCH64_NULL
)
1830 return BFD_RELOC_AARCH64_NONE
;
1832 /* PR 17512: file: b371e70a. */
1833 if (r_type
>= R_AARCH64_end
)
1835 _bfd_error_handler (_("Invalid AArch64 reloc number: %d"), r_type
);
1836 bfd_set_error (bfd_error_bad_value
);
1837 return BFD_RELOC_AARCH64_NONE
;
1840 return BFD_RELOC_AARCH64_RELOC_START
+ offsets
[r_type
];
1843 struct elf_aarch64_reloc_map
1845 bfd_reloc_code_real_type from
;
1846 bfd_reloc_code_real_type to
;
1849 /* Map bfd generic reloc to AArch64-specific reloc. */
1850 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map
[] =
1852 {BFD_RELOC_NONE
, BFD_RELOC_AARCH64_NONE
},
1854 /* Basic data relocations. */
1855 {BFD_RELOC_CTOR
, BFD_RELOC_AARCH64_NN
},
1856 {BFD_RELOC_64
, BFD_RELOC_AARCH64_64
},
1857 {BFD_RELOC_32
, BFD_RELOC_AARCH64_32
},
1858 {BFD_RELOC_16
, BFD_RELOC_AARCH64_16
},
1859 {BFD_RELOC_64_PCREL
, BFD_RELOC_AARCH64_64_PCREL
},
1860 {BFD_RELOC_32_PCREL
, BFD_RELOC_AARCH64_32_PCREL
},
1861 {BFD_RELOC_16_PCREL
, BFD_RELOC_AARCH64_16_PCREL
},
1864 /* Given the bfd internal relocation enumerator in CODE, return the
1865 corresponding howto entry. */
1867 static reloc_howto_type
*
1868 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code
)
1872 /* Convert bfd generic reloc to AArch64-specific reloc. */
1873 if (code
< BFD_RELOC_AARCH64_RELOC_START
1874 || code
> BFD_RELOC_AARCH64_RELOC_END
)
1875 for (i
= 0; i
< ARRAY_SIZE (elf_aarch64_reloc_map
); i
++)
1876 if (elf_aarch64_reloc_map
[i
].from
== code
)
1878 code
= elf_aarch64_reloc_map
[i
].to
;
1882 if (code
> BFD_RELOC_AARCH64_RELOC_START
1883 && code
< BFD_RELOC_AARCH64_RELOC_END
)
1884 if (elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
].type
)
1885 return &elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
];
1887 if (code
== BFD_RELOC_AARCH64_NONE
)
1888 return &elfNN_aarch64_howto_none
;
1893 static reloc_howto_type
*
1894 elfNN_aarch64_howto_from_type (unsigned int r_type
)
1896 bfd_reloc_code_real_type val
;
1897 reloc_howto_type
*howto
;
1902 bfd_set_error (bfd_error_bad_value
);
1907 if (r_type
== R_AARCH64_NONE
)
1908 return &elfNN_aarch64_howto_none
;
1910 val
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
1911 howto
= elfNN_aarch64_howto_from_bfd_reloc (val
);
1916 bfd_set_error (bfd_error_bad_value
);
1921 elfNN_aarch64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*bfd_reloc
,
1922 Elf_Internal_Rela
*elf_reloc
)
1924 unsigned int r_type
;
1926 r_type
= ELFNN_R_TYPE (elf_reloc
->r_info
);
1927 bfd_reloc
->howto
= elfNN_aarch64_howto_from_type (r_type
);
1930 static reloc_howto_type
*
1931 elfNN_aarch64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1932 bfd_reloc_code_real_type code
)
1934 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (code
);
1939 bfd_set_error (bfd_error_bad_value
);
1943 static reloc_howto_type
*
1944 elfNN_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1949 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
1950 if (elfNN_aarch64_howto_table
[i
].name
!= NULL
1951 && strcasecmp (elfNN_aarch64_howto_table
[i
].name
, r_name
) == 0)
1952 return &elfNN_aarch64_howto_table
[i
];
1957 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
1958 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1959 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
1960 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1962 /* The linker script knows the section names for placement.
1963 The entry_names are used to do simple name mangling on the stubs.
1964 Given a function name, and its type, the stub can be found. The
1965 name can be changed. The only requirement is the %s be present. */
1966 #define STUB_ENTRY_NAME "__%s_veneer"
1968 /* The name of the dynamic interpreter. This is put in the .interp
1970 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1972 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1973 (((1 << 25) - 1) << 2)
1974 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1977 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1978 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1981 aarch64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
1983 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
1984 return offset
<= AARCH64_MAX_ADRP_IMM
&& offset
>= AARCH64_MIN_ADRP_IMM
;
1988 aarch64_valid_branch_p (bfd_vma value
, bfd_vma place
)
1990 bfd_signed_vma offset
= (bfd_signed_vma
) (value
- place
);
1991 return (offset
<= AARCH64_MAX_FWD_BRANCH_OFFSET
1992 && offset
>= AARCH64_MAX_BWD_BRANCH_OFFSET
);
1995 static const uint32_t aarch64_adrp_branch_stub
[] =
1997 0x90000010, /* adrp ip0, X */
1998 /* R_AARCH64_ADR_HI21_PCREL(X) */
1999 0x91000210, /* add ip0, ip0, :lo12:X */
2000 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2001 0xd61f0200, /* br ip0 */
2004 static const uint32_t aarch64_long_branch_stub
[] =
2007 0x58000090, /* ldr ip0, 1f */
2009 0x18000090, /* ldr wip0, 1f */
2011 0x10000011, /* adr ip1, #0 */
2012 0x8b110210, /* add ip0, ip0, ip1 */
2013 0xd61f0200, /* br ip0 */
2014 0x00000000, /* 1: .xword or .word
2015 R_AARCH64_PRELNN(X) + 12
2020 static const uint32_t aarch64_erratum_835769_stub
[] =
2022 0x00000000, /* Placeholder for multiply accumulate. */
2023 0x14000000, /* b <label> */
2026 static const uint32_t aarch64_erratum_843419_stub
[] =
2028 0x00000000, /* Placeholder for LDR instruction. */
2029 0x14000000, /* b <label> */
2032 /* Section name for stubs is the associated section name plus this
2034 #define STUB_SUFFIX ".stub"
2036 enum elf_aarch64_stub_type
2039 aarch64_stub_adrp_branch
,
2040 aarch64_stub_long_branch
,
2041 aarch64_stub_erratum_835769_veneer
,
2042 aarch64_stub_erratum_843419_veneer
,
2045 struct elf_aarch64_stub_hash_entry
2047 /* Base hash table entry structure. */
2048 struct bfd_hash_entry root
;
2050 /* The stub section. */
2053 /* Offset within stub_sec of the beginning of this stub. */
2054 bfd_vma stub_offset
;
2056 /* Given the symbol's value and its section we can determine its final
2057 value when building the stubs (so the stub knows where to jump). */
2058 bfd_vma target_value
;
2059 asection
*target_section
;
2061 enum elf_aarch64_stub_type stub_type
;
2063 /* The symbol table entry, if any, that this was derived from. */
2064 struct elf_aarch64_link_hash_entry
*h
;
2066 /* Destination symbol type */
2067 unsigned char st_type
;
2069 /* Where this stub is being called from, or, in the case of combined
2070 stub sections, the first input section in the group. */
2073 /* The name for the local symbol at the start of this stub. The
2074 stub name in the hash table has to be unique; this does not, so
2075 it can be friendlier. */
2078 /* The instruction which caused this stub to be generated (only valid for
2079 erratum 835769 workaround stubs at present). */
2080 uint32_t veneered_insn
;
2082 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
2083 bfd_vma adrp_offset
;
2086 /* Used to build a map of a section. This is required for mixed-endian
2089 typedef struct elf_elf_section_map
2094 elf_aarch64_section_map
;
2097 typedef struct _aarch64_elf_section_data
2099 struct bfd_elf_section_data elf
;
2100 unsigned int mapcount
;
2101 unsigned int mapsize
;
2102 elf_aarch64_section_map
*map
;
2104 _aarch64_elf_section_data
;
2106 #define elf_aarch64_section_data(sec) \
2107 ((_aarch64_elf_section_data *) elf_section_data (sec))
2109 /* The size of the thread control block which is defined to be two pointers. */
2110 #define TCB_SIZE (ARCH_SIZE/8)*2
2112 struct elf_aarch64_local_symbol
2114 unsigned int got_type
;
2115 bfd_signed_vma got_refcount
;
2118 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2119 offset is from the end of the jump table and reserved entries
2122 The magic value (bfd_vma) -1 indicates that an offset has not be
2124 bfd_vma tlsdesc_got_jump_table_offset
;
2127 struct elf_aarch64_obj_tdata
2129 struct elf_obj_tdata root
;
2131 /* local symbol descriptors */
2132 struct elf_aarch64_local_symbol
*locals
;
2134 /* Zero to warn when linking objects with incompatible enum sizes. */
2135 int no_enum_size_warning
;
2137 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
2138 int no_wchar_size_warning
;
2141 #define elf_aarch64_tdata(bfd) \
2142 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
2144 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
2146 #define is_aarch64_elf(bfd) \
2147 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2148 && elf_tdata (bfd) != NULL \
2149 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2152 elfNN_aarch64_mkobject (bfd
*abfd
)
2154 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
),
2158 #define elf_aarch64_hash_entry(ent) \
2159 ((struct elf_aarch64_link_hash_entry *)(ent))
2161 #define GOT_UNKNOWN 0
2162 #define GOT_NORMAL 1
2163 #define GOT_TLS_GD 2
2164 #define GOT_TLS_IE 4
2165 #define GOT_TLSDESC_GD 8
2167 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
2169 /* AArch64 ELF linker hash entry. */
2170 struct elf_aarch64_link_hash_entry
2172 struct elf_link_hash_entry root
;
2174 /* Track dynamic relocs copied for this symbol. */
2175 struct elf_dyn_relocs
*dyn_relocs
;
2177 /* Since PLT entries have variable size, we need to record the
2178 index into .got.plt instead of recomputing it from the PLT
2180 bfd_signed_vma plt_got_offset
;
2182 /* Bit mask representing the type of GOT entry(s) if any required by
2184 unsigned int got_type
;
2186 /* A pointer to the most recently used stub hash entry against this
2188 struct elf_aarch64_stub_hash_entry
*stub_cache
;
2190 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
2191 is from the end of the jump table and reserved entries within the PLTGOT.
2193 The magic value (bfd_vma) -1 indicates that an offset has not
2195 bfd_vma tlsdesc_got_jump_table_offset
;
2199 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
2201 unsigned long r_symndx
)
2204 return elf_aarch64_hash_entry (h
)->got_type
;
2206 if (! elf_aarch64_locals (abfd
))
2209 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
2212 /* Get the AArch64 elf linker hash table from a link_info structure. */
2213 #define elf_aarch64_hash_table(info) \
2214 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
2216 #define aarch64_stub_hash_lookup(table, string, create, copy) \
2217 ((struct elf_aarch64_stub_hash_entry *) \
2218 bfd_hash_lookup ((table), (string), (create), (copy)))
2220 /* AArch64 ELF linker hash table. */
2221 struct elf_aarch64_link_hash_table
2223 /* The main hash table. */
2224 struct elf_link_hash_table root
;
2226 /* Nonzero to force PIC branch veneers. */
2229 /* Fix erratum 835769. */
2230 int fix_erratum_835769
;
2232 /* Fix erratum 843419. */
2233 int fix_erratum_843419
;
2235 /* Enable ADRP->ADR rewrite for erratum 843419 workaround. */
2236 int fix_erratum_843419_adr
;
2238 /* The number of bytes in the initial entry in the PLT. */
2239 bfd_size_type plt_header_size
;
2241 /* The number of bytes in the subsequent PLT etries. */
2242 bfd_size_type plt_entry_size
;
2244 /* Short-cuts to get to dynamic linker sections. */
2248 /* Small local sym cache. */
2249 struct sym_cache sym_cache
;
2251 /* For convenience in allocate_dynrelocs. */
2254 /* The amount of space used by the reserved portion of the sgotplt
2255 section, plus whatever space is used by the jump slots. */
2256 bfd_vma sgotplt_jump_table_size
;
2258 /* The stub hash table. */
2259 struct bfd_hash_table stub_hash_table
;
2261 /* Linker stub bfd. */
2264 /* Linker call-backs. */
2265 asection
*(*add_stub_section
) (const char *, asection
*);
2266 void (*layout_sections_again
) (void);
2268 /* Array to keep track of which stub sections have been created, and
2269 information on stub grouping. */
2272 /* This is the section to which stubs in the group will be
2275 /* The stub section. */
2279 /* Assorted information used by elfNN_aarch64_size_stubs. */
2280 unsigned int bfd_count
;
2281 unsigned int top_index
;
2282 asection
**input_list
;
2284 /* The offset into splt of the PLT entry for the TLS descriptor
2285 resolver. Special values are 0, if not necessary (or not found
2286 to be necessary yet), and -1 if needed but not determined
2288 bfd_vma tlsdesc_plt
;
2290 /* The GOT offset for the lazy trampoline. Communicated to the
2291 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
2292 indicates an offset is not allocated. */
2293 bfd_vma dt_tlsdesc_got
;
2295 /* Used by local STT_GNU_IFUNC symbols. */
2296 htab_t loc_hash_table
;
2297 void * loc_hash_memory
;
2300 /* Create an entry in an AArch64 ELF linker hash table. */
2302 static struct bfd_hash_entry
*
2303 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
2304 struct bfd_hash_table
*table
,
2307 struct elf_aarch64_link_hash_entry
*ret
=
2308 (struct elf_aarch64_link_hash_entry
*) entry
;
2310 /* Allocate the structure if it has not already been allocated by a
2313 ret
= bfd_hash_allocate (table
,
2314 sizeof (struct elf_aarch64_link_hash_entry
));
2316 return (struct bfd_hash_entry
*) ret
;
2318 /* Call the allocation method of the superclass. */
2319 ret
= ((struct elf_aarch64_link_hash_entry
*)
2320 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
2324 ret
->dyn_relocs
= NULL
;
2325 ret
->got_type
= GOT_UNKNOWN
;
2326 ret
->plt_got_offset
= (bfd_vma
) - 1;
2327 ret
->stub_cache
= NULL
;
2328 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
2331 return (struct bfd_hash_entry
*) ret
;
2334 /* Initialize an entry in the stub hash table. */
2336 static struct bfd_hash_entry
*
2337 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
2338 struct bfd_hash_table
*table
, const char *string
)
2340 /* Allocate the structure if it has not already been allocated by a
2344 entry
= bfd_hash_allocate (table
,
2346 elf_aarch64_stub_hash_entry
));
2351 /* Call the allocation method of the superclass. */
2352 entry
= bfd_hash_newfunc (entry
, table
, string
);
2355 struct elf_aarch64_stub_hash_entry
*eh
;
2357 /* Initialize the local fields. */
2358 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
2359 eh
->adrp_offset
= 0;
2360 eh
->stub_sec
= NULL
;
2361 eh
->stub_offset
= 0;
2362 eh
->target_value
= 0;
2363 eh
->target_section
= NULL
;
2364 eh
->stub_type
= aarch64_stub_none
;
2372 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
2373 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2374 as global symbol. We reuse indx and dynstr_index for local symbol
2375 hash since they aren't used by global symbols in this backend. */
2378 elfNN_aarch64_local_htab_hash (const void *ptr
)
2380 struct elf_link_hash_entry
*h
2381 = (struct elf_link_hash_entry
*) ptr
;
2382 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
2385 /* Compare local hash entries. */
2388 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
2390 struct elf_link_hash_entry
*h1
2391 = (struct elf_link_hash_entry
*) ptr1
;
2392 struct elf_link_hash_entry
*h2
2393 = (struct elf_link_hash_entry
*) ptr2
;
2395 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
2398 /* Find and/or create a hash entry for local symbol. */
2400 static struct elf_link_hash_entry
*
2401 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
2402 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2405 struct elf_aarch64_link_hash_entry e
, *ret
;
2406 asection
*sec
= abfd
->sections
;
2407 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
2408 ELFNN_R_SYM (rel
->r_info
));
2411 e
.root
.indx
= sec
->id
;
2412 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2413 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
2414 create
? INSERT
: NO_INSERT
);
2421 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
2425 ret
= (struct elf_aarch64_link_hash_entry
*)
2426 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
2427 sizeof (struct elf_aarch64_link_hash_entry
));
2430 memset (ret
, 0, sizeof (*ret
));
2431 ret
->root
.indx
= sec
->id
;
2432 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2433 ret
->root
.dynindx
= -1;
2439 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2442 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
2443 struct elf_link_hash_entry
*dir
,
2444 struct elf_link_hash_entry
*ind
)
2446 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
2448 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
2449 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
2451 if (eind
->dyn_relocs
!= NULL
)
2453 if (edir
->dyn_relocs
!= NULL
)
2455 struct elf_dyn_relocs
**pp
;
2456 struct elf_dyn_relocs
*p
;
2458 /* Add reloc counts against the indirect sym to the direct sym
2459 list. Merge any entries against the same section. */
2460 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
;)
2462 struct elf_dyn_relocs
*q
;
2464 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
2465 if (q
->sec
== p
->sec
)
2467 q
->pc_count
+= p
->pc_count
;
2468 q
->count
+= p
->count
;
2475 *pp
= edir
->dyn_relocs
;
2478 edir
->dyn_relocs
= eind
->dyn_relocs
;
2479 eind
->dyn_relocs
= NULL
;
2482 if (ind
->root
.type
== bfd_link_hash_indirect
)
2484 /* Copy over PLT info. */
2485 if (dir
->got
.refcount
<= 0)
2487 edir
->got_type
= eind
->got_type
;
2488 eind
->got_type
= GOT_UNKNOWN
;
2492 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2495 /* Destroy an AArch64 elf linker hash table. */
2498 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
2500 struct elf_aarch64_link_hash_table
*ret
2501 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
2503 if (ret
->loc_hash_table
)
2504 htab_delete (ret
->loc_hash_table
);
2505 if (ret
->loc_hash_memory
)
2506 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
2508 bfd_hash_table_free (&ret
->stub_hash_table
);
2509 _bfd_elf_link_hash_table_free (obfd
);
2512 /* Create an AArch64 elf linker hash table. */
2514 static struct bfd_link_hash_table
*
2515 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
2517 struct elf_aarch64_link_hash_table
*ret
;
2518 bfd_size_type amt
= sizeof (struct elf_aarch64_link_hash_table
);
2520 ret
= bfd_zmalloc (amt
);
2524 if (!_bfd_elf_link_hash_table_init
2525 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
2526 sizeof (struct elf_aarch64_link_hash_entry
), AARCH64_ELF_DATA
))
2532 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
2533 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
2535 ret
->dt_tlsdesc_got
= (bfd_vma
) - 1;
2537 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
2538 sizeof (struct elf_aarch64_stub_hash_entry
)))
2540 _bfd_elf_link_hash_table_free (abfd
);
2544 ret
->loc_hash_table
= htab_try_create (1024,
2545 elfNN_aarch64_local_htab_hash
,
2546 elfNN_aarch64_local_htab_eq
,
2548 ret
->loc_hash_memory
= objalloc_create ();
2549 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
2551 elfNN_aarch64_link_hash_table_free (abfd
);
2554 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
2556 return &ret
->root
.root
;
2560 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
2561 bfd_vma offset
, bfd_vma value
)
2563 reloc_howto_type
*howto
;
2566 howto
= elfNN_aarch64_howto_from_type (r_type
);
2567 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
2570 r_type
= elfNN_aarch64_bfd_reloc_from_type (r_type
);
2571 value
= _bfd_aarch64_elf_resolve_relocation (r_type
, place
, value
, 0, FALSE
);
2572 return _bfd_aarch64_elf_put_addend (input_bfd
,
2573 input_section
->contents
+ offset
, r_type
,
2577 static enum elf_aarch64_stub_type
2578 aarch64_select_branch_stub (bfd_vma value
, bfd_vma place
)
2580 if (aarch64_valid_for_adrp_p (value
, place
))
2581 return aarch64_stub_adrp_branch
;
2582 return aarch64_stub_long_branch
;
2585 /* Determine the type of stub needed, if any, for a call. */
2587 static enum elf_aarch64_stub_type
2588 aarch64_type_of_stub (struct bfd_link_info
*info
,
2589 asection
*input_sec
,
2590 const Elf_Internal_Rela
*rel
,
2592 unsigned char st_type
,
2593 struct elf_aarch64_link_hash_entry
*hash
,
2594 bfd_vma destination
)
2597 bfd_signed_vma branch_offset
;
2598 unsigned int r_type
;
2599 struct elf_aarch64_link_hash_table
*globals
;
2600 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
2601 bfd_boolean via_plt_p
;
2603 if (st_type
!= STT_FUNC
2604 && (sym_sec
!= bfd_abs_section_ptr
))
2607 globals
= elf_aarch64_hash_table (info
);
2608 via_plt_p
= (globals
->root
.splt
!= NULL
&& hash
!= NULL
2609 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1);
2610 /* Make sure call to plt stub can fit into the branch range. */
2612 destination
= (globals
->root
.splt
->output_section
->vma
2613 + globals
->root
.splt
->output_offset
2614 + hash
->root
.plt
.offset
);
2616 /* Determine where the call point is. */
2617 location
= (input_sec
->output_offset
2618 + input_sec
->output_section
->vma
+ rel
->r_offset
);
2620 branch_offset
= (bfd_signed_vma
) (destination
- location
);
2622 r_type
= ELFNN_R_TYPE (rel
->r_info
);
2624 /* We don't want to redirect any old unconditional jump in this way,
2625 only one which is being used for a sibcall, where it is
2626 acceptable for the IP0 and IP1 registers to be clobbered. */
2627 if ((r_type
== AARCH64_R (CALL26
) || r_type
== AARCH64_R (JUMP26
))
2628 && (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
2629 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
))
2631 stub_type
= aarch64_stub_long_branch
;
2637 /* Build a name for an entry in the stub hash table. */
2640 elfNN_aarch64_stub_name (const asection
*input_section
,
2641 const asection
*sym_sec
,
2642 const struct elf_aarch64_link_hash_entry
*hash
,
2643 const Elf_Internal_Rela
*rel
)
2650 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
2651 stub_name
= bfd_malloc (len
);
2652 if (stub_name
!= NULL
)
2653 snprintf (stub_name
, len
, "%08x_%s+%" BFD_VMA_FMT
"x",
2654 (unsigned int) input_section
->id
,
2655 hash
->root
.root
.root
.string
,
2660 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2661 stub_name
= bfd_malloc (len
);
2662 if (stub_name
!= NULL
)
2663 snprintf (stub_name
, len
, "%08x_%x:%x+%" BFD_VMA_FMT
"x",
2664 (unsigned int) input_section
->id
,
2665 (unsigned int) sym_sec
->id
,
2666 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
2673 /* Look up an entry in the stub hash. Stub entries are cached because
2674 creating the stub name takes a bit of time. */
2676 static struct elf_aarch64_stub_hash_entry
*
2677 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
2678 const asection
*sym_sec
,
2679 struct elf_link_hash_entry
*hash
,
2680 const Elf_Internal_Rela
*rel
,
2681 struct elf_aarch64_link_hash_table
*htab
)
2683 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2684 struct elf_aarch64_link_hash_entry
*h
=
2685 (struct elf_aarch64_link_hash_entry
*) hash
;
2686 const asection
*id_sec
;
2688 if ((input_section
->flags
& SEC_CODE
) == 0)
2691 /* If this input section is part of a group of sections sharing one
2692 stub section, then use the id of the first section in the group.
2693 Stub names need to include a section id, as there may well be
2694 more than one stub used to reach say, printf, and we need to
2695 distinguish between them. */
2696 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
2698 if (h
!= NULL
&& h
->stub_cache
!= NULL
2699 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
2701 stub_entry
= h
->stub_cache
;
2707 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
);
2708 if (stub_name
== NULL
)
2711 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
2712 stub_name
, FALSE
, FALSE
);
2714 h
->stub_cache
= stub_entry
;
2723 /* Create a stub section. */
2726 _bfd_aarch64_create_stub_section (asection
*section
,
2727 struct elf_aarch64_link_hash_table
*htab
)
2733 namelen
= strlen (section
->name
);
2734 len
= namelen
+ sizeof (STUB_SUFFIX
);
2735 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
2739 memcpy (s_name
, section
->name
, namelen
);
2740 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
2741 return (*htab
->add_stub_section
) (s_name
, section
);
2745 /* Find or create a stub section for a link section.
2747 Fix or create the stub section used to collect stubs attached to
2748 the specified link section. */
2751 _bfd_aarch64_get_stub_for_link_section (asection
*link_section
,
2752 struct elf_aarch64_link_hash_table
*htab
)
2754 if (htab
->stub_group
[link_section
->id
].stub_sec
== NULL
)
2755 htab
->stub_group
[link_section
->id
].stub_sec
2756 = _bfd_aarch64_create_stub_section (link_section
, htab
);
2757 return htab
->stub_group
[link_section
->id
].stub_sec
;
2761 /* Find or create a stub section in the stub group for an input
2765 _bfd_aarch64_create_or_find_stub_sec (asection
*section
,
2766 struct elf_aarch64_link_hash_table
*htab
)
2768 asection
*link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2769 return _bfd_aarch64_get_stub_for_link_section (link_sec
, htab
);
2773 /* Add a new stub entry in the stub group associated with an input
2774 section to the stub hash. Not all fields of the new stub entry are
2777 static struct elf_aarch64_stub_hash_entry
*
2778 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name
,
2780 struct elf_aarch64_link_hash_table
*htab
)
2784 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2786 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
2787 stub_sec
= _bfd_aarch64_create_or_find_stub_sec (section
, htab
);
2789 /* Enter this entry into the linker stub hash table. */
2790 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2792 if (stub_entry
== NULL
)
2794 (*_bfd_error_handler
) (_("%s: cannot create stub entry %s"),
2795 section
->owner
, stub_name
);
2799 stub_entry
->stub_sec
= stub_sec
;
2800 stub_entry
->stub_offset
= 0;
2801 stub_entry
->id_sec
= link_sec
;
2806 /* Add a new stub entry in the final stub section to the stub hash.
2807 Not all fields of the new stub entry are initialised. */
2809 static struct elf_aarch64_stub_hash_entry
*
2810 _bfd_aarch64_add_stub_entry_after (const char *stub_name
,
2811 asection
*link_section
,
2812 struct elf_aarch64_link_hash_table
*htab
)
2815 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2817 stub_sec
= _bfd_aarch64_get_stub_for_link_section (link_section
, htab
);
2818 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
2820 if (stub_entry
== NULL
)
2822 (*_bfd_error_handler
) (_("cannot create stub entry %s"), stub_name
);
2826 stub_entry
->stub_sec
= stub_sec
;
2827 stub_entry
->stub_offset
= 0;
2828 stub_entry
->id_sec
= link_section
;
2835 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
2836 void *in_arg ATTRIBUTE_UNUSED
)
2838 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2843 bfd_vma veneered_insn_loc
;
2844 bfd_vma veneer_entry_loc
;
2845 bfd_signed_vma branch_offset
= 0;
2846 unsigned int template_size
;
2847 const uint32_t *template;
2850 /* Massage our args to the form they really have. */
2851 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2853 stub_sec
= stub_entry
->stub_sec
;
2855 /* Make a note of the offset within the stubs for this entry. */
2856 stub_entry
->stub_offset
= stub_sec
->size
;
2857 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
2859 stub_bfd
= stub_sec
->owner
;
2861 /* This is the address of the stub destination. */
2862 sym_value
= (stub_entry
->target_value
2863 + stub_entry
->target_section
->output_offset
2864 + stub_entry
->target_section
->output_section
->vma
);
2866 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
2868 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
2869 + stub_sec
->output_offset
);
2871 /* See if we can relax the stub. */
2872 if (aarch64_valid_for_adrp_p (sym_value
, place
))
2873 stub_entry
->stub_type
= aarch64_select_branch_stub (sym_value
, place
);
2876 switch (stub_entry
->stub_type
)
2878 case aarch64_stub_adrp_branch
:
2879 template = aarch64_adrp_branch_stub
;
2880 template_size
= sizeof (aarch64_adrp_branch_stub
);
2882 case aarch64_stub_long_branch
:
2883 template = aarch64_long_branch_stub
;
2884 template_size
= sizeof (aarch64_long_branch_stub
);
2886 case aarch64_stub_erratum_835769_veneer
:
2887 template = aarch64_erratum_835769_stub
;
2888 template_size
= sizeof (aarch64_erratum_835769_stub
);
2890 case aarch64_stub_erratum_843419_veneer
:
2891 template = aarch64_erratum_843419_stub
;
2892 template_size
= sizeof (aarch64_erratum_843419_stub
);
2898 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
2900 bfd_putl32 (template[i
], loc
);
2904 template_size
= (template_size
+ 7) & ~7;
2905 stub_sec
->size
+= template_size
;
2907 switch (stub_entry
->stub_type
)
2909 case aarch64_stub_adrp_branch
:
2910 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
2911 stub_entry
->stub_offset
, sym_value
))
2912 /* The stub would not have been relaxed if the offset was out
2916 if (aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
2917 stub_entry
->stub_offset
+ 4, sym_value
))
2921 case aarch64_stub_long_branch
:
2922 /* We want the value relative to the address 12 bytes back from the
2924 if (aarch64_relocate (AARCH64_R (PRELNN
), stub_bfd
, stub_sec
,
2925 stub_entry
->stub_offset
+ 16, sym_value
+ 12))
2929 case aarch64_stub_erratum_835769_veneer
:
2930 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
2931 + stub_entry
->target_section
->output_offset
2932 + stub_entry
->target_value
;
2933 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
2934 + stub_entry
->stub_sec
->output_offset
2935 + stub_entry
->stub_offset
;
2936 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
2937 branch_offset
>>= 2;
2938 branch_offset
&= 0x3ffffff;
2939 bfd_putl32 (stub_entry
->veneered_insn
,
2940 stub_sec
->contents
+ stub_entry
->stub_offset
);
2941 bfd_putl32 (template[1] | branch_offset
,
2942 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
2945 case aarch64_stub_erratum_843419_veneer
:
2946 if (aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
2947 stub_entry
->stub_offset
+ 4, sym_value
+ 4))
2958 /* As above, but don't actually build the stub. Just bump offset so
2959 we know stub section sizes. */
2962 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
,
2963 void *in_arg ATTRIBUTE_UNUSED
)
2965 struct elf_aarch64_stub_hash_entry
*stub_entry
;
2968 /* Massage our args to the form they really have. */
2969 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
2971 switch (stub_entry
->stub_type
)
2973 case aarch64_stub_adrp_branch
:
2974 size
= sizeof (aarch64_adrp_branch_stub
);
2976 case aarch64_stub_long_branch
:
2977 size
= sizeof (aarch64_long_branch_stub
);
2979 case aarch64_stub_erratum_835769_veneer
:
2980 size
= sizeof (aarch64_erratum_835769_stub
);
2982 case aarch64_stub_erratum_843419_veneer
:
2983 size
= sizeof (aarch64_erratum_843419_stub
);
2989 size
= (size
+ 7) & ~7;
2990 stub_entry
->stub_sec
->size
+= size
;
2994 /* External entry points for sizing and building linker stubs. */
2996 /* Set up various things so that we can make a list of input sections
2997 for each output section included in the link. Returns -1 on error,
2998 0 when no stubs will be needed, and 1 on success. */
3001 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
3002 struct bfd_link_info
*info
)
3005 unsigned int bfd_count
;
3006 unsigned int top_id
, top_index
;
3008 asection
**input_list
, **list
;
3010 struct elf_aarch64_link_hash_table
*htab
=
3011 elf_aarch64_hash_table (info
);
3013 if (!is_elf_hash_table (htab
))
3016 /* Count the number of input BFDs and find the top input section id. */
3017 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
3018 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3021 for (section
= input_bfd
->sections
;
3022 section
!= NULL
; section
= section
->next
)
3024 if (top_id
< section
->id
)
3025 top_id
= section
->id
;
3028 htab
->bfd_count
= bfd_count
;
3030 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
3031 htab
->stub_group
= bfd_zmalloc (amt
);
3032 if (htab
->stub_group
== NULL
)
3035 /* We can't use output_bfd->section_count here to find the top output
3036 section index as some sections may have been removed, and
3037 _bfd_strip_section_from_output doesn't renumber the indices. */
3038 for (section
= output_bfd
->sections
, top_index
= 0;
3039 section
!= NULL
; section
= section
->next
)
3041 if (top_index
< section
->index
)
3042 top_index
= section
->index
;
3045 htab
->top_index
= top_index
;
3046 amt
= sizeof (asection
*) * (top_index
+ 1);
3047 input_list
= bfd_malloc (amt
);
3048 htab
->input_list
= input_list
;
3049 if (input_list
== NULL
)
3052 /* For sections we aren't interested in, mark their entries with a
3053 value we can check later. */
3054 list
= input_list
+ top_index
;
3056 *list
= bfd_abs_section_ptr
;
3057 while (list
-- != input_list
);
3059 for (section
= output_bfd
->sections
;
3060 section
!= NULL
; section
= section
->next
)
3062 if ((section
->flags
& SEC_CODE
) != 0)
3063 input_list
[section
->index
] = NULL
;
3069 /* Used by elfNN_aarch64_next_input_section and group_sections. */
3070 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
3072 /* The linker repeatedly calls this function for each input section,
3073 in the order that input sections are linked into output sections.
3074 Build lists of input sections to determine groupings between which
3075 we may insert linker stubs. */
3078 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
3080 struct elf_aarch64_link_hash_table
*htab
=
3081 elf_aarch64_hash_table (info
);
3083 if (isec
->output_section
->index
<= htab
->top_index
)
3085 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
3087 if (*list
!= bfd_abs_section_ptr
)
3089 /* Steal the link_sec pointer for our list. */
3090 /* This happens to make the list in reverse order,
3091 which is what we want. */
3092 PREV_SEC (isec
) = *list
;
3098 /* See whether we can group stub sections together. Grouping stub
3099 sections may result in fewer stubs. More importantly, we need to
3100 put all .init* and .fini* stubs at the beginning of the .init or
3101 .fini output sections respectively, because glibc splits the
3102 _init and _fini functions into multiple parts. Putting a stub in
3103 the middle of a function is not a good idea. */
3106 group_sections (struct elf_aarch64_link_hash_table
*htab
,
3107 bfd_size_type stub_group_size
,
3108 bfd_boolean stubs_always_before_branch
)
3110 asection
**list
= htab
->input_list
+ htab
->top_index
;
3114 asection
*tail
= *list
;
3116 if (tail
== bfd_abs_section_ptr
)
3119 while (tail
!= NULL
)
3123 bfd_size_type total
;
3127 while ((prev
= PREV_SEC (curr
)) != NULL
3128 && ((total
+= curr
->output_offset
- prev
->output_offset
)
3132 /* OK, the size from the start of CURR to the end is less
3133 than stub_group_size and thus can be handled by one stub
3134 section. (Or the tail section is itself larger than
3135 stub_group_size, in which case we may be toast.)
3136 We should really be keeping track of the total size of
3137 stubs added here, as stubs contribute to the final output
3141 prev
= PREV_SEC (tail
);
3142 /* Set up this stub group. */
3143 htab
->stub_group
[tail
->id
].link_sec
= curr
;
3145 while (tail
!= curr
&& (tail
= prev
) != NULL
);
3147 /* But wait, there's more! Input sections up to stub_group_size
3148 bytes before the stub section can be handled by it too. */
3149 if (!stubs_always_before_branch
)
3153 && ((total
+= tail
->output_offset
- prev
->output_offset
)
3157 prev
= PREV_SEC (tail
);
3158 htab
->stub_group
[tail
->id
].link_sec
= curr
;
3164 while (list
-- != htab
->input_list
);
3166 free (htab
->input_list
);
3171 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
3173 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
3174 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
3175 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
3176 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
3177 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
3178 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
3180 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
3181 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
3182 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
3183 #define AARCH64_ZR 0x1f
3185 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
3186 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
3188 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
3189 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
3190 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
3191 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
3192 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
3193 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
3194 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
3195 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
3196 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
3197 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
3198 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
3199 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
3200 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
3201 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
3202 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
3203 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
3204 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
3205 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
3207 /* Classify an INSN if it is indeed a load/store.
3209 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
3211 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
3214 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned.
3219 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rt2
,
3220 bfd_boolean
*pair
, bfd_boolean
*load
)
3228 /* Bail out quickly if INSN doesn't fall into the the load-store
3230 if (!AARCH64_LDST (insn
))
3235 if (AARCH64_LDST_EX (insn
))
3237 *rt
= AARCH64_RT (insn
);
3239 if (AARCH64_BIT (insn
, 21) == 1)
3242 *rt2
= AARCH64_RT2 (insn
);
3244 *load
= AARCH64_LD (insn
);
3247 else if (AARCH64_LDST_NAP (insn
)
3248 || AARCH64_LDSTP_PI (insn
)
3249 || AARCH64_LDSTP_O (insn
)
3250 || AARCH64_LDSTP_PRE (insn
))
3253 *rt
= AARCH64_RT (insn
);
3254 *rt2
= AARCH64_RT2 (insn
);
3255 *load
= AARCH64_LD (insn
);
3258 else if (AARCH64_LDST_PCREL (insn
)
3259 || AARCH64_LDST_UI (insn
)
3260 || AARCH64_LDST_PIIMM (insn
)
3261 || AARCH64_LDST_U (insn
)
3262 || AARCH64_LDST_PREIMM (insn
)
3263 || AARCH64_LDST_RO (insn
)
3264 || AARCH64_LDST_UIMM (insn
))
3266 *rt
= AARCH64_RT (insn
);
3268 if (AARCH64_LDST_PCREL (insn
))
3270 opc
= AARCH64_BITS (insn
, 22, 2);
3271 v
= AARCH64_BIT (insn
, 26);
3272 opc_v
= opc
| (v
<< 2);
3273 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
3274 || opc_v
== 5 || opc_v
== 7);
3277 else if (AARCH64_LDST_SIMD_M (insn
)
3278 || AARCH64_LDST_SIMD_M_PI (insn
))
3280 *rt
= AARCH64_RT (insn
);
3281 *load
= AARCH64_BIT (insn
, 22);
3282 opcode
= (insn
>> 12) & 0xf;
3309 else if (AARCH64_LDST_SIMD_S (insn
)
3310 || AARCH64_LDST_SIMD_S_PI (insn
))
3312 *rt
= AARCH64_RT (insn
);
3313 r
= (insn
>> 21) & 1;
3314 *load
= AARCH64_BIT (insn
, 22);
3315 opcode
= (insn
>> 13) & 0x7;
3327 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3335 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3347 /* Return TRUE if INSN is multiply-accumulate. */
3350 aarch64_mlxl_p (uint32_t insn
)
3352 uint32_t op31
= AARCH64_OP31 (insn
);
3354 if (AARCH64_MAC (insn
)
3355 && (op31
== 0 || op31
== 1 || op31
== 5)
3356 /* Exclude MUL instructions which are encoded as a multiple accumulate
3358 && AARCH64_RA (insn
) != AARCH64_ZR
)
3364 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3365 it is possible for a 64-bit multiply-accumulate instruction to generate an
3366 incorrect result. The details are quite complex and hard to
3367 determine statically, since branches in the code may exist in some
3368 circumstances, but all cases end with a memory (load, store, or
3369 prefetch) instruction followed immediately by the multiply-accumulate
3370 operation. We employ a linker patching technique, by moving the potentially
3371 affected multiply-accumulate instruction into a patch region and replacing
3372 the original instruction with a branch to the patch. This function checks
3373 if INSN_1 is the memory operation followed by a multiply-accumulate
3374 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3375 if INSN_1 and INSN_2 are safe. */
3378 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
3388 if (aarch64_mlxl_p (insn_2
)
3389 && aarch64_mem_op_p (insn_1
, &rt
, &rt2
, &pair
, &load
))
3391 /* Any SIMD memory op is independent of the subsequent MLA
3392 by definition of the erratum. */
3393 if (AARCH64_BIT (insn_1
, 26))
3396 /* If not SIMD, check for integer memory ops and MLA relationship. */
3397 rn
= AARCH64_RN (insn_2
);
3398 ra
= AARCH64_RA (insn_2
);
3399 rm
= AARCH64_RM (insn_2
);
3401 /* If this is a load and there's a true(RAW) dependency, we are safe
3402 and this is not an erratum sequence. */
3404 (rt
== rn
|| rt
== rm
|| rt
== ra
3405 || (pair
&& (rt2
== rn
|| rt2
== rm
|| rt2
== ra
))))
3408 /* We conservatively put out stubs for all other cases (including
3416 /* Used to order a list of mapping symbols by address. */
3419 elf_aarch64_compare_mapping (const void *a
, const void *b
)
3421 const elf_aarch64_section_map
*amap
= (const elf_aarch64_section_map
*) a
;
3422 const elf_aarch64_section_map
*bmap
= (const elf_aarch64_section_map
*) b
;
3424 if (amap
->vma
> bmap
->vma
)
3426 else if (amap
->vma
< bmap
->vma
)
3428 else if (amap
->type
> bmap
->type
)
3429 /* Ensure results do not depend on the host qsort for objects with
3430 multiple mapping symbols at the same address by sorting on type
3433 else if (amap
->type
< bmap
->type
)
3441 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes
)
3443 char *stub_name
= (char *) bfd_malloc
3444 (strlen ("__erratum_835769_veneer_") + 16);
3445 sprintf (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
3449 /* Scan for Cortex-A53 erratum 835769 sequence.
3451 Return TRUE else FALSE on abnormal termination. */
3454 _bfd_aarch64_erratum_835769_scan (bfd
*input_bfd
,
3455 struct bfd_link_info
*info
,
3456 unsigned int *num_fixes_p
)
3459 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3460 unsigned int num_fixes
= *num_fixes_p
;
3465 for (section
= input_bfd
->sections
;
3467 section
= section
->next
)
3469 bfd_byte
*contents
= NULL
;
3470 struct _aarch64_elf_section_data
*sec_data
;
3473 if (elf_section_type (section
) != SHT_PROGBITS
3474 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3475 || (section
->flags
& SEC_EXCLUDE
) != 0
3476 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3477 || (section
->output_section
== bfd_abs_section_ptr
))
3480 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3481 contents
= elf_section_data (section
)->this_hdr
.contents
;
3482 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3485 sec_data
= elf_aarch64_section_data (section
);
3487 qsort (sec_data
->map
, sec_data
->mapcount
,
3488 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3490 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3492 unsigned int span_start
= sec_data
->map
[span
].vma
;
3493 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3494 ? sec_data
->map
[0].vma
+ section
->size
3495 : sec_data
->map
[span
+ 1].vma
);
3497 char span_type
= sec_data
->map
[span
].type
;
3499 if (span_type
== 'd')
3502 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
3504 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3505 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3507 if (aarch64_erratum_sequence (insn_1
, insn_2
))
3509 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3510 char *stub_name
= _bfd_aarch64_erratum_835769_stub_name (num_fixes
);
3514 stub_entry
= _bfd_aarch64_add_stub_entry_in_group (stub_name
,
3520 stub_entry
->stub_type
= aarch64_stub_erratum_835769_veneer
;
3521 stub_entry
->target_section
= section
;
3522 stub_entry
->target_value
= i
+ 4;
3523 stub_entry
->veneered_insn
= insn_2
;
3524 stub_entry
->output_name
= stub_name
;
3529 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3533 *num_fixes_p
= num_fixes
;
3539 /* Test if instruction INSN is ADRP. */
3542 _bfd_aarch64_adrp_p (uint32_t insn
)
3544 return ((insn
& 0x9f000000) == 0x90000000);
3548 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
3551 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1
, uint32_t insn_2
,
3559 return (aarch64_mem_op_p (insn_2
, &rt
, &rt2
, &pair
, &load
)
3562 && AARCH64_LDST_UIMM (insn_3
)
3563 && AARCH64_RN (insn_3
) == AARCH64_RD (insn_1
));
3567 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
3569 Return TRUE if section CONTENTS at offset I contains one of the
3570 erratum 843419 sequences, otherwise return FALSE. If a sequence is
3571 seen set P_VENEER_I to the offset of the final LOAD/STORE
3572 instruction in the sequence.
3576 _bfd_aarch64_erratum_843419_p (bfd_byte
*contents
, bfd_vma vma
,
3577 bfd_vma i
, bfd_vma span_end
,
3578 bfd_vma
*p_veneer_i
)
3580 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
3582 if (!_bfd_aarch64_adrp_p (insn_1
))
3585 if (span_end
< i
+ 12)
3588 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
3589 uint32_t insn_3
= bfd_getl32 (contents
+ i
+ 8);
3591 if ((vma
& 0xfff) != 0xff8 && (vma
& 0xfff) != 0xffc)
3594 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_3
))
3596 *p_veneer_i
= i
+ 8;
3600 if (span_end
< i
+ 16)
3603 uint32_t insn_4
= bfd_getl32 (contents
+ i
+ 12);
3605 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_4
))
3607 *p_veneer_i
= i
+ 12;
3615 /* Resize all stub sections. */
3618 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table
*htab
)
3622 /* OK, we've added some stubs. Find out the new size of the
3624 for (section
= htab
->stub_bfd
->sections
;
3625 section
!= NULL
; section
= section
->next
)
3627 /* Ignore non-stub sections. */
3628 if (!strstr (section
->name
, STUB_SUFFIX
))
3633 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
3635 for (section
= htab
->stub_bfd
->sections
;
3636 section
!= NULL
; section
= section
->next
)
3638 if (!strstr (section
->name
, STUB_SUFFIX
))
3644 /* Ensure all stub sections have a size which is a multiple of
3645 4096. This is important in order to ensure that the insertion
3646 of stub sections does not in itself move existing code around
3647 in such a way that new errata sequences are created. */
3648 if (htab
->fix_erratum_843419
)
3650 section
->size
= BFD_ALIGN (section
->size
, 0x1000);
3655 /* Construct an erratum 843419 workaround stub name.
3659 _bfd_aarch64_erratum_843419_stub_name (asection
*input_section
,
3662 const bfd_size_type len
= 8 + 4 + 1 + 8 + 1 + 16 + 1;
3663 char *stub_name
= bfd_malloc (len
);
3665 if (stub_name
!= NULL
)
3666 snprintf (stub_name
, len
, "e843419@%04x_%08x_%" BFD_VMA_FMT
"x",
3667 input_section
->owner
->id
,
3673 /* Build a stub_entry structure describing an 843419 fixup.
3675 The stub_entry constructed is populated with the bit pattern INSN
3676 of the instruction located at OFFSET within input SECTION.
3678 Returns TRUE on success. */
3681 _bfd_aarch64_erratum_843419_fixup (uint32_t insn
,
3682 bfd_vma adrp_offset
,
3683 bfd_vma ldst_offset
,
3685 struct bfd_link_info
*info
)
3687 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3689 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3691 stub_name
= _bfd_aarch64_erratum_843419_stub_name (section
, ldst_offset
);
3692 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3700 /* We always place an 843419 workaround veneer in the stub section
3701 attached to the input section in which an erratum sequence has
3702 been found. This ensures that later in the link process (in
3703 elfNN_aarch64_write_section) when we copy the veneered
3704 instruction from the input section into the stub section the
3705 copied instruction will have had any relocations applied to it.
3706 If we placed workaround veneers in any other stub section then we
3707 could not assume that all relocations have been processed on the
3708 corresponding input section at the point we output the stub
3712 stub_entry
= _bfd_aarch64_add_stub_entry_after (stub_name
, section
, htab
);
3713 if (stub_entry
== NULL
)
3719 stub_entry
->adrp_offset
= adrp_offset
;
3720 stub_entry
->target_value
= ldst_offset
;
3721 stub_entry
->target_section
= section
;
3722 stub_entry
->stub_type
= aarch64_stub_erratum_843419_veneer
;
3723 stub_entry
->veneered_insn
= insn
;
3724 stub_entry
->output_name
= stub_name
;
3730 /* Scan an input section looking for the signature of erratum 843419.
3732 Scans input SECTION in INPUT_BFD looking for erratum 843419
3733 signatures, for each signature found a stub_entry is created
3734 describing the location of the erratum for subsequent fixup.
3736 Return TRUE on successful scan, FALSE on failure to scan.
3740 _bfd_aarch64_erratum_843419_scan (bfd
*input_bfd
, asection
*section
,
3741 struct bfd_link_info
*info
)
3743 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3748 if (elf_section_type (section
) != SHT_PROGBITS
3749 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
3750 || (section
->flags
& SEC_EXCLUDE
) != 0
3751 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
3752 || (section
->output_section
== bfd_abs_section_ptr
))
3757 bfd_byte
*contents
= NULL
;
3758 struct _aarch64_elf_section_data
*sec_data
;
3761 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
3762 contents
= elf_section_data (section
)->this_hdr
.contents
;
3763 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
3766 sec_data
= elf_aarch64_section_data (section
);
3768 qsort (sec_data
->map
, sec_data
->mapcount
,
3769 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
3771 for (span
= 0; span
< sec_data
->mapcount
; span
++)
3773 unsigned int span_start
= sec_data
->map
[span
].vma
;
3774 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
3775 ? sec_data
->map
[0].vma
+ section
->size
3776 : sec_data
->map
[span
+ 1].vma
);
3778 char span_type
= sec_data
->map
[span
].type
;
3780 if (span_type
== 'd')
3783 for (i
= span_start
; i
+ 8 < span_end
; i
+= 4)
3785 bfd_vma vma
= (section
->output_section
->vma
3786 + section
->output_offset
3790 if (_bfd_aarch64_erratum_843419_p
3791 (contents
, vma
, i
, span_end
, &veneer_i
))
3793 uint32_t insn
= bfd_getl32 (contents
+ veneer_i
);
3795 if (!_bfd_aarch64_erratum_843419_fixup (insn
, i
, veneer_i
,
3802 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
3811 /* Determine and set the size of the stub section for a final link.
3813 The basic idea here is to examine all the relocations looking for
3814 PC-relative calls to a target that is unreachable with a "bl"
3818 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
3820 struct bfd_link_info
*info
,
3821 bfd_signed_vma group_size
,
3822 asection
* (*add_stub_section
) (const char *,
3824 void (*layout_sections_again
) (void))
3826 bfd_size_type stub_group_size
;
3827 bfd_boolean stubs_always_before_branch
;
3828 bfd_boolean stub_changed
= FALSE
;
3829 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3830 unsigned int num_erratum_835769_fixes
= 0;
3832 /* Propagate mach to stub bfd, because it may not have been
3833 finalized when we created stub_bfd. */
3834 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
3835 bfd_get_mach (output_bfd
));
3837 /* Stash our params away. */
3838 htab
->stub_bfd
= stub_bfd
;
3839 htab
->add_stub_section
= add_stub_section
;
3840 htab
->layout_sections_again
= layout_sections_again
;
3841 stubs_always_before_branch
= group_size
< 0;
3843 stub_group_size
= -group_size
;
3845 stub_group_size
= group_size
;
3847 if (stub_group_size
== 1)
3849 /* Default values. */
3850 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
3851 stub_group_size
= 127 * 1024 * 1024;
3854 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
3856 (*htab
->layout_sections_again
) ();
3858 if (htab
->fix_erratum_835769
)
3862 for (input_bfd
= info
->input_bfds
;
3863 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3864 if (!_bfd_aarch64_erratum_835769_scan (input_bfd
, info
,
3865 &num_erratum_835769_fixes
))
3868 _bfd_aarch64_resize_stubs (htab
);
3869 (*htab
->layout_sections_again
) ();
3872 if (htab
->fix_erratum_843419
)
3876 for (input_bfd
= info
->input_bfds
;
3878 input_bfd
= input_bfd
->link
.next
)
3882 for (section
= input_bfd
->sections
;
3884 section
= section
->next
)
3885 if (!_bfd_aarch64_erratum_843419_scan (input_bfd
, section
, info
))
3889 _bfd_aarch64_resize_stubs (htab
);
3890 (*htab
->layout_sections_again
) ();
3897 for (input_bfd
= info
->input_bfds
;
3898 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3900 Elf_Internal_Shdr
*symtab_hdr
;
3902 Elf_Internal_Sym
*local_syms
= NULL
;
3904 /* We'll need the symbol table in a second. */
3905 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
3906 if (symtab_hdr
->sh_info
== 0)
3909 /* Walk over each section attached to the input bfd. */
3910 for (section
= input_bfd
->sections
;
3911 section
!= NULL
; section
= section
->next
)
3913 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
3915 /* If there aren't any relocs, then there's nothing more
3917 if ((section
->flags
& SEC_RELOC
) == 0
3918 || section
->reloc_count
== 0
3919 || (section
->flags
& SEC_CODE
) == 0)
3922 /* If this section is a link-once section that will be
3923 discarded, then don't create any stubs. */
3924 if (section
->output_section
== NULL
3925 || section
->output_section
->owner
!= output_bfd
)
3928 /* Get the relocs. */
3930 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
3931 NULL
, info
->keep_memory
);
3932 if (internal_relocs
== NULL
)
3933 goto error_ret_free_local
;
3935 /* Now examine each relocation. */
3936 irela
= internal_relocs
;
3937 irelaend
= irela
+ section
->reloc_count
;
3938 for (; irela
< irelaend
; irela
++)
3940 unsigned int r_type
, r_indx
;
3941 enum elf_aarch64_stub_type stub_type
;
3942 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3945 bfd_vma destination
;
3946 struct elf_aarch64_link_hash_entry
*hash
;
3947 const char *sym_name
;
3949 const asection
*id_sec
;
3950 unsigned char st_type
;
3953 r_type
= ELFNN_R_TYPE (irela
->r_info
);
3954 r_indx
= ELFNN_R_SYM (irela
->r_info
);
3956 if (r_type
>= (unsigned int) R_AARCH64_end
)
3958 bfd_set_error (bfd_error_bad_value
);
3959 error_ret_free_internal
:
3960 if (elf_section_data (section
)->relocs
== NULL
)
3961 free (internal_relocs
);
3962 goto error_ret_free_local
;
3965 /* Only look for stubs on unconditional branch and
3966 branch and link instructions. */
3967 if (r_type
!= (unsigned int) AARCH64_R (CALL26
)
3968 && r_type
!= (unsigned int) AARCH64_R (JUMP26
))
3971 /* Now determine the call target, its name, value,
3978 if (r_indx
< symtab_hdr
->sh_info
)
3980 /* It's a local symbol. */
3981 Elf_Internal_Sym
*sym
;
3982 Elf_Internal_Shdr
*hdr
;
3984 if (local_syms
== NULL
)
3987 = (Elf_Internal_Sym
*) symtab_hdr
->contents
;
3988 if (local_syms
== NULL
)
3990 = bfd_elf_get_elf_syms (input_bfd
, symtab_hdr
,
3991 symtab_hdr
->sh_info
, 0,
3993 if (local_syms
== NULL
)
3994 goto error_ret_free_internal
;
3997 sym
= local_syms
+ r_indx
;
3998 hdr
= elf_elfsections (input_bfd
)[sym
->st_shndx
];
3999 sym_sec
= hdr
->bfd_section
;
4001 /* This is an undefined symbol. It can never
4005 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
4006 sym_value
= sym
->st_value
;
4007 destination
= (sym_value
+ irela
->r_addend
4008 + sym_sec
->output_offset
4009 + sym_sec
->output_section
->vma
);
4010 st_type
= ELF_ST_TYPE (sym
->st_info
);
4012 = bfd_elf_string_from_elf_section (input_bfd
,
4013 symtab_hdr
->sh_link
,
4020 e_indx
= r_indx
- symtab_hdr
->sh_info
;
4021 hash
= ((struct elf_aarch64_link_hash_entry
*)
4022 elf_sym_hashes (input_bfd
)[e_indx
]);
4024 while (hash
->root
.root
.type
== bfd_link_hash_indirect
4025 || hash
->root
.root
.type
== bfd_link_hash_warning
)
4026 hash
= ((struct elf_aarch64_link_hash_entry
*)
4027 hash
->root
.root
.u
.i
.link
);
4029 if (hash
->root
.root
.type
== bfd_link_hash_defined
4030 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
4032 struct elf_aarch64_link_hash_table
*globals
=
4033 elf_aarch64_hash_table (info
);
4034 sym_sec
= hash
->root
.root
.u
.def
.section
;
4035 sym_value
= hash
->root
.root
.u
.def
.value
;
4036 /* For a destination in a shared library,
4037 use the PLT stub as target address to
4038 decide whether a branch stub is
4040 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
4041 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
4043 sym_sec
= globals
->root
.splt
;
4044 sym_value
= hash
->root
.plt
.offset
;
4045 if (sym_sec
->output_section
!= NULL
)
4046 destination
= (sym_value
4047 + sym_sec
->output_offset
4049 sym_sec
->output_section
->vma
);
4051 else if (sym_sec
->output_section
!= NULL
)
4052 destination
= (sym_value
+ irela
->r_addend
4053 + sym_sec
->output_offset
4054 + sym_sec
->output_section
->vma
);
4056 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
4057 || (hash
->root
.root
.type
4058 == bfd_link_hash_undefweak
))
4060 /* For a shared library, use the PLT stub as
4061 target address to decide whether a long
4062 branch stub is needed.
4063 For absolute code, they cannot be handled. */
4064 struct elf_aarch64_link_hash_table
*globals
=
4065 elf_aarch64_hash_table (info
);
4067 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
4068 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
4070 sym_sec
= globals
->root
.splt
;
4071 sym_value
= hash
->root
.plt
.offset
;
4072 if (sym_sec
->output_section
!= NULL
)
4073 destination
= (sym_value
4074 + sym_sec
->output_offset
4076 sym_sec
->output_section
->vma
);
4083 bfd_set_error (bfd_error_bad_value
);
4084 goto error_ret_free_internal
;
4086 st_type
= ELF_ST_TYPE (hash
->root
.type
);
4087 sym_name
= hash
->root
.root
.root
.string
;
4090 /* Determine what (if any) linker stub is needed. */
4091 stub_type
= aarch64_type_of_stub
4092 (info
, section
, irela
, sym_sec
, st_type
, hash
, destination
);
4093 if (stub_type
== aarch64_stub_none
)
4096 /* Support for grouping stub sections. */
4097 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
4099 /* Get the name of this stub. */
4100 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
4103 goto error_ret_free_internal
;
4106 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
4107 stub_name
, FALSE
, FALSE
);
4108 if (stub_entry
!= NULL
)
4110 /* The proper stub has already been created. */
4115 stub_entry
= _bfd_aarch64_add_stub_entry_in_group
4116 (stub_name
, section
, htab
);
4117 if (stub_entry
== NULL
)
4120 goto error_ret_free_internal
;
4123 stub_entry
->target_value
= sym_value
;
4124 stub_entry
->target_section
= sym_sec
;
4125 stub_entry
->stub_type
= stub_type
;
4126 stub_entry
->h
= hash
;
4127 stub_entry
->st_type
= st_type
;
4129 if (sym_name
== NULL
)
4130 sym_name
= "unnamed";
4131 len
= sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
);
4132 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
4133 if (stub_entry
->output_name
== NULL
)
4136 goto error_ret_free_internal
;
4139 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
4142 stub_changed
= TRUE
;
4145 /* We're done with the internal relocs, free them. */
4146 if (elf_section_data (section
)->relocs
== NULL
)
4147 free (internal_relocs
);
4154 _bfd_aarch64_resize_stubs (htab
);
4156 /* Ask the linker to do its stuff. */
4157 (*htab
->layout_sections_again
) ();
4158 stub_changed
= FALSE
;
4163 error_ret_free_local
:
4167 /* Build all the stubs associated with the current output file. The
4168 stubs are kept in a hash table attached to the main linker hash
4169 table. We also set up the .plt entries for statically linked PIC
4170 functions here. This function is called via aarch64_elf_finish in the
4174 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
4177 struct bfd_hash_table
*table
;
4178 struct elf_aarch64_link_hash_table
*htab
;
4180 htab
= elf_aarch64_hash_table (info
);
4182 for (stub_sec
= htab
->stub_bfd
->sections
;
4183 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
4187 /* Ignore non-stub sections. */
4188 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
4191 /* Allocate memory to hold the linker stubs. */
4192 size
= stub_sec
->size
;
4193 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
4194 if (stub_sec
->contents
== NULL
&& size
!= 0)
4198 bfd_putl32 (0x14000000 | (size
>> 2), stub_sec
->contents
);
4199 stub_sec
->size
+= 4;
4202 /* Build the stubs as directed by the stub hash table. */
4203 table
= &htab
->stub_hash_table
;
4204 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
4210 /* Add an entry to the code/data map for section SEC. */
4213 elfNN_aarch64_section_map_add (asection
*sec
, char type
, bfd_vma vma
)
4215 struct _aarch64_elf_section_data
*sec_data
=
4216 elf_aarch64_section_data (sec
);
4217 unsigned int newidx
;
4219 if (sec_data
->map
== NULL
)
4221 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
4222 sec_data
->mapcount
= 0;
4223 sec_data
->mapsize
= 1;
4226 newidx
= sec_data
->mapcount
++;
4228 if (sec_data
->mapcount
> sec_data
->mapsize
)
4230 sec_data
->mapsize
*= 2;
4231 sec_data
->map
= bfd_realloc_or_free
4232 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
4237 sec_data
->map
[newidx
].vma
= vma
;
4238 sec_data
->map
[newidx
].type
= type
;
4243 /* Initialise maps of insn/data for input BFDs. */
4245 bfd_elfNN_aarch64_init_maps (bfd
*abfd
)
4247 Elf_Internal_Sym
*isymbuf
;
4248 Elf_Internal_Shdr
*hdr
;
4249 unsigned int i
, localsyms
;
4251 /* Make sure that we are dealing with an AArch64 elf binary. */
4252 if (!is_aarch64_elf (abfd
))
4255 if ((abfd
->flags
& DYNAMIC
) != 0)
4258 hdr
= &elf_symtab_hdr (abfd
);
4259 localsyms
= hdr
->sh_info
;
4261 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
4262 should contain the number of local symbols, which should come before any
4263 global symbols. Mapping symbols are always local. */
4264 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
4266 /* No internal symbols read? Skip this BFD. */
4267 if (isymbuf
== NULL
)
4270 for (i
= 0; i
< localsyms
; i
++)
4272 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
4273 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
4276 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
4278 name
= bfd_elf_string_from_elf_section (abfd
,
4282 if (bfd_is_aarch64_special_symbol_name
4283 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
4284 elfNN_aarch64_section_map_add (sec
, name
[1], isym
->st_value
);
4289 /* Set option values needed during linking. */
4291 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
4292 struct bfd_link_info
*link_info
,
4294 int no_wchar_warn
, int pic_veneer
,
4295 int fix_erratum_835769
,
4296 int fix_erratum_843419
)
4298 struct elf_aarch64_link_hash_table
*globals
;
4300 globals
= elf_aarch64_hash_table (link_info
);
4301 globals
->pic_veneer
= pic_veneer
;
4302 globals
->fix_erratum_835769
= fix_erratum_835769
;
4303 globals
->fix_erratum_843419
= fix_erratum_843419
;
4304 globals
->fix_erratum_843419_adr
= TRUE
;
4306 BFD_ASSERT (is_aarch64_elf (output_bfd
));
4307 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
4308 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
4312 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
4313 struct elf_aarch64_link_hash_table
4314 *globals
, struct bfd_link_info
*info
,
4315 bfd_vma value
, bfd
*output_bfd
,
4316 bfd_boolean
*unresolved_reloc_p
)
4318 bfd_vma off
= (bfd_vma
) - 1;
4319 asection
*basegot
= globals
->root
.sgot
;
4320 bfd_boolean dyn
= globals
->root
.dynamic_sections_created
;
4324 BFD_ASSERT (basegot
!= NULL
);
4325 off
= h
->got
.offset
;
4326 BFD_ASSERT (off
!= (bfd_vma
) - 1);
4327 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
4328 || (bfd_link_pic (info
)
4329 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4330 || (ELF_ST_VISIBILITY (h
->other
)
4331 && h
->root
.type
== bfd_link_hash_undefweak
))
4333 /* This is actually a static link, or it is a -Bsymbolic link
4334 and the symbol is defined locally. We must initialize this
4335 entry in the global offset table. Since the offset must
4336 always be a multiple of 8 (4 in the case of ILP32), we use
4337 the least significant bit to record whether we have
4338 initialized it already.
4339 When doing a dynamic link, we create a .rel(a).got relocation
4340 entry to initialize the value. This is done in the
4341 finish_dynamic_symbol routine. */
4346 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
4351 *unresolved_reloc_p
= FALSE
;
4353 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
4359 /* Change R_TYPE to a more efficient access model where possible,
4360 return the new reloc type. */
4362 static bfd_reloc_code_real_type
4363 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
4364 struct elf_link_hash_entry
*h
)
4366 bfd_boolean is_local
= h
== NULL
;
4370 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4371 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4373 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4374 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
4376 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
4378 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4381 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
4383 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4384 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
4386 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
4387 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4389 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4390 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
4392 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4393 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
4395 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
4396 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
4398 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4401 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4403 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
4404 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
4406 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4407 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4408 /* Instructions with these relocations will become NOPs. */
4409 return BFD_RELOC_AARCH64_NONE
;
4411 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
4412 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
4413 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
4414 return is_local
? BFD_RELOC_AARCH64_NONE
: r_type
;
4424 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
4428 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4429 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4430 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4431 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4432 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
4433 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4434 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4437 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
4438 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
4439 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
4440 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
4441 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
4442 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
4445 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
4446 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
4447 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
4448 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
4449 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
4450 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
4451 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
4452 return GOT_TLSDESC_GD
;
4454 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
4455 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
4456 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
4457 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
4467 aarch64_can_relax_tls (bfd
*input_bfd
,
4468 struct bfd_link_info
*info
,
4469 bfd_reloc_code_real_type r_type
,
4470 struct elf_link_hash_entry
*h
,
4471 unsigned long r_symndx
)
4473 unsigned int symbol_got_type
;
4474 unsigned int reloc_got_type
;
4476 if (! IS_AARCH64_TLS_RELAX_RELOC (r_type
))
4479 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
4480 reloc_got_type
= aarch64_reloc_got_type (r_type
);
4482 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
4485 if (bfd_link_pic (info
))
4488 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
4494 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
4497 static bfd_reloc_code_real_type
4498 aarch64_tls_transition (bfd
*input_bfd
,
4499 struct bfd_link_info
*info
,
4500 unsigned int r_type
,
4501 struct elf_link_hash_entry
*h
,
4502 unsigned long r_symndx
)
4504 bfd_reloc_code_real_type bfd_r_type
4505 = elfNN_aarch64_bfd_reloc_from_type (r_type
);
4507 if (! aarch64_can_relax_tls (input_bfd
, info
, bfd_r_type
, h
, r_symndx
))
4510 return aarch64_tls_transition_without_check (bfd_r_type
, h
);
4513 /* Return the base VMA address which should be subtracted from real addresses
4514 when resolving R_AARCH64_TLS_DTPREL relocation. */
4517 dtpoff_base (struct bfd_link_info
*info
)
4519 /* If tls_sec is NULL, we should have signalled an error already. */
4520 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
4521 return elf_hash_table (info
)->tls_sec
->vma
;
4524 /* Return the base VMA address which should be subtracted from real addresses
4525 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
4528 tpoff_base (struct bfd_link_info
*info
)
4530 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
4532 /* If tls_sec is NULL, we should have signalled an error already. */
4533 BFD_ASSERT (htab
->tls_sec
!= NULL
);
4535 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE
,
4536 htab
->tls_sec
->alignment_power
);
4537 return htab
->tls_sec
->vma
- base
;
4541 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4542 unsigned long r_symndx
)
4544 /* Calculate the address of the GOT entry for symbol
4545 referred to in h. */
4547 return &h
->got
.offset
;
4551 struct elf_aarch64_local_symbol
*l
;
4553 l
= elf_aarch64_locals (input_bfd
);
4554 return &l
[r_symndx
].got_offset
;
4559 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4560 unsigned long r_symndx
)
4563 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4568 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4569 unsigned long r_symndx
)
4572 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4577 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4578 unsigned long r_symndx
)
4581 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
4587 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4588 unsigned long r_symndx
)
4590 /* Calculate the address of the GOT entry for symbol
4591 referred to in h. */
4594 struct elf_aarch64_link_hash_entry
*eh
;
4595 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
4596 return &eh
->tlsdesc_got_jump_table_offset
;
4601 struct elf_aarch64_local_symbol
*l
;
4603 l
= elf_aarch64_locals (input_bfd
);
4604 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
4609 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4610 unsigned long r_symndx
)
4613 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4618 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
4619 struct elf_link_hash_entry
*h
,
4620 unsigned long r_symndx
)
4623 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4628 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
4629 unsigned long r_symndx
)
4632 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
4637 /* Data for make_branch_to_erratum_835769_stub(). */
4639 struct erratum_835769_branch_to_stub_data
4641 struct bfd_link_info
*info
;
4642 asection
*output_section
;
4646 /* Helper to insert branches to erratum 835769 stubs in the right
4647 places for a particular section. */
4650 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
4653 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4654 struct erratum_835769_branch_to_stub_data
*data
;
4656 unsigned long branch_insn
= 0;
4657 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
4658 bfd_signed_vma branch_offset
;
4659 unsigned int target
;
4662 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4663 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4665 if (stub_entry
->target_section
!= data
->output_section
4666 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
4669 contents
= data
->contents
;
4670 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4671 + stub_entry
->target_section
->output_offset
4672 + stub_entry
->target_value
;
4673 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4674 + stub_entry
->stub_sec
->output_offset
4675 + stub_entry
->stub_offset
;
4676 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4678 abfd
= stub_entry
->target_section
->owner
;
4679 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4680 (*_bfd_error_handler
)
4681 (_("%B: error: Erratum 835769 stub out "
4682 "of range (input file too large)"), abfd
);
4684 target
= stub_entry
->target_value
;
4685 branch_insn
= 0x14000000;
4686 branch_offset
>>= 2;
4687 branch_offset
&= 0x3ffffff;
4688 branch_insn
|= branch_offset
;
4689 bfd_putl32 (branch_insn
, &contents
[target
]);
4696 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry
*gen_entry
,
4699 struct elf_aarch64_stub_hash_entry
*stub_entry
4700 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
4701 struct erratum_835769_branch_to_stub_data
*data
4702 = (struct erratum_835769_branch_to_stub_data
*) in_arg
;
4703 struct bfd_link_info
*info
;
4704 struct elf_aarch64_link_hash_table
*htab
;
4712 contents
= data
->contents
;
4713 section
= data
->output_section
;
4715 htab
= elf_aarch64_hash_table (info
);
4717 if (stub_entry
->target_section
!= section
4718 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
)
4721 insn
= bfd_getl32 (contents
+ stub_entry
->target_value
);
4723 stub_entry
->stub_sec
->contents
+ stub_entry
->stub_offset
);
4725 place
= (section
->output_section
->vma
+ section
->output_offset
4726 + stub_entry
->adrp_offset
);
4727 insn
= bfd_getl32 (contents
+ stub_entry
->adrp_offset
);
4729 if ((insn
& AARCH64_ADRP_OP_MASK
) != AARCH64_ADRP_OP
)
4732 bfd_signed_vma imm
=
4733 (_bfd_aarch64_sign_extend
4734 ((bfd_vma
) _bfd_aarch64_decode_adrp_imm (insn
) << 12, 33)
4737 if (htab
->fix_erratum_843419_adr
4738 && (imm
>= AARCH64_MIN_ADRP_IMM
&& imm
<= AARCH64_MAX_ADRP_IMM
))
4740 insn
= (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP
, imm
)
4741 | AARCH64_RT (insn
));
4742 bfd_putl32 (insn
, contents
+ stub_entry
->adrp_offset
);
4746 bfd_vma veneered_insn_loc
;
4747 bfd_vma veneer_entry_loc
;
4748 bfd_signed_vma branch_offset
;
4749 uint32_t branch_insn
;
4751 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
4752 + stub_entry
->target_section
->output_offset
4753 + stub_entry
->target_value
;
4754 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
4755 + stub_entry
->stub_sec
->output_offset
4756 + stub_entry
->stub_offset
;
4757 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
4759 abfd
= stub_entry
->target_section
->owner
;
4760 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
4761 (*_bfd_error_handler
)
4762 (_("%B: error: Erratum 843419 stub out "
4763 "of range (input file too large)"), abfd
);
4765 branch_insn
= 0x14000000;
4766 branch_offset
>>= 2;
4767 branch_offset
&= 0x3ffffff;
4768 branch_insn
|= branch_offset
;
4769 bfd_putl32 (branch_insn
, contents
+ stub_entry
->target_value
);
4776 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4777 struct bfd_link_info
*link_info
,
4782 struct elf_aarch64_link_hash_table
*globals
=
4783 elf_aarch64_hash_table (link_info
);
4785 if (globals
== NULL
)
4788 /* Fix code to point to erratum 835769 stubs. */
4789 if (globals
->fix_erratum_835769
)
4791 struct erratum_835769_branch_to_stub_data data
;
4793 data
.info
= link_info
;
4794 data
.output_section
= sec
;
4795 data
.contents
= contents
;
4796 bfd_hash_traverse (&globals
->stub_hash_table
,
4797 make_branch_to_erratum_835769_stub
, &data
);
4800 if (globals
->fix_erratum_843419
)
4802 struct erratum_835769_branch_to_stub_data data
;
4804 data
.info
= link_info
;
4805 data
.output_section
= sec
;
4806 data
.contents
= contents
;
4807 bfd_hash_traverse (&globals
->stub_hash_table
,
4808 _bfd_aarch64_erratum_843419_branch_to_stub
, &data
);
4814 /* Perform a relocation as part of a final link. */
4815 static bfd_reloc_status_type
4816 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
4819 asection
*input_section
,
4821 Elf_Internal_Rela
*rel
,
4823 struct bfd_link_info
*info
,
4825 struct elf_link_hash_entry
*h
,
4826 bfd_boolean
*unresolved_reloc_p
,
4827 bfd_boolean save_addend
,
4828 bfd_vma
*saved_addend
,
4829 Elf_Internal_Sym
*sym
)
4831 Elf_Internal_Shdr
*symtab_hdr
;
4832 unsigned int r_type
= howto
->type
;
4833 bfd_reloc_code_real_type bfd_r_type
4834 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
4835 bfd_reloc_code_real_type new_bfd_r_type
;
4836 unsigned long r_symndx
;
4837 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
4839 bfd_signed_vma signed_addend
;
4840 struct elf_aarch64_link_hash_table
*globals
;
4841 bfd_boolean weak_undef_p
;
4844 globals
= elf_aarch64_hash_table (info
);
4846 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
4848 BFD_ASSERT (is_aarch64_elf (input_bfd
));
4850 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
4852 /* It is possible to have linker relaxations on some TLS access
4853 models. Update our information here. */
4854 new_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
, h
, r_symndx
);
4855 if (new_bfd_r_type
!= bfd_r_type
)
4857 bfd_r_type
= new_bfd_r_type
;
4858 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
4859 BFD_ASSERT (howto
!= NULL
);
4860 r_type
= howto
->type
;
4863 place
= input_section
->output_section
->vma
4864 + input_section
->output_offset
+ rel
->r_offset
;
4866 /* Get addend, accumulating the addend for consecutive relocs
4867 which refer to the same offset. */
4868 signed_addend
= saved_addend
? *saved_addend
: 0;
4869 signed_addend
+= rel
->r_addend
;
4871 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
4872 : bfd_is_und_section (sym_sec
));
4874 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
4875 it here if it is defined in a non-shared object. */
4877 && h
->type
== STT_GNU_IFUNC
4884 if ((input_section
->flags
& SEC_ALLOC
) == 0
4885 || h
->plt
.offset
== (bfd_vma
) -1)
4888 /* STT_GNU_IFUNC symbol must go through PLT. */
4889 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
4890 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
4895 if (h
->root
.root
.string
)
4896 name
= h
->root
.root
.string
;
4898 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
4900 (*_bfd_error_handler
)
4901 (_("%B: relocation %s against STT_GNU_IFUNC "
4902 "symbol `%s' isn't handled by %s"), input_bfd
,
4903 howto
->name
, name
, __FUNCTION__
);
4904 bfd_set_error (bfd_error_bad_value
);
4907 case BFD_RELOC_AARCH64_NN
:
4908 if (rel
->r_addend
!= 0)
4910 if (h
->root
.root
.string
)
4911 name
= h
->root
.root
.string
;
4913 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
4915 (*_bfd_error_handler
)
4916 (_("%B: relocation %s against STT_GNU_IFUNC "
4917 "symbol `%s' has non-zero addend: %d"),
4918 input_bfd
, howto
->name
, name
, rel
->r_addend
);
4919 bfd_set_error (bfd_error_bad_value
);
4923 /* Generate dynamic relocation only when there is a
4924 non-GOT reference in a shared object. */
4925 if (bfd_link_pic (info
) && h
->non_got_ref
)
4927 Elf_Internal_Rela outrel
;
4930 /* Need a dynamic relocation to get the real function
4932 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
4936 if (outrel
.r_offset
== (bfd_vma
) -1
4937 || outrel
.r_offset
== (bfd_vma
) -2)
4940 outrel
.r_offset
+= (input_section
->output_section
->vma
4941 + input_section
->output_offset
);
4943 if (h
->dynindx
== -1
4945 || bfd_link_executable (info
))
4947 /* This symbol is resolved locally. */
4948 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
4949 outrel
.r_addend
= (h
->root
.u
.def
.value
4950 + h
->root
.u
.def
.section
->output_section
->vma
4951 + h
->root
.u
.def
.section
->output_offset
);
4955 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
4956 outrel
.r_addend
= 0;
4959 sreloc
= globals
->root
.irelifunc
;
4960 elf_append_rela (output_bfd
, sreloc
, &outrel
);
4962 /* If this reloc is against an external symbol, we
4963 do not want to fiddle with the addend. Otherwise,
4964 we need to include the symbol value so that it
4965 becomes an addend for the dynamic reloc. For an
4966 internal symbol, we have updated addend. */
4967 return bfd_reloc_ok
;
4970 case BFD_RELOC_AARCH64_CALL26
:
4971 case BFD_RELOC_AARCH64_JUMP26
:
4972 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
4975 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
4977 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
4978 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
4979 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
4980 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
4981 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
4982 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
4983 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
4984 base_got
= globals
->root
.sgot
;
4985 off
= h
->got
.offset
;
4987 if (base_got
== NULL
)
4990 if (off
== (bfd_vma
) -1)
4994 /* We can't use h->got.offset here to save state, or
4995 even just remember the offset, as finish_dynamic_symbol
4996 would use that as offset into .got. */
4998 if (globals
->root
.splt
!= NULL
)
5000 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
5001 globals
->plt_entry_size
);
5002 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
5003 base_got
= globals
->root
.sgotplt
;
5007 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
5008 off
= plt_index
* GOT_ENTRY_SIZE
;
5009 base_got
= globals
->root
.igotplt
;
5012 if (h
->dynindx
== -1
5016 /* This references the local definition. We must
5017 initialize this entry in the global offset table.
5018 Since the offset must always be a multiple of 8,
5019 we use the least significant bit to record
5020 whether we have initialized it already.
5022 When doing a dynamic link, we create a .rela.got
5023 relocation entry to initialize the value. This
5024 is done in the finish_dynamic_symbol routine. */
5029 bfd_put_NN (output_bfd
, value
,
5030 base_got
->contents
+ off
);
5031 /* Note that this is harmless as -1 | 1 still is -1. */
5035 value
= (base_got
->output_section
->vma
5036 + base_got
->output_offset
+ off
);
5039 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
5041 unresolved_reloc_p
);
5045 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5046 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5047 addend
= (globals
->root
.sgot
->output_section
->vma
5048 + globals
->root
.sgot
->output_offset
);
5050 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
5051 value
= (value
- globals
->root
.sgot
->output_section
->vma
5052 - globals
->root
.sgot
->output_offset
);
5057 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5058 addend
, weak_undef_p
);
5059 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
5060 case BFD_RELOC_AARCH64_ADD_LO12
:
5061 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5068 case BFD_RELOC_AARCH64_NONE
:
5069 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5070 *unresolved_reloc_p
= FALSE
;
5071 return bfd_reloc_ok
;
5073 case BFD_RELOC_AARCH64_NN
:
5075 /* When generating a shared object or relocatable executable, these
5076 relocations are copied into the output file to be resolved at
5078 if (((bfd_link_pic (info
) == TRUE
)
5079 || globals
->root
.is_relocatable_executable
)
5080 && (input_section
->flags
& SEC_ALLOC
)
5082 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5083 || h
->root
.type
!= bfd_link_hash_undefweak
))
5085 Elf_Internal_Rela outrel
;
5087 bfd_boolean skip
, relocate
;
5090 *unresolved_reloc_p
= FALSE
;
5095 outrel
.r_addend
= signed_addend
;
5097 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
5099 if (outrel
.r_offset
== (bfd_vma
) - 1)
5101 else if (outrel
.r_offset
== (bfd_vma
) - 2)
5107 outrel
.r_offset
+= (input_section
->output_section
->vma
5108 + input_section
->output_offset
);
5111 memset (&outrel
, 0, sizeof outrel
);
5114 && (!bfd_link_pic (info
)
5115 || !SYMBOLIC_BIND (info
, h
)
5116 || !h
->def_regular
))
5117 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
5122 /* On SVR4-ish systems, the dynamic loader cannot
5123 relocate the text and data segments independently,
5124 so the symbol does not matter. */
5126 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
5127 outrel
.r_addend
+= value
;
5130 sreloc
= elf_section_data (input_section
)->sreloc
;
5131 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
5132 return bfd_reloc_notsupported
;
5134 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
5135 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
5137 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
5139 /* Sanity to check that we have previously allocated
5140 sufficient space in the relocation section for the
5141 number of relocations we actually want to emit. */
5145 /* If this reloc is against an external symbol, we do not want to
5146 fiddle with the addend. Otherwise, we need to include the symbol
5147 value so that it becomes an addend for the dynamic reloc. */
5149 return bfd_reloc_ok
;
5151 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
5152 contents
, rel
->r_offset
, value
,
5156 value
+= signed_addend
;
5159 case BFD_RELOC_AARCH64_CALL26
:
5160 case BFD_RELOC_AARCH64_JUMP26
:
5162 asection
*splt
= globals
->root
.splt
;
5163 bfd_boolean via_plt_p
=
5164 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
5166 /* A call to an undefined weak symbol is converted to a jump to
5167 the next instruction unless a PLT entry will be created.
5168 The jump to the next instruction is optimized as a NOP.
5169 Do the same for local undefined symbols. */
5170 if (weak_undef_p
&& ! via_plt_p
)
5172 bfd_putl32 (INSN_NOP
, hit_data
);
5173 return bfd_reloc_ok
;
5176 /* If the call goes through a PLT entry, make sure to
5177 check distance to the right destination address. */
5179 value
= (splt
->output_section
->vma
5180 + splt
->output_offset
+ h
->plt
.offset
);
5182 /* Check if a stub has to be inserted because the destination
5184 struct elf_aarch64_stub_hash_entry
*stub_entry
= NULL
;
5185 if (! aarch64_valid_branch_p (value
, place
))
5186 /* The target is out of reach, so redirect the branch to
5187 the local stub for this function. */
5188 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
, sym_sec
, h
,
5190 if (stub_entry
!= NULL
)
5191 value
= (stub_entry
->stub_offset
5192 + stub_entry
->stub_sec
->output_offset
5193 + stub_entry
->stub_sec
->output_section
->vma
);
5195 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5196 signed_addend
, weak_undef_p
);
5197 *unresolved_reloc_p
= FALSE
;
5200 case BFD_RELOC_AARCH64_16_PCREL
:
5201 case BFD_RELOC_AARCH64_32_PCREL
:
5202 case BFD_RELOC_AARCH64_64_PCREL
:
5203 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
5204 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5205 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
5206 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
5207 if (bfd_link_pic (info
)
5208 && (input_section
->flags
& SEC_ALLOC
) != 0
5209 && (input_section
->flags
& SEC_READONLY
) != 0
5213 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
5215 (*_bfd_error_handler
)
5216 (_("%B: relocation %s against external symbol `%s' can not be used"
5217 " when making a shared object; recompile with -fPIC"),
5218 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
5219 h
->root
.root
.string
);
5220 bfd_set_error (bfd_error_bad_value
);
5224 case BFD_RELOC_AARCH64_16
:
5226 case BFD_RELOC_AARCH64_32
:
5228 case BFD_RELOC_AARCH64_ADD_LO12
:
5229 case BFD_RELOC_AARCH64_BRANCH19
:
5230 case BFD_RELOC_AARCH64_LDST128_LO12
:
5231 case BFD_RELOC_AARCH64_LDST16_LO12
:
5232 case BFD_RELOC_AARCH64_LDST32_LO12
:
5233 case BFD_RELOC_AARCH64_LDST64_LO12
:
5234 case BFD_RELOC_AARCH64_LDST8_LO12
:
5235 case BFD_RELOC_AARCH64_MOVW_G0
:
5236 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
5237 case BFD_RELOC_AARCH64_MOVW_G0_S
:
5238 case BFD_RELOC_AARCH64_MOVW_G1
:
5239 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
5240 case BFD_RELOC_AARCH64_MOVW_G1_S
:
5241 case BFD_RELOC_AARCH64_MOVW_G2
:
5242 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
5243 case BFD_RELOC_AARCH64_MOVW_G2_S
:
5244 case BFD_RELOC_AARCH64_MOVW_G3
:
5245 case BFD_RELOC_AARCH64_TSTBR14
:
5246 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5247 signed_addend
, weak_undef_p
);
5250 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5251 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5252 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5253 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5254 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5255 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5256 if (globals
->root
.sgot
== NULL
)
5257 BFD_ASSERT (h
!= NULL
);
5262 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
, value
,
5264 unresolved_reloc_p
);
5265 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5266 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
5267 addend
= (globals
->root
.sgot
->output_section
->vma
5268 + globals
->root
.sgot
->output_offset
);
5269 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5270 addend
, weak_undef_p
);
5275 struct elf_aarch64_local_symbol
*locals
5276 = elf_aarch64_locals (input_bfd
);
5280 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
5281 (*_bfd_error_handler
)
5282 (_("%B: Local symbol descriptor table be NULL when applying "
5283 "relocation %s against local symbol"),
5284 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
5288 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5289 base_got
= globals
->root
.sgot
;
5290 bfd_vma got_entry_addr
= (base_got
->output_section
->vma
5291 + base_got
->output_offset
+ off
);
5293 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5295 bfd_put_64 (output_bfd
, value
, base_got
->contents
+ off
);
5297 if (bfd_link_pic (info
))
5300 Elf_Internal_Rela outrel
;
5302 /* For local symbol, we have done absolute relocation in static
5303 linking stageh. While for share library, we need to update
5304 the content of GOT entry according to the share objects
5305 loading base address. So we need to generate a
5306 R_AARCH64_RELATIVE reloc for dynamic linker. */
5307 s
= globals
->root
.srelgot
;
5311 outrel
.r_offset
= got_entry_addr
;
5312 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
5313 outrel
.r_addend
= value
;
5314 elf_append_rela (output_bfd
, s
, &outrel
);
5317 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5320 /* Update the relocation value to GOT entry addr as we have transformed
5321 the direct data access into indirect data access through GOT. */
5322 value
= got_entry_addr
;
5324 if (bfd_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5325 || bfd_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
5326 addend
= base_got
->output_section
->vma
+ base_got
->output_offset
;
5328 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5329 addend
, weak_undef_p
);
5334 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
5336 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
, value
,
5338 unresolved_reloc_p
);
5341 struct elf_aarch64_local_symbol
*locals
5342 = elf_aarch64_locals (input_bfd
);
5346 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
5347 (*_bfd_error_handler
)
5348 (_("%B: Local symbol descriptor table be NULL when applying "
5349 "relocation %s against local symbol"),
5350 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
5354 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5355 base_got
= globals
->root
.sgot
;
5356 if (base_got
== NULL
)
5359 bfd_vma got_entry_addr
= (base_got
->output_section
->vma
5360 + base_got
->output_offset
+ off
);
5362 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5364 bfd_put_64 (output_bfd
, value
, base_got
->contents
+ off
);
5366 if (bfd_link_pic (info
))
5369 Elf_Internal_Rela outrel
;
5371 /* For local symbol, we have done absolute relocation in static
5372 linking stage. While for share library, we need to update
5373 the content of GOT entry according to the share objects
5374 loading base address. So we need to generate a
5375 R_AARCH64_RELATIVE reloc for dynamic linker. */
5376 s
= globals
->root
.srelgot
;
5380 outrel
.r_offset
= got_entry_addr
;
5381 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
5382 outrel
.r_addend
= value
;
5383 elf_append_rela (output_bfd
, s
, &outrel
);
5386 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
5390 /* Update the relocation value to GOT entry addr as we have transformed
5391 the direct data access into indirect data access through GOT. */
5392 value
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5393 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5395 *unresolved_reloc_p
= FALSE
;
5398 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5399 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5400 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5401 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5402 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5403 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5404 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5405 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5406 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5407 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5408 if (globals
->root
.sgot
== NULL
)
5409 return bfd_reloc_notsupported
;
5411 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
5412 + globals
->root
.sgot
->output_section
->vma
5413 + globals
->root
.sgot
->output_offset
);
5415 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5417 *unresolved_reloc_p
= FALSE
;
5420 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
5421 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
5422 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
5423 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
5424 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
5425 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
5426 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
5427 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
5428 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
5429 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
5430 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
5431 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
5432 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
5433 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
5434 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
5435 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
5436 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5437 signed_addend
- dtpoff_base (info
),
5441 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
5442 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
5443 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
5444 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
5445 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
5446 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
5447 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
5448 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
5449 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5450 signed_addend
- tpoff_base (info
),
5452 *unresolved_reloc_p
= FALSE
;
5455 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5456 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5457 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5458 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5459 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5460 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
5461 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5462 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5463 if (globals
->root
.sgot
== NULL
)
5464 return bfd_reloc_notsupported
;
5465 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
5466 + globals
->root
.sgotplt
->output_section
->vma
5467 + globals
->root
.sgotplt
->output_offset
5468 + globals
->sgotplt_jump_table_size
);
5470 value
= _bfd_aarch64_elf_resolve_relocation (bfd_r_type
, place
, value
,
5472 *unresolved_reloc_p
= FALSE
;
5476 return bfd_reloc_notsupported
;
5480 *saved_addend
= value
;
5482 /* Only apply the final relocation in a sequence. */
5484 return bfd_reloc_continue
;
5486 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
5490 /* Handle TLS relaxations. Relaxing is possible for symbols that use
5491 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
5494 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
5495 is to then call final_link_relocate. Return other values in the
5498 static bfd_reloc_status_type
5499 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table
*globals
,
5500 bfd
*input_bfd
, bfd_byte
*contents
,
5501 Elf_Internal_Rela
*rel
, struct elf_link_hash_entry
*h
)
5503 bfd_boolean is_local
= h
== NULL
;
5504 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
5507 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
5509 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
5511 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5512 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5515 /* GD->LE relaxation:
5516 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
5518 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
5520 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
5521 return bfd_reloc_continue
;
5525 /* GD->IE relaxation:
5526 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
5528 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
5530 return bfd_reloc_continue
;
5533 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5537 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5540 /* Tiny TLSDESC->LE relaxation:
5541 ldr x1, :tlsdesc:var => movz x0, #:tprel_g1:var
5542 adr x0, :tlsdesc:var => movk x0, #:tprel_g0_nc:var
5546 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
5547 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
5549 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5550 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
5551 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5553 bfd_putl32 (0xd2a00000, contents
+ rel
->r_offset
);
5554 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
+ 4);
5555 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
5556 return bfd_reloc_continue
;
5560 /* Tiny TLSDESC->IE relaxation:
5561 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
5562 adr x0, :tlsdesc:var => nop
5566 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
5567 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
5569 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5570 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5572 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
5573 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
5574 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
5575 return bfd_reloc_continue
;
5578 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5581 /* Tiny GD->LE relaxation:
5582 adr x0, :tlsgd:var => mrs x1, tpidr_el0
5583 bl __tls_get_addr => add x0, x1, #:tprel_hi12:x, lsl #12
5584 nop => add x0, x0, #:tprel_lo12_nc:x
5587 /* First kill the tls_get_addr reloc on the bl instruction. */
5588 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5590 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
5591 bfd_putl32 (0x91400020, contents
+ rel
->r_offset
+ 4);
5592 bfd_putl32 (0x91000000, contents
+ rel
->r_offset
+ 8);
5594 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5595 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
5596 rel
[1].r_offset
= rel
->r_offset
+ 8;
5598 /* Move the current relocation to the second instruction in
5601 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
5602 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
5603 return bfd_reloc_continue
;
5607 /* Tiny GD->IE relaxation:
5608 adr x0, :tlsgd:var => ldr x0, :gottprel:var
5609 bl __tls_get_addr => mrs x1, tpidr_el0
5610 nop => add x0, x0, x1
5613 /* First kill the tls_get_addr reloc on the bl instruction. */
5614 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5615 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5617 bfd_putl32 (0x58000000, contents
+ rel
->r_offset
);
5618 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
5619 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
5620 return bfd_reloc_continue
;
5623 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5624 return bfd_reloc_continue
;
5626 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5629 /* GD->LE relaxation:
5630 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
5632 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
5633 return bfd_reloc_continue
;
5637 /* GD->IE relaxation:
5638 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
5640 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5642 bfd_putl32 (insn
, contents
+ rel
->r_offset
);
5643 return bfd_reloc_continue
;
5646 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5649 /* GD->LE relaxation
5650 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
5651 bl __tls_get_addr => mrs x1, tpidr_el0
5652 nop => add x0, x1, x0
5655 /* First kill the tls_get_addr reloc on the bl instruction. */
5656 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5657 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5659 bfd_putl32 (0xf2800000, contents
+ rel
->r_offset
);
5660 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
5661 bfd_putl32 (0x8b000020, contents
+ rel
->r_offset
+ 8);
5662 return bfd_reloc_continue
;
5666 /* GD->IE relaxation
5667 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
5668 BL __tls_get_addr => mrs x1, tpidr_el0
5670 NOP => add x0, x1, x0
5673 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
5675 /* Remove the relocation on the BL instruction. */
5676 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5678 bfd_putl32 (0xf9400000, contents
+ rel
->r_offset
);
5680 /* We choose to fixup the BL and NOP instructions using the
5681 offset from the second relocation to allow flexibility in
5682 scheduling instructions between the ADD and BL. */
5683 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
5684 bfd_putl32 (0x8b000020, contents
+ rel
[1].r_offset
+ 4);
5685 return bfd_reloc_continue
;
5688 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
5689 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5690 /* GD->IE/LE relaxation:
5691 add x0, x0, #:tlsdesc_lo12:var => nop
5694 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
5695 return bfd_reloc_ok
;
5697 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5698 /* IE->LE relaxation:
5699 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
5703 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5704 bfd_putl32 (0xd2a00000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
5706 return bfd_reloc_continue
;
5708 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5709 /* IE->LE relaxation:
5710 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
5714 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
5715 bfd_putl32 (0xf2800000 | (insn
& 0x1f), contents
+ rel
->r_offset
);
5717 return bfd_reloc_continue
;
5719 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5720 /* LD->LE relaxation (tiny):
5721 adr x0, :tlsldm:x => mrs x0, tpidr_el0
5722 bl __tls_get_addr => add x0, x0, TCB_SIZE
5726 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5727 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
5728 /* No need of CALL26 relocation for tls_get_addr. */
5729 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5730 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
+ 0);
5731 bfd_putl32 (0x91004000, contents
+ rel
->r_offset
+ 4);
5732 return bfd_reloc_ok
;
5734 return bfd_reloc_continue
;
5736 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5737 /* LD->LE relaxation (small):
5738 adrp x0, :tlsldm:x => mrs x0, tpidr_el0
5742 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
);
5743 return bfd_reloc_ok
;
5745 return bfd_reloc_continue
;
5747 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5748 /* LD->LE relaxation (small):
5749 add x0, #:tlsldm_lo12:x => add x0, x0, TCB_SIZE
5750 bl __tls_get_addr => nop
5754 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
5755 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
5756 /* No need of CALL26 relocation for tls_get_addr. */
5757 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
5758 bfd_putl32 (0x91004000, contents
+ rel
->r_offset
+ 0);
5759 bfd_putl32 (0xd503201f, contents
+ rel
->r_offset
+ 4);
5760 return bfd_reloc_ok
;
5762 return bfd_reloc_continue
;
5765 return bfd_reloc_continue
;
5768 return bfd_reloc_ok
;
5771 /* Relocate an AArch64 ELF section. */
5774 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
5775 struct bfd_link_info
*info
,
5777 asection
*input_section
,
5779 Elf_Internal_Rela
*relocs
,
5780 Elf_Internal_Sym
*local_syms
,
5781 asection
**local_sections
)
5783 Elf_Internal_Shdr
*symtab_hdr
;
5784 struct elf_link_hash_entry
**sym_hashes
;
5785 Elf_Internal_Rela
*rel
;
5786 Elf_Internal_Rela
*relend
;
5788 struct elf_aarch64_link_hash_table
*globals
;
5789 bfd_boolean save_addend
= FALSE
;
5792 globals
= elf_aarch64_hash_table (info
);
5794 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
5795 sym_hashes
= elf_sym_hashes (input_bfd
);
5798 relend
= relocs
+ input_section
->reloc_count
;
5799 for (; rel
< relend
; rel
++)
5801 unsigned int r_type
;
5802 bfd_reloc_code_real_type bfd_r_type
;
5803 bfd_reloc_code_real_type relaxed_bfd_r_type
;
5804 reloc_howto_type
*howto
;
5805 unsigned long r_symndx
;
5806 Elf_Internal_Sym
*sym
;
5808 struct elf_link_hash_entry
*h
;
5810 bfd_reloc_status_type r
;
5813 bfd_boolean unresolved_reloc
= FALSE
;
5814 char *error_message
= NULL
;
5816 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5817 r_type
= ELFNN_R_TYPE (rel
->r_info
);
5819 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (r_type
);
5820 howto
= bfd_reloc
.howto
;
5824 (*_bfd_error_handler
)
5825 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
5826 input_bfd
, input_section
, r_type
);
5829 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
5835 if (r_symndx
< symtab_hdr
->sh_info
)
5837 sym
= local_syms
+ r_symndx
;
5838 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
5839 sec
= local_sections
[r_symndx
];
5841 /* An object file might have a reference to a local
5842 undefined symbol. This is a daft object file, but we
5843 should at least do something about it. */
5844 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
5845 && bfd_is_und_section (sec
)
5846 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
5848 if (!info
->callbacks
->undefined_symbol
5849 (info
, bfd_elf_string_from_elf_section
5850 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
5851 input_bfd
, input_section
, rel
->r_offset
, TRUE
))
5855 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
5857 /* Relocate against local STT_GNU_IFUNC symbol. */
5858 if (!bfd_link_relocatable (info
)
5859 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
5861 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
5866 /* Set STT_GNU_IFUNC symbol value. */
5867 h
->root
.u
.def
.value
= sym
->st_value
;
5868 h
->root
.u
.def
.section
= sec
;
5873 bfd_boolean warned
, ignored
;
5875 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
5876 r_symndx
, symtab_hdr
, sym_hashes
,
5878 unresolved_reloc
, warned
, ignored
);
5883 if (sec
!= NULL
&& discarded_section (sec
))
5884 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
5885 rel
, 1, relend
, howto
, 0, contents
);
5887 if (bfd_link_relocatable (info
))
5891 name
= h
->root
.root
.string
;
5894 name
= (bfd_elf_string_from_elf_section
5895 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
5896 if (name
== NULL
|| *name
== '\0')
5897 name
= bfd_section_name (input_bfd
, sec
);
5901 && r_type
!= R_AARCH64_NONE
5902 && r_type
!= R_AARCH64_NULL
5904 || h
->root
.type
== bfd_link_hash_defined
5905 || h
->root
.type
== bfd_link_hash_defweak
)
5906 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
5908 (*_bfd_error_handler
)
5909 ((sym_type
== STT_TLS
5910 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
5911 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
5913 input_section
, (long) rel
->r_offset
, howto
->name
, name
);
5916 /* We relax only if we can see that there can be a valid transition
5917 from a reloc type to another.
5918 We call elfNN_aarch64_final_link_relocate unless we're completely
5919 done, i.e., the relaxation produced the final output we want. */
5921 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
,
5923 if (relaxed_bfd_r_type
!= bfd_r_type
)
5925 bfd_r_type
= relaxed_bfd_r_type
;
5926 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
5927 BFD_ASSERT (howto
!= NULL
);
5928 r_type
= howto
->type
;
5929 r
= elfNN_aarch64_tls_relax (globals
, input_bfd
, contents
, rel
, h
);
5930 unresolved_reloc
= 0;
5933 r
= bfd_reloc_continue
;
5935 /* There may be multiple consecutive relocations for the
5936 same offset. In that case we are supposed to treat the
5937 output of each relocation as the addend for the next. */
5938 if (rel
+ 1 < relend
5939 && rel
->r_offset
== rel
[1].r_offset
5940 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
5941 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
5944 save_addend
= FALSE
;
5946 if (r
== bfd_reloc_continue
)
5947 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
5948 input_section
, contents
, rel
,
5949 relocation
, info
, sec
,
5950 h
, &unresolved_reloc
,
5951 save_addend
, &addend
, sym
);
5953 switch (elfNN_aarch64_bfd_reloc_from_type (r_type
))
5955 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5956 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5957 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5958 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5959 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5960 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5961 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
5963 bfd_boolean need_relocs
= FALSE
;
5968 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
5969 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
5972 (bfd_link_pic (info
) || indx
!= 0) &&
5974 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5975 || h
->root
.type
!= bfd_link_hash_undefweak
);
5977 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
5981 Elf_Internal_Rela rela
;
5982 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
5984 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
5985 globals
->root
.sgot
->output_offset
+ off
;
5988 loc
= globals
->root
.srelgot
->contents
;
5989 loc
+= globals
->root
.srelgot
->reloc_count
++
5990 * RELOC_SIZE (htab
);
5991 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
5993 bfd_reloc_code_real_type real_type
=
5994 elfNN_aarch64_bfd_reloc_from_type (r_type
);
5996 if (real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
5997 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
5998 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
)
6000 /* For local dynamic, don't generate DTPREL in any case.
6001 Initialize the DTPREL slot into zero, so we get module
6002 base address when invoke runtime TLS resolver. */
6003 bfd_put_NN (output_bfd
, 0,
6004 globals
->root
.sgot
->contents
+ off
6009 bfd_put_NN (output_bfd
,
6010 relocation
- dtpoff_base (info
),
6011 globals
->root
.sgot
->contents
+ off
6016 /* This TLS symbol is global. We emit a
6017 relocation to fixup the tls offset at load
6020 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
6023 (globals
->root
.sgot
->output_section
->vma
6024 + globals
->root
.sgot
->output_offset
+ off
6027 loc
= globals
->root
.srelgot
->contents
;
6028 loc
+= globals
->root
.srelgot
->reloc_count
++
6029 * RELOC_SIZE (globals
);
6030 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
6031 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
6032 globals
->root
.sgot
->contents
+ off
6038 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
6039 globals
->root
.sgot
->contents
+ off
);
6040 bfd_put_NN (output_bfd
,
6041 relocation
- dtpoff_base (info
),
6042 globals
->root
.sgot
->contents
+ off
6046 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
6050 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6051 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
6052 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6053 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
6055 bfd_boolean need_relocs
= FALSE
;
6060 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
6062 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
6065 (bfd_link_pic (info
) || indx
!= 0) &&
6067 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
6068 || h
->root
.type
!= bfd_link_hash_undefweak
);
6070 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
6074 Elf_Internal_Rela rela
;
6077 rela
.r_addend
= relocation
- dtpoff_base (info
);
6081 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
6082 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
6083 globals
->root
.sgot
->output_offset
+ off
;
6085 loc
= globals
->root
.srelgot
->contents
;
6086 loc
+= globals
->root
.srelgot
->reloc_count
++
6087 * RELOC_SIZE (htab
);
6089 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
6091 bfd_put_NN (output_bfd
, rela
.r_addend
,
6092 globals
->root
.sgot
->contents
+ off
);
6095 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
6096 globals
->root
.sgot
->contents
+ off
);
6098 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
6102 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6103 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6104 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6105 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
6106 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6107 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
6109 bfd_boolean need_relocs
= FALSE
;
6110 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
6111 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
6113 need_relocs
= (h
== NULL
6114 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
6115 || h
->root
.type
!= bfd_link_hash_undefweak
);
6117 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
6118 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
6123 Elf_Internal_Rela rela
;
6124 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLSDESC
));
6127 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
6128 + globals
->root
.sgotplt
->output_offset
6129 + off
+ globals
->sgotplt_jump_table_size
);
6132 rela
.r_addend
= relocation
- dtpoff_base (info
);
6134 /* Allocate the next available slot in the PLT reloc
6135 section to hold our R_AARCH64_TLSDESC, the next
6136 available slot is determined from reloc_count,
6137 which we step. But note, reloc_count was
6138 artifically moved down while allocating slots for
6139 real PLT relocs such that all of the PLT relocs
6140 will fit above the initial reloc_count and the
6141 extra stuff will fit below. */
6142 loc
= globals
->root
.srelplt
->contents
;
6143 loc
+= globals
->root
.srelplt
->reloc_count
++
6144 * RELOC_SIZE (globals
);
6146 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
6148 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
6149 globals
->root
.sgotplt
->contents
+ off
+
6150 globals
->sgotplt_jump_table_size
);
6151 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
6152 globals
->root
.sgotplt
->contents
+ off
+
6153 globals
->sgotplt_jump_table_size
+
6157 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
6168 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
6169 because such sections are not SEC_ALLOC and thus ld.so will
6170 not process them. */
6171 if (unresolved_reloc
6172 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
6174 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
6175 +rel
->r_offset
) != (bfd_vma
) - 1)
6177 (*_bfd_error_handler
)
6179 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
6180 input_bfd
, input_section
, (long) rel
->r_offset
, howto
->name
,
6181 h
->root
.root
.string
);
6185 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
6187 bfd_reloc_code_real_type real_r_type
6188 = elfNN_aarch64_bfd_reloc_from_type (r_type
);
6192 case bfd_reloc_overflow
:
6193 if (!(*info
->callbacks
->reloc_overflow
)
6194 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
6195 input_bfd
, input_section
, rel
->r_offset
))
6197 if (real_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
6198 || real_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
6200 (*info
->callbacks
->warning
)
6202 _("Too many GOT entries for -fpic, "
6203 "please recompile with -fPIC"),
6204 name
, input_bfd
, input_section
, rel
->r_offset
);
6209 case bfd_reloc_undefined
:
6210 if (!((*info
->callbacks
->undefined_symbol
)
6211 (info
, name
, input_bfd
, input_section
,
6212 rel
->r_offset
, TRUE
)))
6216 case bfd_reloc_outofrange
:
6217 error_message
= _("out of range");
6220 case bfd_reloc_notsupported
:
6221 error_message
= _("unsupported relocation");
6224 case bfd_reloc_dangerous
:
6225 /* error_message should already be set. */
6229 error_message
= _("unknown error");
6233 BFD_ASSERT (error_message
!= NULL
);
6234 if (!((*info
->callbacks
->reloc_dangerous
)
6235 (info
, error_message
, input_bfd
, input_section
,
6246 /* Set the right machine number. */
6249 elfNN_aarch64_object_p (bfd
*abfd
)
6252 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
6254 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
6259 /* Function to keep AArch64 specific flags in the ELF header. */
6262 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
6264 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
6269 elf_elfheader (abfd
)->e_flags
= flags
;
6270 elf_flags_init (abfd
) = TRUE
;
6276 /* Merge backend specific data from an object file to the output
6277 object file when linking. */
6280 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
6284 bfd_boolean flags_compatible
= TRUE
;
6287 /* Check if we have the same endianess. */
6288 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
6291 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
6294 /* The input BFD must have had its flags initialised. */
6295 /* The following seems bogus to me -- The flags are initialized in
6296 the assembler but I don't think an elf_flags_init field is
6297 written into the object. */
6298 /* BFD_ASSERT (elf_flags_init (ibfd)); */
6300 in_flags
= elf_elfheader (ibfd
)->e_flags
;
6301 out_flags
= elf_elfheader (obfd
)->e_flags
;
6303 if (!elf_flags_init (obfd
))
6305 /* If the input is the default architecture and had the default
6306 flags then do not bother setting the flags for the output
6307 architecture, instead allow future merges to do this. If no
6308 future merges ever set these flags then they will retain their
6309 uninitialised values, which surprise surprise, correspond
6310 to the default values. */
6311 if (bfd_get_arch_info (ibfd
)->the_default
6312 && elf_elfheader (ibfd
)->e_flags
== 0)
6315 elf_flags_init (obfd
) = TRUE
;
6316 elf_elfheader (obfd
)->e_flags
= in_flags
;
6318 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
6319 && bfd_get_arch_info (obfd
)->the_default
)
6320 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
6321 bfd_get_mach (ibfd
));
6326 /* Identical flags must be compatible. */
6327 if (in_flags
== out_flags
)
6330 /* Check to see if the input BFD actually contains any sections. If
6331 not, its flags may not have been initialised either, but it
6332 cannot actually cause any incompatiblity. Do not short-circuit
6333 dynamic objects; their section list may be emptied by
6334 elf_link_add_object_symbols.
6336 Also check to see if there are no code sections in the input.
6337 In this case there is no need to check for code specific flags.
6338 XXX - do we need to worry about floating-point format compatability
6339 in data sections ? */
6340 if (!(ibfd
->flags
& DYNAMIC
))
6342 bfd_boolean null_input_bfd
= TRUE
;
6343 bfd_boolean only_data_sections
= TRUE
;
6345 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
6347 if ((bfd_get_section_flags (ibfd
, sec
)
6348 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
6349 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
6350 only_data_sections
= FALSE
;
6352 null_input_bfd
= FALSE
;
6356 if (null_input_bfd
|| only_data_sections
)
6360 return flags_compatible
;
6363 /* Display the flags field. */
6366 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
6368 FILE *file
= (FILE *) ptr
;
6369 unsigned long flags
;
6371 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
6373 /* Print normal ELF private data. */
6374 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
6376 flags
= elf_elfheader (abfd
)->e_flags
;
6377 /* Ignore init flag - it may not be set, despite the flags field
6378 containing valid data. */
6380 /* xgettext:c-format */
6381 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
6384 fprintf (file
, _("<Unrecognised flag bits set>"));
6391 /* Update the got entry reference counts for the section being removed. */
6394 elfNN_aarch64_gc_sweep_hook (bfd
*abfd
,
6395 struct bfd_link_info
*info
,
6397 const Elf_Internal_Rela
* relocs
)
6399 struct elf_aarch64_link_hash_table
*htab
;
6400 Elf_Internal_Shdr
*symtab_hdr
;
6401 struct elf_link_hash_entry
**sym_hashes
;
6402 struct elf_aarch64_local_symbol
*locals
;
6403 const Elf_Internal_Rela
*rel
, *relend
;
6405 if (bfd_link_relocatable (info
))
6408 htab
= elf_aarch64_hash_table (info
);
6413 elf_section_data (sec
)->local_dynrel
= NULL
;
6415 symtab_hdr
= &elf_symtab_hdr (abfd
);
6416 sym_hashes
= elf_sym_hashes (abfd
);
6418 locals
= elf_aarch64_locals (abfd
);
6420 relend
= relocs
+ sec
->reloc_count
;
6421 for (rel
= relocs
; rel
< relend
; rel
++)
6423 unsigned long r_symndx
;
6424 unsigned int r_type
;
6425 struct elf_link_hash_entry
*h
= NULL
;
6427 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6429 if (r_symndx
>= symtab_hdr
->sh_info
)
6432 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
6433 while (h
->root
.type
== bfd_link_hash_indirect
6434 || h
->root
.type
== bfd_link_hash_warning
)
6435 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6439 Elf_Internal_Sym
*isym
;
6441 /* A local symbol. */
6442 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6445 /* Check relocation against local STT_GNU_IFUNC symbol. */
6447 && ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
6449 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
, FALSE
);
6457 struct elf_aarch64_link_hash_entry
*eh
;
6458 struct elf_dyn_relocs
**pp
;
6459 struct elf_dyn_relocs
*p
;
6461 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6463 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
; pp
= &p
->next
)
6466 /* Everything must go for SEC. */
6472 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6473 switch (aarch64_tls_transition (abfd
,info
, r_type
, h
,r_symndx
))
6475 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6476 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6477 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6478 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6479 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
6480 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6481 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6482 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6483 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6484 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6485 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6486 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
6487 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6488 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6489 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6490 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6491 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6492 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6493 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6494 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6495 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6496 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6497 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6500 if (h
->got
.refcount
> 0)
6501 h
->got
.refcount
-= 1;
6503 if (h
->type
== STT_GNU_IFUNC
)
6505 if (h
->plt
.refcount
> 0)
6506 h
->plt
.refcount
-= 1;
6509 else if (locals
!= NULL
)
6511 if (locals
[r_symndx
].got_refcount
> 0)
6512 locals
[r_symndx
].got_refcount
-= 1;
6516 case BFD_RELOC_AARCH64_CALL26
:
6517 case BFD_RELOC_AARCH64_JUMP26
:
6518 /* If this is a local symbol then we resolve it
6519 directly without creating a PLT entry. */
6523 if (h
->plt
.refcount
> 0)
6524 h
->plt
.refcount
-= 1;
6527 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6528 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6529 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6530 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6531 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6532 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6533 case BFD_RELOC_AARCH64_MOVW_G3
:
6534 case BFD_RELOC_AARCH64_NN
:
6535 if (h
!= NULL
&& bfd_link_executable (info
))
6537 if (h
->plt
.refcount
> 0)
6538 h
->plt
.refcount
-= 1;
6550 /* Adjust a symbol defined by a dynamic object and referenced by a
6551 regular object. The current definition is in some section of the
6552 dynamic object, but we're not including those sections. We have to
6553 change the definition to something the rest of the link can
6557 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
6558 struct elf_link_hash_entry
*h
)
6560 struct elf_aarch64_link_hash_table
*htab
;
6563 /* If this is a function, put it in the procedure linkage table. We
6564 will fill in the contents of the procedure linkage table later,
6565 when we know the address of the .got section. */
6566 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
6568 if (h
->plt
.refcount
<= 0
6569 || (h
->type
!= STT_GNU_IFUNC
6570 && (SYMBOL_CALLS_LOCAL (info
, h
)
6571 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
6572 && h
->root
.type
== bfd_link_hash_undefweak
))))
6574 /* This case can occur if we saw a CALL26 reloc in
6575 an input file, but the symbol wasn't referred to
6576 by a dynamic object or all references were
6577 garbage collected. In which case we can end up
6579 h
->plt
.offset
= (bfd_vma
) - 1;
6586 /* Otherwise, reset to -1. */
6587 h
->plt
.offset
= (bfd_vma
) - 1;
6590 /* If this is a weak symbol, and there is a real definition, the
6591 processor independent code will have arranged for us to see the
6592 real definition first, and we can just use the same value. */
6593 if (h
->u
.weakdef
!= NULL
)
6595 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
6596 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
6597 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
6598 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
6599 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
6600 h
->non_got_ref
= h
->u
.weakdef
->non_got_ref
;
6604 /* If we are creating a shared library, we must presume that the
6605 only references to the symbol are via the global offset table.
6606 For such cases we need not do anything here; the relocations will
6607 be handled correctly by relocate_section. */
6608 if (bfd_link_pic (info
))
6611 /* If there are no references to this symbol that do not use the
6612 GOT, we don't need to generate a copy reloc. */
6613 if (!h
->non_got_ref
)
6616 /* If -z nocopyreloc was given, we won't generate them either. */
6617 if (info
->nocopyreloc
)
6623 /* We must allocate the symbol in our .dynbss section, which will
6624 become part of the .bss section of the executable. There will be
6625 an entry for this symbol in the .dynsym section. The dynamic
6626 object will contain position independent code, so all references
6627 from the dynamic object to this symbol will go through the global
6628 offset table. The dynamic linker will use the .dynsym entry to
6629 determine the address it must put in the global offset table, so
6630 both the dynamic object and the regular object will refer to the
6631 same memory location for the variable. */
6633 htab
= elf_aarch64_hash_table (info
);
6635 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
6636 to copy the initial value out of the dynamic object and into the
6637 runtime process image. */
6638 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
6640 htab
->srelbss
->size
+= RELOC_SIZE (htab
);
6646 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
6651 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
6653 struct elf_aarch64_local_symbol
*locals
;
6654 locals
= elf_aarch64_locals (abfd
);
6657 locals
= (struct elf_aarch64_local_symbol
*)
6658 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
6661 elf_aarch64_locals (abfd
) = locals
;
6666 /* Create the .got section to hold the global offset table. */
6669 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
6671 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
6674 struct elf_link_hash_entry
*h
;
6675 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
6677 /* This function may be called more than once. */
6678 s
= bfd_get_linker_section (abfd
, ".got");
6682 flags
= bed
->dynamic_sec_flags
;
6684 s
= bfd_make_section_anyway_with_flags (abfd
,
6685 (bed
->rela_plts_and_copies_p
6686 ? ".rela.got" : ".rel.got"),
6687 (bed
->dynamic_sec_flags
6690 || ! bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
6694 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
6696 || !bfd_set_section_alignment (abfd
, s
, bed
->s
->log_file_align
))
6699 htab
->sgot
->size
+= GOT_ENTRY_SIZE
;
6701 if (bed
->want_got_sym
)
6703 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
6704 (or .got.plt) section. We don't do this in the linker script
6705 because we don't want to define the symbol if we are not creating
6706 a global offset table. */
6707 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
6708 "_GLOBAL_OFFSET_TABLE_");
6709 elf_hash_table (info
)->hgot
= h
;
6714 if (bed
->want_got_plt
)
6716 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
6718 || !bfd_set_section_alignment (abfd
, s
,
6719 bed
->s
->log_file_align
))
6724 /* The first bit of the global offset table is the header. */
6725 s
->size
+= bed
->got_header_size
;
6730 /* Look through the relocs for a section during the first phase. */
6733 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
6734 asection
*sec
, const Elf_Internal_Rela
*relocs
)
6736 Elf_Internal_Shdr
*symtab_hdr
;
6737 struct elf_link_hash_entry
**sym_hashes
;
6738 const Elf_Internal_Rela
*rel
;
6739 const Elf_Internal_Rela
*rel_end
;
6742 struct elf_aarch64_link_hash_table
*htab
;
6744 if (bfd_link_relocatable (info
))
6747 BFD_ASSERT (is_aarch64_elf (abfd
));
6749 htab
= elf_aarch64_hash_table (info
);
6752 symtab_hdr
= &elf_symtab_hdr (abfd
);
6753 sym_hashes
= elf_sym_hashes (abfd
);
6755 rel_end
= relocs
+ sec
->reloc_count
;
6756 for (rel
= relocs
; rel
< rel_end
; rel
++)
6758 struct elf_link_hash_entry
*h
;
6759 unsigned long r_symndx
;
6760 unsigned int r_type
;
6761 bfd_reloc_code_real_type bfd_r_type
;
6762 Elf_Internal_Sym
*isym
;
6764 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6765 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6767 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
6769 (*_bfd_error_handler
) (_("%B: bad symbol index: %d"), abfd
,
6774 if (r_symndx
< symtab_hdr
->sh_info
)
6776 /* A local symbol. */
6777 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6782 /* Check relocation against local STT_GNU_IFUNC symbol. */
6783 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
6785 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
6790 /* Fake a STT_GNU_IFUNC symbol. */
6791 h
->type
= STT_GNU_IFUNC
;
6794 h
->forced_local
= 1;
6795 h
->root
.type
= bfd_link_hash_defined
;
6802 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
6803 while (h
->root
.type
== bfd_link_hash_indirect
6804 || h
->root
.type
== bfd_link_hash_warning
)
6805 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
6807 /* PR15323, ref flags aren't set for references in the same
6809 h
->root
.non_ir_ref
= 1;
6812 /* Could be done earlier, if h were already available. */
6813 bfd_r_type
= aarch64_tls_transition (abfd
, info
, r_type
, h
, r_symndx
);
6817 /* Create the ifunc sections for static executables. If we
6818 never see an indirect function symbol nor we are building
6819 a static executable, those sections will be empty and
6820 won't appear in output. */
6826 case BFD_RELOC_AARCH64_ADD_LO12
:
6827 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6828 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6829 case BFD_RELOC_AARCH64_CALL26
:
6830 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6831 case BFD_RELOC_AARCH64_JUMP26
:
6832 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6833 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6834 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
6835 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6836 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6837 case BFD_RELOC_AARCH64_NN
:
6838 if (htab
->root
.dynobj
== NULL
)
6839 htab
->root
.dynobj
= abfd
;
6840 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
6845 /* It is referenced by a non-shared object. */
6847 h
->root
.non_ir_ref
= 1;
6852 case BFD_RELOC_AARCH64_NN
:
6854 /* We don't need to handle relocs into sections not going into
6855 the "real" output. */
6856 if ((sec
->flags
& SEC_ALLOC
) == 0)
6861 if (!bfd_link_pic (info
))
6864 h
->plt
.refcount
+= 1;
6865 h
->pointer_equality_needed
= 1;
6868 /* No need to do anything if we're not creating a shared
6870 if (! bfd_link_pic (info
))
6874 struct elf_dyn_relocs
*p
;
6875 struct elf_dyn_relocs
**head
;
6877 /* We must copy these reloc types into the output file.
6878 Create a reloc section in dynobj and make room for
6882 if (htab
->root
.dynobj
== NULL
)
6883 htab
->root
.dynobj
= abfd
;
6885 sreloc
= _bfd_elf_make_dynamic_reloc_section
6886 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ TRUE
);
6892 /* If this is a global symbol, we count the number of
6893 relocations we need for this symbol. */
6896 struct elf_aarch64_link_hash_entry
*eh
;
6897 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6898 head
= &eh
->dyn_relocs
;
6902 /* Track dynamic relocs needed for local syms too.
6903 We really need local syms available to do this
6909 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
6914 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
6918 /* Beware of type punned pointers vs strict aliasing
6920 vpp
= &(elf_section_data (s
)->local_dynrel
);
6921 head
= (struct elf_dyn_relocs
**) vpp
;
6925 if (p
== NULL
|| p
->sec
!= sec
)
6927 bfd_size_type amt
= sizeof *p
;
6928 p
= ((struct elf_dyn_relocs
*)
6929 bfd_zalloc (htab
->root
.dynobj
, amt
));
6942 /* RR: We probably want to keep a consistency check that
6943 there are no dangling GOT_PAGE relocs. */
6944 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6945 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6946 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6947 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6948 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
6949 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6950 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6951 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
:
6952 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6953 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6954 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6955 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
:
6956 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6957 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6958 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6959 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6960 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6961 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6962 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6963 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6964 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6965 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6966 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6969 unsigned old_got_type
;
6971 got_type
= aarch64_reloc_got_type (bfd_r_type
);
6975 h
->got
.refcount
+= 1;
6976 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
6980 struct elf_aarch64_local_symbol
*locals
;
6982 if (!elfNN_aarch64_allocate_local_symbols
6983 (abfd
, symtab_hdr
->sh_info
))
6986 locals
= elf_aarch64_locals (abfd
);
6987 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
6988 locals
[r_symndx
].got_refcount
+= 1;
6989 old_got_type
= locals
[r_symndx
].got_type
;
6992 /* If a variable is accessed with both general dynamic TLS
6993 methods, two slots may be created. */
6994 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
6995 got_type
|= old_got_type
;
6997 /* We will already have issued an error message if there
6998 is a TLS/non-TLS mismatch, based on the symbol type.
6999 So just combine any TLS types needed. */
7000 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
7001 && got_type
!= GOT_NORMAL
)
7002 got_type
|= old_got_type
;
7004 /* If the symbol is accessed by both IE and GD methods, we
7005 are able to relax. Turn off the GD flag, without
7006 messing up with any other kind of TLS types that may be
7008 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
7009 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
7011 if (old_got_type
!= got_type
)
7014 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
7017 struct elf_aarch64_local_symbol
*locals
;
7018 locals
= elf_aarch64_locals (abfd
);
7019 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
7020 locals
[r_symndx
].got_type
= got_type
;
7024 if (htab
->root
.dynobj
== NULL
)
7025 htab
->root
.dynobj
= abfd
;
7026 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
7031 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
7032 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
7033 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
7034 case BFD_RELOC_AARCH64_MOVW_G3
:
7035 if (bfd_link_pic (info
))
7037 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7038 (*_bfd_error_handler
)
7039 (_("%B: relocation %s against `%s' can not be used when making "
7040 "a shared object; recompile with -fPIC"),
7041 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7042 (h
) ? h
->root
.root
.string
: "a local symbol");
7043 bfd_set_error (bfd_error_bad_value
);
7047 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
7048 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
7049 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
7050 if (h
!= NULL
&& bfd_link_executable (info
))
7052 /* If this reloc is in a read-only section, we might
7053 need a copy reloc. We can't check reliably at this
7054 stage whether the section is read-only, as input
7055 sections have not yet been mapped to output sections.
7056 Tentatively set the flag for now, and correct in
7057 adjust_dynamic_symbol. */
7059 h
->plt
.refcount
+= 1;
7060 h
->pointer_equality_needed
= 1;
7062 /* FIXME:: RR need to handle these in shared libraries
7063 and essentially bomb out as these being non-PIC
7064 relocations in shared libraries. */
7067 case BFD_RELOC_AARCH64_CALL26
:
7068 case BFD_RELOC_AARCH64_JUMP26
:
7069 /* If this is a local symbol then we resolve it
7070 directly without creating a PLT entry. */
7075 if (h
->plt
.refcount
<= 0)
7076 h
->plt
.refcount
= 1;
7078 h
->plt
.refcount
+= 1;
7089 /* Treat mapping symbols as special target symbols. */
7092 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
7095 return bfd_is_aarch64_special_symbol_name (sym
->name
,
7096 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
7099 /* This is a copy of elf_find_function () from elf.c except that
7100 AArch64 mapping symbols are ignored when looking for function names. */
7103 aarch64_elf_find_function (bfd
*abfd ATTRIBUTE_UNUSED
,
7107 const char **filename_ptr
,
7108 const char **functionname_ptr
)
7110 const char *filename
= NULL
;
7111 asymbol
*func
= NULL
;
7112 bfd_vma low_func
= 0;
7115 for (p
= symbols
; *p
!= NULL
; p
++)
7119 q
= (elf_symbol_type
*) * p
;
7121 switch (ELF_ST_TYPE (q
->internal_elf_sym
.st_info
))
7126 filename
= bfd_asymbol_name (&q
->symbol
);
7130 /* Skip mapping symbols. */
7131 if ((q
->symbol
.flags
& BSF_LOCAL
)
7132 && (bfd_is_aarch64_special_symbol_name
7133 (q
->symbol
.name
, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
)))
7136 if (bfd_get_section (&q
->symbol
) == section
7137 && q
->symbol
.value
>= low_func
&& q
->symbol
.value
<= offset
)
7139 func
= (asymbol
*) q
;
7140 low_func
= q
->symbol
.value
;
7150 *filename_ptr
= filename
;
7151 if (functionname_ptr
)
7152 *functionname_ptr
= bfd_asymbol_name (func
);
7158 /* Find the nearest line to a particular section and offset, for error
7159 reporting. This code is a duplicate of the code in elf.c, except
7160 that it uses aarch64_elf_find_function. */
7163 elfNN_aarch64_find_nearest_line (bfd
*abfd
,
7167 const char **filename_ptr
,
7168 const char **functionname_ptr
,
7169 unsigned int *line_ptr
,
7170 unsigned int *discriminator_ptr
)
7172 bfd_boolean found
= FALSE
;
7174 if (_bfd_dwarf2_find_nearest_line (abfd
, symbols
, NULL
, section
, offset
,
7175 filename_ptr
, functionname_ptr
,
7176 line_ptr
, discriminator_ptr
,
7177 dwarf_debug_sections
, 0,
7178 &elf_tdata (abfd
)->dwarf2_find_line_info
))
7180 if (!*functionname_ptr
)
7181 aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
7182 *filename_ptr
? NULL
: filename_ptr
,
7188 /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
7189 toolchain uses DWARF1. */
7191 if (!_bfd_stab_section_find_nearest_line (abfd
, symbols
, section
, offset
,
7192 &found
, filename_ptr
,
7193 functionname_ptr
, line_ptr
,
7194 &elf_tdata (abfd
)->line_info
))
7197 if (found
&& (*functionname_ptr
|| *line_ptr
))
7200 if (symbols
== NULL
)
7203 if (!aarch64_elf_find_function (abfd
, symbols
, section
, offset
,
7204 filename_ptr
, functionname_ptr
))
7212 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
7213 const char **filename_ptr
,
7214 const char **functionname_ptr
,
7215 unsigned int *line_ptr
)
7218 found
= _bfd_dwarf2_find_inliner_info
7219 (abfd
, filename_ptr
,
7220 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
7226 elfNN_aarch64_post_process_headers (bfd
*abfd
,
7227 struct bfd_link_info
*link_info
)
7229 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
7231 i_ehdrp
= elf_elfheader (abfd
);
7232 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
7234 _bfd_elf_post_process_headers (abfd
, link_info
);
7237 static enum elf_reloc_type_class
7238 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
7239 const asection
*rel_sec ATTRIBUTE_UNUSED
,
7240 const Elf_Internal_Rela
*rela
)
7242 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
7244 case AARCH64_R (RELATIVE
):
7245 return reloc_class_relative
;
7246 case AARCH64_R (JUMP_SLOT
):
7247 return reloc_class_plt
;
7248 case AARCH64_R (COPY
):
7249 return reloc_class_copy
;
7251 return reloc_class_normal
;
7255 /* Handle an AArch64 specific section when reading an object file. This is
7256 called when bfd_section_from_shdr finds a section with an unknown
7260 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
7261 Elf_Internal_Shdr
*hdr
,
7262 const char *name
, int shindex
)
7264 /* There ought to be a place to keep ELF backend specific flags, but
7265 at the moment there isn't one. We just keep track of the
7266 sections by their name, instead. Fortunately, the ABI gives
7267 names for all the AArch64 specific sections, so we will probably get
7269 switch (hdr
->sh_type
)
7271 case SHT_AARCH64_ATTRIBUTES
:
7278 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
7284 /* A structure used to record a list of sections, independently
7285 of the next and prev fields in the asection structure. */
7286 typedef struct section_list
7289 struct section_list
*next
;
7290 struct section_list
*prev
;
7294 /* Unfortunately we need to keep a list of sections for which
7295 an _aarch64_elf_section_data structure has been allocated. This
7296 is because it is possible for functions like elfNN_aarch64_write_section
7297 to be called on a section which has had an elf_data_structure
7298 allocated for it (and so the used_by_bfd field is valid) but
7299 for which the AArch64 extended version of this structure - the
7300 _aarch64_elf_section_data structure - has not been allocated. */
7301 static section_list
*sections_with_aarch64_elf_section_data
= NULL
;
7304 record_section_with_aarch64_elf_section_data (asection
*sec
)
7306 struct section_list
*entry
;
7308 entry
= bfd_malloc (sizeof (*entry
));
7312 entry
->next
= sections_with_aarch64_elf_section_data
;
7314 if (entry
->next
!= NULL
)
7315 entry
->next
->prev
= entry
;
7316 sections_with_aarch64_elf_section_data
= entry
;
7319 static struct section_list
*
7320 find_aarch64_elf_section_entry (asection
*sec
)
7322 struct section_list
*entry
;
7323 static struct section_list
*last_entry
= NULL
;
7325 /* This is a short cut for the typical case where the sections are added
7326 to the sections_with_aarch64_elf_section_data list in forward order and
7327 then looked up here in backwards order. This makes a real difference
7328 to the ld-srec/sec64k.exp linker test. */
7329 entry
= sections_with_aarch64_elf_section_data
;
7330 if (last_entry
!= NULL
)
7332 if (last_entry
->sec
== sec
)
7334 else if (last_entry
->next
!= NULL
&& last_entry
->next
->sec
== sec
)
7335 entry
= last_entry
->next
;
7338 for (; entry
; entry
= entry
->next
)
7339 if (entry
->sec
== sec
)
7343 /* Record the entry prior to this one - it is the entry we are
7344 most likely to want to locate next time. Also this way if we
7345 have been called from
7346 unrecord_section_with_aarch64_elf_section_data () we will not
7347 be caching a pointer that is about to be freed. */
7348 last_entry
= entry
->prev
;
7354 unrecord_section_with_aarch64_elf_section_data (asection
*sec
)
7356 struct section_list
*entry
;
7358 entry
= find_aarch64_elf_section_entry (sec
);
7362 if (entry
->prev
!= NULL
)
7363 entry
->prev
->next
= entry
->next
;
7364 if (entry
->next
!= NULL
)
7365 entry
->next
->prev
= entry
->prev
;
7366 if (entry
== sections_with_aarch64_elf_section_data
)
7367 sections_with_aarch64_elf_section_data
= entry
->next
;
7376 struct bfd_link_info
*info
;
7379 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
7380 asection
*, struct elf_link_hash_entry
*);
7381 } output_arch_syminfo
;
7383 enum map_symbol_type
7390 /* Output a single mapping symbol. */
7393 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
7394 enum map_symbol_type type
, bfd_vma offset
)
7396 static const char *names
[2] = { "$x", "$d" };
7397 Elf_Internal_Sym sym
;
7399 sym
.st_value
= (osi
->sec
->output_section
->vma
7400 + osi
->sec
->output_offset
+ offset
);
7403 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
7404 sym
.st_shndx
= osi
->sec_shndx
;
7405 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
7408 /* Output a single local symbol for a generated stub. */
7411 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
7412 bfd_vma offset
, bfd_vma size
)
7414 Elf_Internal_Sym sym
;
7416 sym
.st_value
= (osi
->sec
->output_section
->vma
7417 + osi
->sec
->output_offset
+ offset
);
7420 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
7421 sym
.st_shndx
= osi
->sec_shndx
;
7422 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
7426 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
7428 struct elf_aarch64_stub_hash_entry
*stub_entry
;
7432 output_arch_syminfo
*osi
;
7434 /* Massage our args to the form they really have. */
7435 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
7436 osi
= (output_arch_syminfo
*) in_arg
;
7438 stub_sec
= stub_entry
->stub_sec
;
7440 /* Ensure this stub is attached to the current section being
7442 if (stub_sec
!= osi
->sec
)
7445 addr
= (bfd_vma
) stub_entry
->stub_offset
;
7447 stub_name
= stub_entry
->output_name
;
7449 switch (stub_entry
->stub_type
)
7451 case aarch64_stub_adrp_branch
:
7452 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7453 sizeof (aarch64_adrp_branch_stub
)))
7455 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7458 case aarch64_stub_long_branch
:
7459 if (!elfNN_aarch64_output_stub_sym
7460 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
7462 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7464 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
7467 case aarch64_stub_erratum_835769_veneer
:
7468 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7469 sizeof (aarch64_erratum_835769_stub
)))
7471 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7474 case aarch64_stub_erratum_843419_veneer
:
7475 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
7476 sizeof (aarch64_erratum_843419_stub
)))
7478 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
7489 /* Output mapping symbols for linker generated sections. */
7492 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
7493 struct bfd_link_info
*info
,
7495 int (*func
) (void *, const char *,
7498 struct elf_link_hash_entry
7501 output_arch_syminfo osi
;
7502 struct elf_aarch64_link_hash_table
*htab
;
7504 htab
= elf_aarch64_hash_table (info
);
7510 /* Long calls stubs. */
7511 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
7515 for (stub_sec
= htab
->stub_bfd
->sections
;
7516 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
7518 /* Ignore non-stub sections. */
7519 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
7524 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
7525 (output_bfd
, osi
.sec
->output_section
);
7527 /* The first instruction in a stub is always a branch. */
7528 if (!elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0))
7531 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
7536 /* Finally, output mapping symbols for the PLT. */
7537 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
7540 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
7541 (output_bfd
, htab
->root
.splt
->output_section
);
7542 osi
.sec
= htab
->root
.splt
;
7544 elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0);
7550 /* Allocate target specific section data. */
7553 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
7555 if (!sec
->used_by_bfd
)
7557 _aarch64_elf_section_data
*sdata
;
7558 bfd_size_type amt
= sizeof (*sdata
);
7560 sdata
= bfd_zalloc (abfd
, amt
);
7563 sec
->used_by_bfd
= sdata
;
7566 record_section_with_aarch64_elf_section_data (sec
);
7568 return _bfd_elf_new_section_hook (abfd
, sec
);
7573 unrecord_section_via_map_over_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
7575 void *ignore ATTRIBUTE_UNUSED
)
7577 unrecord_section_with_aarch64_elf_section_data (sec
);
7581 elfNN_aarch64_close_and_cleanup (bfd
*abfd
)
7584 bfd_map_over_sections (abfd
,
7585 unrecord_section_via_map_over_sections
, NULL
);
7587 return _bfd_elf_close_and_cleanup (abfd
);
7591 elfNN_aarch64_bfd_free_cached_info (bfd
*abfd
)
7594 bfd_map_over_sections (abfd
,
7595 unrecord_section_via_map_over_sections
, NULL
);
7597 return _bfd_free_cached_info (abfd
);
7600 /* Create dynamic sections. This is different from the ARM backend in that
7601 the got, plt, gotplt and their relocation sections are all created in the
7602 standard part of the bfd elf backend. */
7605 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
7606 struct bfd_link_info
*info
)
7608 struct elf_aarch64_link_hash_table
*htab
;
7610 /* We need to create .got section. */
7611 if (!aarch64_elf_create_got_section (dynobj
, info
))
7614 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
7617 htab
= elf_aarch64_hash_table (info
);
7618 htab
->sdynbss
= bfd_get_linker_section (dynobj
, ".dynbss");
7619 if (!bfd_link_pic (info
))
7620 htab
->srelbss
= bfd_get_linker_section (dynobj
, ".rela.bss");
7622 if (!htab
->sdynbss
|| (!bfd_link_pic (info
) && !htab
->srelbss
))
7629 /* Allocate space in .plt, .got and associated reloc sections for
7633 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
7635 struct bfd_link_info
*info
;
7636 struct elf_aarch64_link_hash_table
*htab
;
7637 struct elf_aarch64_link_hash_entry
*eh
;
7638 struct elf_dyn_relocs
*p
;
7640 /* An example of a bfd_link_hash_indirect symbol is versioned
7641 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7642 -> __gxx_personality_v0(bfd_link_hash_defined)
7644 There is no need to process bfd_link_hash_indirect symbols here
7645 because we will also be presented with the concrete instance of
7646 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7647 called to copy all relevant data from the generic to the concrete
7650 if (h
->root
.type
== bfd_link_hash_indirect
)
7653 if (h
->root
.type
== bfd_link_hash_warning
)
7654 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7656 info
= (struct bfd_link_info
*) inf
;
7657 htab
= elf_aarch64_hash_table (info
);
7659 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7660 here if it is defined and referenced in a non-shared object. */
7661 if (h
->type
== STT_GNU_IFUNC
7664 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
7666 /* Make sure this symbol is output as a dynamic symbol.
7667 Undefined weak syms won't yet be marked as dynamic. */
7668 if (h
->dynindx
== -1 && !h
->forced_local
)
7670 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
7674 if (bfd_link_pic (info
) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
7676 asection
*s
= htab
->root
.splt
;
7678 /* If this is the first .plt entry, make room for the special
7681 s
->size
+= htab
->plt_header_size
;
7683 h
->plt
.offset
= s
->size
;
7685 /* If this symbol is not defined in a regular file, and we are
7686 not generating a shared library, then set the symbol to this
7687 location in the .plt. This is required to make function
7688 pointers compare as equal between the normal executable and
7689 the shared library. */
7690 if (!bfd_link_pic (info
) && !h
->def_regular
)
7692 h
->root
.u
.def
.section
= s
;
7693 h
->root
.u
.def
.value
= h
->plt
.offset
;
7696 /* Make room for this entry. For now we only create the
7697 small model PLT entries. We later need to find a way
7698 of relaxing into these from the large model PLT entries. */
7699 s
->size
+= PLT_SMALL_ENTRY_SIZE
;
7701 /* We also need to make an entry in the .got.plt section, which
7702 will be placed in the .got section by the linker script. */
7703 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
;
7705 /* We also need to make an entry in the .rela.plt section. */
7706 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7708 /* We need to ensure that all GOT entries that serve the PLT
7709 are consecutive with the special GOT slots [0] [1] and
7710 [2]. Any addtional relocations, such as
7711 R_AARCH64_TLSDESC, must be placed after the PLT related
7712 entries. We abuse the reloc_count such that during
7713 sizing we adjust reloc_count to indicate the number of
7714 PLT related reserved entries. In subsequent phases when
7715 filling in the contents of the reloc entries, PLT related
7716 entries are placed by computing their PLT index (0
7717 .. reloc_count). While other none PLT relocs are placed
7718 at the slot indicated by reloc_count and reloc_count is
7721 htab
->root
.srelplt
->reloc_count
++;
7725 h
->plt
.offset
= (bfd_vma
) - 1;
7731 h
->plt
.offset
= (bfd_vma
) - 1;
7735 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7736 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
7738 if (h
->got
.refcount
> 0)
7741 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
7743 h
->got
.offset
= (bfd_vma
) - 1;
7745 dyn
= htab
->root
.dynamic_sections_created
;
7747 /* Make sure this symbol is output as a dynamic symbol.
7748 Undefined weak syms won't yet be marked as dynamic. */
7749 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
)
7751 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
7755 if (got_type
== GOT_UNKNOWN
)
7758 else if (got_type
== GOT_NORMAL
)
7760 h
->got
.offset
= htab
->root
.sgot
->size
;
7761 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7762 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7763 || h
->root
.type
!= bfd_link_hash_undefweak
)
7764 && (bfd_link_pic (info
)
7765 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
7767 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7773 if (got_type
& GOT_TLSDESC_GD
)
7775 eh
->tlsdesc_got_jump_table_offset
=
7776 (htab
->root
.sgotplt
->size
7777 - aarch64_compute_jump_table_size (htab
));
7778 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
7779 h
->got
.offset
= (bfd_vma
) - 2;
7782 if (got_type
& GOT_TLS_GD
)
7784 h
->got
.offset
= htab
->root
.sgot
->size
;
7785 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
7788 if (got_type
& GOT_TLS_IE
)
7790 h
->got
.offset
= htab
->root
.sgot
->size
;
7791 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
7794 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
7795 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7796 || h
->root
.type
!= bfd_link_hash_undefweak
)
7797 && (bfd_link_pic (info
)
7799 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
7801 if (got_type
& GOT_TLSDESC_GD
)
7803 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
7804 /* Note reloc_count not incremented here! We have
7805 already adjusted reloc_count for this relocation
7808 /* TLSDESC PLT is now needed, but not yet determined. */
7809 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
7812 if (got_type
& GOT_TLS_GD
)
7813 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
7815 if (got_type
& GOT_TLS_IE
)
7816 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
7822 h
->got
.offset
= (bfd_vma
) - 1;
7825 if (eh
->dyn_relocs
== NULL
)
7828 /* In the shared -Bsymbolic case, discard space allocated for
7829 dynamic pc-relative relocs against symbols which turn out to be
7830 defined in regular objects. For the normal shared case, discard
7831 space for pc-relative relocs that have become local due to symbol
7832 visibility changes. */
7834 if (bfd_link_pic (info
))
7836 /* Relocs that use pc_count are those that appear on a call
7837 insn, or certain REL relocs that can generated via assembly.
7838 We want calls to protected symbols to resolve directly to the
7839 function rather than going via the plt. If people want
7840 function pointer comparisons to work as expected then they
7841 should avoid writing weird assembly. */
7842 if (SYMBOL_CALLS_LOCAL (info
, h
))
7844 struct elf_dyn_relocs
**pp
;
7846 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
;)
7848 p
->count
-= p
->pc_count
;
7857 /* Also discard relocs on undefined weak syms with non-default
7859 if (eh
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
7861 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
7862 eh
->dyn_relocs
= NULL
;
7864 /* Make sure undefined weak symbols are output as a dynamic
7866 else if (h
->dynindx
== -1
7868 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
7873 else if (ELIMINATE_COPY_RELOCS
)
7875 /* For the non-shared case, discard space for relocs against
7876 symbols which turn out to need copy relocs or are not
7882 || (htab
->root
.dynamic_sections_created
7883 && (h
->root
.type
== bfd_link_hash_undefweak
7884 || h
->root
.type
== bfd_link_hash_undefined
))))
7886 /* Make sure this symbol is output as a dynamic symbol.
7887 Undefined weak syms won't yet be marked as dynamic. */
7888 if (h
->dynindx
== -1
7890 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
7893 /* If that succeeded, we know we'll be keeping all the
7895 if (h
->dynindx
!= -1)
7899 eh
->dyn_relocs
= NULL
;
7904 /* Finally, allocate space. */
7905 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
7909 sreloc
= elf_section_data (p
->sec
)->sreloc
;
7911 BFD_ASSERT (sreloc
!= NULL
);
7913 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
7919 /* Allocate space in .plt, .got and associated reloc sections for
7920 ifunc dynamic relocs. */
7923 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
7926 struct bfd_link_info
*info
;
7927 struct elf_aarch64_link_hash_table
*htab
;
7928 struct elf_aarch64_link_hash_entry
*eh
;
7930 /* An example of a bfd_link_hash_indirect symbol is versioned
7931 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
7932 -> __gxx_personality_v0(bfd_link_hash_defined)
7934 There is no need to process bfd_link_hash_indirect symbols here
7935 because we will also be presented with the concrete instance of
7936 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
7937 called to copy all relevant data from the generic to the concrete
7940 if (h
->root
.type
== bfd_link_hash_indirect
)
7943 if (h
->root
.type
== bfd_link_hash_warning
)
7944 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7946 info
= (struct bfd_link_info
*) inf
;
7947 htab
= elf_aarch64_hash_table (info
);
7949 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7951 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
7952 here if it is defined and referenced in a non-shared object. */
7953 if (h
->type
== STT_GNU_IFUNC
7955 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
7957 htab
->plt_entry_size
,
7958 htab
->plt_header_size
,
7963 /* Allocate space in .plt, .got and associated reloc sections for
7964 local dynamic relocs. */
7967 elfNN_aarch64_allocate_local_dynrelocs (void **slot
, void *inf
)
7969 struct elf_link_hash_entry
*h
7970 = (struct elf_link_hash_entry
*) *slot
;
7972 if (h
->type
!= STT_GNU_IFUNC
7976 || h
->root
.type
!= bfd_link_hash_defined
)
7979 return elfNN_aarch64_allocate_dynrelocs (h
, inf
);
7982 /* Allocate space in .plt, .got and associated reloc sections for
7983 local ifunc dynamic relocs. */
7986 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
7988 struct elf_link_hash_entry
*h
7989 = (struct elf_link_hash_entry
*) *slot
;
7991 if (h
->type
!= STT_GNU_IFUNC
7995 || h
->root
.type
!= bfd_link_hash_defined
)
7998 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
8001 /* Find any dynamic relocs that apply to read-only sections. */
8004 aarch64_readonly_dynrelocs (struct elf_link_hash_entry
* h
, void * inf
)
8006 struct elf_aarch64_link_hash_entry
* eh
;
8007 struct elf_dyn_relocs
* p
;
8009 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
8010 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
8012 asection
*s
= p
->sec
;
8014 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
8016 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
8018 info
->flags
|= DF_TEXTREL
;
8020 /* Not an error, just cut short the traversal. */
8027 /* This is the most important function of all . Innocuosly named
8030 elfNN_aarch64_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
8031 struct bfd_link_info
*info
)
8033 struct elf_aarch64_link_hash_table
*htab
;
8039 htab
= elf_aarch64_hash_table ((info
));
8040 dynobj
= htab
->root
.dynobj
;
8042 BFD_ASSERT (dynobj
!= NULL
);
8044 if (htab
->root
.dynamic_sections_created
)
8046 if (bfd_link_executable (info
) && !info
->nointerp
)
8048 s
= bfd_get_linker_section (dynobj
, ".interp");
8051 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
8052 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
8056 /* Set up .got offsets for local syms, and space for local dynamic
8058 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
8060 struct elf_aarch64_local_symbol
*locals
= NULL
;
8061 Elf_Internal_Shdr
*symtab_hdr
;
8065 if (!is_aarch64_elf (ibfd
))
8068 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
8070 struct elf_dyn_relocs
*p
;
8072 for (p
= (struct elf_dyn_relocs
*)
8073 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
8075 if (!bfd_is_abs_section (p
->sec
)
8076 && bfd_is_abs_section (p
->sec
->output_section
))
8078 /* Input section has been discarded, either because
8079 it is a copy of a linkonce section or due to
8080 linker script /DISCARD/, so we'll be discarding
8083 else if (p
->count
!= 0)
8085 srel
= elf_section_data (p
->sec
)->sreloc
;
8086 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
8087 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
8088 info
->flags
|= DF_TEXTREL
;
8093 locals
= elf_aarch64_locals (ibfd
);
8097 symtab_hdr
= &elf_symtab_hdr (ibfd
);
8098 srel
= htab
->root
.srelgot
;
8099 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
8101 locals
[i
].got_offset
= (bfd_vma
) - 1;
8102 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
8103 if (locals
[i
].got_refcount
> 0)
8105 unsigned got_type
= locals
[i
].got_type
;
8106 if (got_type
& GOT_TLSDESC_GD
)
8108 locals
[i
].tlsdesc_got_jump_table_offset
=
8109 (htab
->root
.sgotplt
->size
8110 - aarch64_compute_jump_table_size (htab
));
8111 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
8112 locals
[i
].got_offset
= (bfd_vma
) - 2;
8115 if (got_type
& GOT_TLS_GD
)
8117 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
8118 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
8121 if (got_type
& GOT_TLS_IE
8122 || got_type
& GOT_NORMAL
)
8124 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
8125 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
8128 if (got_type
== GOT_UNKNOWN
)
8132 if (bfd_link_pic (info
))
8134 if (got_type
& GOT_TLSDESC_GD
)
8136 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
8137 /* Note RELOC_COUNT not incremented here! */
8138 htab
->tlsdesc_plt
= (bfd_vma
) - 1;
8141 if (got_type
& GOT_TLS_GD
)
8142 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
8144 if (got_type
& GOT_TLS_IE
8145 || got_type
& GOT_NORMAL
)
8146 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
8151 locals
[i
].got_refcount
= (bfd_vma
) - 1;
8157 /* Allocate global sym .plt and .got entries, and space for global
8158 sym dynamic relocs. */
8159 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
8162 /* Allocate global ifunc sym .plt and .got entries, and space for global
8163 ifunc sym dynamic relocs. */
8164 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
8167 /* Allocate .plt and .got entries, and space for local symbols. */
8168 htab_traverse (htab
->loc_hash_table
,
8169 elfNN_aarch64_allocate_local_dynrelocs
,
8172 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
8173 htab_traverse (htab
->loc_hash_table
,
8174 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
8177 /* For every jump slot reserved in the sgotplt, reloc_count is
8178 incremented. However, when we reserve space for TLS descriptors,
8179 it's not incremented, so in order to compute the space reserved
8180 for them, it suffices to multiply the reloc count by the jump
8183 if (htab
->root
.srelplt
)
8184 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
8186 if (htab
->tlsdesc_plt
)
8188 if (htab
->root
.splt
->size
== 0)
8189 htab
->root
.splt
->size
+= PLT_ENTRY_SIZE
;
8191 htab
->tlsdesc_plt
= htab
->root
.splt
->size
;
8192 htab
->root
.splt
->size
+= PLT_TLSDESC_ENTRY_SIZE
;
8194 /* If we're not using lazy TLS relocations, don't generate the
8195 GOT entry required. */
8196 if (!(info
->flags
& DF_BIND_NOW
))
8198 htab
->dt_tlsdesc_got
= htab
->root
.sgot
->size
;
8199 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
8203 /* Init mapping symbols information to use later to distingush between
8204 code and data while scanning for errata. */
8205 if (htab
->fix_erratum_835769
|| htab
->fix_erratum_843419
)
8206 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
8208 if (!is_aarch64_elf (ibfd
))
8210 bfd_elfNN_aarch64_init_maps (ibfd
);
8213 /* We now have determined the sizes of the various dynamic sections.
8214 Allocate memory for them. */
8216 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
8218 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
8221 if (s
== htab
->root
.splt
8222 || s
== htab
->root
.sgot
8223 || s
== htab
->root
.sgotplt
8224 || s
== htab
->root
.iplt
8225 || s
== htab
->root
.igotplt
|| s
== htab
->sdynbss
)
8227 /* Strip this section if we don't need it; see the
8230 else if (CONST_STRNEQ (bfd_get_section_name (dynobj
, s
), ".rela"))
8232 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
8235 /* We use the reloc_count field as a counter if we need
8236 to copy relocs into the output file. */
8237 if (s
!= htab
->root
.srelplt
)
8242 /* It's not one of our sections, so don't allocate space. */
8248 /* If we don't need this section, strip it from the
8249 output file. This is mostly to handle .rela.bss and
8250 .rela.plt. We must create both sections in
8251 create_dynamic_sections, because they must be created
8252 before the linker maps input sections to output
8253 sections. The linker does that before
8254 adjust_dynamic_symbol is called, and it is that
8255 function which decides whether anything needs to go
8256 into these sections. */
8258 s
->flags
|= SEC_EXCLUDE
;
8262 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
8265 /* Allocate memory for the section contents. We use bfd_zalloc
8266 here in case unused entries are not reclaimed before the
8267 section's contents are written out. This should not happen,
8268 but this way if it does, we get a R_AARCH64_NONE reloc instead
8270 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
8271 if (s
->contents
== NULL
)
8275 if (htab
->root
.dynamic_sections_created
)
8277 /* Add some entries to the .dynamic section. We fill in the
8278 values later, in elfNN_aarch64_finish_dynamic_sections, but we
8279 must add the entries now so that we get the correct size for
8280 the .dynamic section. The DT_DEBUG entry is filled in by the
8281 dynamic linker and used by the debugger. */
8282 #define add_dynamic_entry(TAG, VAL) \
8283 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
8285 if (bfd_link_executable (info
))
8287 if (!add_dynamic_entry (DT_DEBUG
, 0))
8291 if (htab
->root
.splt
->size
!= 0)
8293 if (!add_dynamic_entry (DT_PLTGOT
, 0)
8294 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
8295 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
8296 || !add_dynamic_entry (DT_JMPREL
, 0))
8299 if (htab
->tlsdesc_plt
8300 && (!add_dynamic_entry (DT_TLSDESC_PLT
, 0)
8301 || !add_dynamic_entry (DT_TLSDESC_GOT
, 0)))
8307 if (!add_dynamic_entry (DT_RELA
, 0)
8308 || !add_dynamic_entry (DT_RELASZ
, 0)
8309 || !add_dynamic_entry (DT_RELAENT
, RELOC_SIZE (htab
)))
8312 /* If any dynamic relocs apply to a read-only section,
8313 then we need a DT_TEXTREL entry. */
8314 if ((info
->flags
& DF_TEXTREL
) == 0)
8315 elf_link_hash_traverse (& htab
->root
, aarch64_readonly_dynrelocs
,
8318 if ((info
->flags
& DF_TEXTREL
) != 0)
8320 if (!add_dynamic_entry (DT_TEXTREL
, 0))
8325 #undef add_dynamic_entry
8331 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
8332 bfd_reloc_code_real_type r_type
,
8333 bfd_byte
*plt_entry
, bfd_vma value
)
8335 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
8337 _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
8341 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
8342 struct elf_aarch64_link_hash_table
8343 *htab
, bfd
*output_bfd
,
8344 struct bfd_link_info
*info
)
8346 bfd_byte
*plt_entry
;
8349 bfd_vma gotplt_entry_address
;
8350 bfd_vma plt_entry_address
;
8351 Elf_Internal_Rela rela
;
8353 asection
*plt
, *gotplt
, *relplt
;
8355 /* When building a static executable, use .iplt, .igot.plt and
8356 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8357 if (htab
->root
.splt
!= NULL
)
8359 plt
= htab
->root
.splt
;
8360 gotplt
= htab
->root
.sgotplt
;
8361 relplt
= htab
->root
.srelplt
;
8365 plt
= htab
->root
.iplt
;
8366 gotplt
= htab
->root
.igotplt
;
8367 relplt
= htab
->root
.irelplt
;
8370 /* Get the index in the procedure linkage table which
8371 corresponds to this symbol. This is the index of this symbol
8372 in all the symbols for which we are making plt entries. The
8373 first entry in the procedure linkage table is reserved.
8375 Get the offset into the .got table of the entry that
8376 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
8377 bytes. The first three are reserved for the dynamic linker.
8379 For static executables, we don't reserve anything. */
8381 if (plt
== htab
->root
.splt
)
8383 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
8384 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
8388 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
8389 got_offset
= plt_index
* GOT_ENTRY_SIZE
;
8392 plt_entry
= plt
->contents
+ h
->plt
.offset
;
8393 plt_entry_address
= plt
->output_section
->vma
8394 + plt
->output_offset
+ h
->plt
.offset
;
8395 gotplt_entry_address
= gotplt
->output_section
->vma
+
8396 gotplt
->output_offset
+ got_offset
;
8398 /* Copy in the boiler-plate for the PLTn entry. */
8399 memcpy (plt_entry
, elfNN_aarch64_small_plt_entry
, PLT_SMALL_ENTRY_SIZE
);
8401 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8402 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8403 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8405 PG (gotplt_entry_address
) -
8406 PG (plt_entry_address
));
8408 /* Fill in the lo12 bits for the load from the pltgot. */
8409 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
8411 PG_OFFSET (gotplt_entry_address
));
8413 /* Fill in the lo12 bits for the add from the pltgot entry. */
8414 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
8416 PG_OFFSET (gotplt_entry_address
));
8418 /* All the GOTPLT Entries are essentially initialized to PLT0. */
8419 bfd_put_NN (output_bfd
,
8420 plt
->output_section
->vma
+ plt
->output_offset
,
8421 gotplt
->contents
+ got_offset
);
8423 rela
.r_offset
= gotplt_entry_address
;
8425 if (h
->dynindx
== -1
8426 || ((bfd_link_executable (info
)
8427 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
8429 && h
->type
== STT_GNU_IFUNC
))
8431 /* If an STT_GNU_IFUNC symbol is locally defined, generate
8432 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
8433 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
8434 rela
.r_addend
= (h
->root
.u
.def
.value
8435 + h
->root
.u
.def
.section
->output_section
->vma
8436 + h
->root
.u
.def
.section
->output_offset
);
8440 /* Fill in the entry in the .rela.plt section. */
8441 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
));
8445 /* Compute the relocation entry to used based on PLT index and do
8446 not adjust reloc_count. The reloc_count has already been adjusted
8447 to account for this entry. */
8448 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
8449 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8452 /* Size sections even though they're not dynamic. We use it to setup
8453 _TLS_MODULE_BASE_, if needed. */
8456 elfNN_aarch64_always_size_sections (bfd
*output_bfd
,
8457 struct bfd_link_info
*info
)
8461 if (bfd_link_relocatable (info
))
8464 tls_sec
= elf_hash_table (info
)->tls_sec
;
8468 struct elf_link_hash_entry
*tlsbase
;
8470 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
8471 "_TLS_MODULE_BASE_", TRUE
, TRUE
, FALSE
);
8475 struct bfd_link_hash_entry
*h
= NULL
;
8476 const struct elf_backend_data
*bed
=
8477 get_elf_backend_data (output_bfd
);
8479 if (!(_bfd_generic_link_add_one_symbol
8480 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
8481 tls_sec
, 0, NULL
, FALSE
, bed
->collect
, &h
)))
8484 tlsbase
->type
= STT_TLS
;
8485 tlsbase
= (struct elf_link_hash_entry
*) h
;
8486 tlsbase
->def_regular
= 1;
8487 tlsbase
->other
= STV_HIDDEN
;
8488 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, TRUE
);
8495 /* Finish up dynamic symbol handling. We set the contents of various
8496 dynamic sections here. */
8498 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
8499 struct bfd_link_info
*info
,
8500 struct elf_link_hash_entry
*h
,
8501 Elf_Internal_Sym
*sym
)
8503 struct elf_aarch64_link_hash_table
*htab
;
8504 htab
= elf_aarch64_hash_table (info
);
8506 if (h
->plt
.offset
!= (bfd_vma
) - 1)
8508 asection
*plt
, *gotplt
, *relplt
;
8510 /* This symbol has an entry in the procedure linkage table. Set
8513 /* When building a static executable, use .iplt, .igot.plt and
8514 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8515 if (htab
->root
.splt
!= NULL
)
8517 plt
= htab
->root
.splt
;
8518 gotplt
= htab
->root
.sgotplt
;
8519 relplt
= htab
->root
.srelplt
;
8523 plt
= htab
->root
.iplt
;
8524 gotplt
= htab
->root
.igotplt
;
8525 relplt
= htab
->root
.irelplt
;
8528 /* This symbol has an entry in the procedure linkage table. Set
8530 if ((h
->dynindx
== -1
8531 && !((h
->forced_local
|| bfd_link_executable (info
))
8533 && h
->type
== STT_GNU_IFUNC
))
8539 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
8540 if (!h
->def_regular
)
8542 /* Mark the symbol as undefined, rather than as defined in
8543 the .plt section. */
8544 sym
->st_shndx
= SHN_UNDEF
;
8545 /* If the symbol is weak we need to clear the value.
8546 Otherwise, the PLT entry would provide a definition for
8547 the symbol even if the symbol wasn't defined anywhere,
8548 and so the symbol would never be NULL. Leave the value if
8549 there were any relocations where pointer equality matters
8550 (this is a clue for the dynamic linker, to make function
8551 pointer comparisons work between an application and shared
8553 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
8558 if (h
->got
.offset
!= (bfd_vma
) - 1
8559 && elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
)
8561 Elf_Internal_Rela rela
;
8564 /* This symbol has an entry in the global offset table. Set it
8566 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
8569 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
8570 + htab
->root
.sgot
->output_offset
8571 + (h
->got
.offset
& ~(bfd_vma
) 1));
8574 && h
->type
== STT_GNU_IFUNC
)
8576 if (bfd_link_pic (info
))
8578 /* Generate R_AARCH64_GLOB_DAT. */
8585 if (!h
->pointer_equality_needed
)
8588 /* For non-shared object, we can't use .got.plt, which
8589 contains the real function address if we need pointer
8590 equality. We load the GOT entry with the PLT entry. */
8591 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
8592 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
8593 + plt
->output_offset
8595 htab
->root
.sgot
->contents
8596 + (h
->got
.offset
& ~(bfd_vma
) 1));
8600 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
8602 if (!h
->def_regular
)
8605 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
8606 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
8607 rela
.r_addend
= (h
->root
.u
.def
.value
8608 + h
->root
.u
.def
.section
->output_section
->vma
8609 + h
->root
.u
.def
.section
->output_offset
);
8614 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
8615 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8616 htab
->root
.sgot
->contents
+ h
->got
.offset
);
8617 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (GLOB_DAT
));
8621 loc
= htab
->root
.srelgot
->contents
;
8622 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
8623 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8628 Elf_Internal_Rela rela
;
8631 /* This symbol needs a copy reloc. Set it up. */
8633 if (h
->dynindx
== -1
8634 || (h
->root
.type
!= bfd_link_hash_defined
8635 && h
->root
.type
!= bfd_link_hash_defweak
)
8636 || htab
->srelbss
== NULL
)
8639 rela
.r_offset
= (h
->root
.u
.def
.value
8640 + h
->root
.u
.def
.section
->output_section
->vma
8641 + h
->root
.u
.def
.section
->output_offset
);
8642 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
8644 loc
= htab
->srelbss
->contents
;
8645 loc
+= htab
->srelbss
->reloc_count
++ * RELOC_SIZE (htab
);
8646 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8649 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
8650 be NULL for local symbols. */
8652 && (h
== elf_hash_table (info
)->hdynamic
8653 || h
== elf_hash_table (info
)->hgot
))
8654 sym
->st_shndx
= SHN_ABS
;
8659 /* Finish up local dynamic symbol handling. We set the contents of
8660 various dynamic sections here. */
8663 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
8665 struct elf_link_hash_entry
*h
8666 = (struct elf_link_hash_entry
*) *slot
;
8667 struct bfd_link_info
*info
8668 = (struct bfd_link_info
*) inf
;
8670 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
8675 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
8676 struct elf_aarch64_link_hash_table
8679 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
8680 small and large plts and at the minute just generates
8683 /* PLT0 of the small PLT looks like this in ELF64 -
8684 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
8685 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
8686 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
8688 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
8689 // GOTPLT entry for this.
8691 PLT0 will be slightly different in ELF32 due to different got entry
8694 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
8698 memcpy (htab
->root
.splt
->contents
, elfNN_aarch64_small_plt0_entry
,
8700 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
=
8703 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
8704 + htab
->root
.sgotplt
->output_offset
8705 + GOT_ENTRY_SIZE
* 2);
8707 plt_base
= htab
->root
.splt
->output_section
->vma
+
8708 htab
->root
.splt
->output_offset
;
8710 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8711 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
8712 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8713 htab
->root
.splt
->contents
+ 4,
8714 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
8716 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
8717 htab
->root
.splt
->contents
+ 8,
8718 PG_OFFSET (plt_got_2nd_ent
));
8720 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
8721 htab
->root
.splt
->contents
+ 12,
8722 PG_OFFSET (plt_got_2nd_ent
));
8726 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
8727 struct bfd_link_info
*info
)
8729 struct elf_aarch64_link_hash_table
*htab
;
8733 htab
= elf_aarch64_hash_table (info
);
8734 dynobj
= htab
->root
.dynobj
;
8735 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
8737 if (htab
->root
.dynamic_sections_created
)
8739 ElfNN_External_Dyn
*dyncon
, *dynconend
;
8741 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
8744 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
8745 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
8746 for (; dyncon
< dynconend
; dyncon
++)
8748 Elf_Internal_Dyn dyn
;
8751 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
8759 s
= htab
->root
.sgotplt
;
8760 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
8764 dyn
.d_un
.d_ptr
= htab
->root
.srelplt
->output_section
->vma
;
8768 s
= htab
->root
.srelplt
;
8769 dyn
.d_un
.d_val
= s
->size
;
8773 /* The procedure linkage table relocs (DT_JMPREL) should
8774 not be included in the overall relocs (DT_RELA).
8775 Therefore, we override the DT_RELASZ entry here to
8776 make it not include the JMPREL relocs. Since the
8777 linker script arranges for .rela.plt to follow all
8778 other relocation sections, we don't have to worry
8779 about changing the DT_RELA entry. */
8780 if (htab
->root
.srelplt
!= NULL
)
8782 s
= htab
->root
.srelplt
;
8783 dyn
.d_un
.d_val
-= s
->size
;
8787 case DT_TLSDESC_PLT
:
8788 s
= htab
->root
.splt
;
8789 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
8790 + htab
->tlsdesc_plt
;
8793 case DT_TLSDESC_GOT
:
8794 s
= htab
->root
.sgot
;
8795 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
8796 + htab
->dt_tlsdesc_got
;
8800 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
8805 /* Fill in the special first entry in the procedure linkage table. */
8806 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
8808 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
8810 elf_section_data (htab
->root
.splt
->output_section
)->
8811 this_hdr
.sh_entsize
= htab
->plt_entry_size
;
8814 if (htab
->tlsdesc_plt
)
8816 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8817 htab
->root
.sgot
->contents
+ htab
->dt_tlsdesc_got
);
8819 memcpy (htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
,
8820 elfNN_aarch64_tlsdesc_small_plt_entry
,
8821 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry
));
8824 bfd_vma adrp1_addr
=
8825 htab
->root
.splt
->output_section
->vma
8826 + htab
->root
.splt
->output_offset
+ htab
->tlsdesc_plt
+ 4;
8828 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
8831 htab
->root
.sgot
->output_section
->vma
8832 + htab
->root
.sgot
->output_offset
;
8834 bfd_vma pltgot_addr
=
8835 htab
->root
.sgotplt
->output_section
->vma
8836 + htab
->root
.sgotplt
->output_offset
;
8838 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->dt_tlsdesc_got
;
8840 bfd_byte
*plt_entry
=
8841 htab
->root
.splt
->contents
+ htab
->tlsdesc_plt
;
8843 /* adrp x2, DT_TLSDESC_GOT */
8844 elf_aarch64_update_plt_entry (output_bfd
,
8845 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8847 (PG (dt_tlsdesc_got
)
8848 - PG (adrp1_addr
)));
8851 elf_aarch64_update_plt_entry (output_bfd
,
8852 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
8855 - PG (adrp2_addr
)));
8857 /* ldr x2, [x2, #0] */
8858 elf_aarch64_update_plt_entry (output_bfd
,
8859 BFD_RELOC_AARCH64_LDSTNN_LO12
,
8861 PG_OFFSET (dt_tlsdesc_got
));
8864 elf_aarch64_update_plt_entry (output_bfd
,
8865 BFD_RELOC_AARCH64_ADD_LO12
,
8867 PG_OFFSET (pltgot_addr
));
8872 if (htab
->root
.sgotplt
)
8874 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
8876 (*_bfd_error_handler
)
8877 (_("discarded output section: `%A'"), htab
->root
.sgotplt
);
8881 /* Fill in the first three entries in the global offset table. */
8882 if (htab
->root
.sgotplt
->size
> 0)
8884 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
8886 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
8887 bfd_put_NN (output_bfd
,
8889 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
8890 bfd_put_NN (output_bfd
,
8892 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
* 2);
8895 if (htab
->root
.sgot
)
8897 if (htab
->root
.sgot
->size
> 0)
8900 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
8901 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
8905 elf_section_data (htab
->root
.sgotplt
->output_section
)->
8906 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
8909 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
8910 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
8913 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
8914 htab_traverse (htab
->loc_hash_table
,
8915 elfNN_aarch64_finish_local_dynamic_symbol
,
8921 /* Return address for Ith PLT stub in section PLT, for relocation REL
8922 or (bfd_vma) -1 if it should not be included. */
8925 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
8926 const arelent
*rel ATTRIBUTE_UNUSED
)
8928 return plt
->vma
+ PLT_ENTRY_SIZE
+ i
* PLT_SMALL_ENTRY_SIZE
;
8932 /* We use this so we can override certain functions
8933 (though currently we don't). */
8935 const struct elf_size_info elfNN_aarch64_size_info
=
8937 sizeof (ElfNN_External_Ehdr
),
8938 sizeof (ElfNN_External_Phdr
),
8939 sizeof (ElfNN_External_Shdr
),
8940 sizeof (ElfNN_External_Rel
),
8941 sizeof (ElfNN_External_Rela
),
8942 sizeof (ElfNN_External_Sym
),
8943 sizeof (ElfNN_External_Dyn
),
8944 sizeof (Elf_External_Note
),
8945 4, /* Hash table entry size. */
8946 1, /* Internal relocs per external relocs. */
8947 ARCH_SIZE
, /* Arch size. */
8948 LOG_FILE_ALIGN
, /* Log_file_align. */
8949 ELFCLASSNN
, EV_CURRENT
,
8950 bfd_elfNN_write_out_phdrs
,
8951 bfd_elfNN_write_shdrs_and_ehdr
,
8952 bfd_elfNN_checksum_contents
,
8953 bfd_elfNN_write_relocs
,
8954 bfd_elfNN_swap_symbol_in
,
8955 bfd_elfNN_swap_symbol_out
,
8956 bfd_elfNN_slurp_reloc_table
,
8957 bfd_elfNN_slurp_symbol_table
,
8958 bfd_elfNN_swap_dyn_in
,
8959 bfd_elfNN_swap_dyn_out
,
8960 bfd_elfNN_swap_reloc_in
,
8961 bfd_elfNN_swap_reloc_out
,
8962 bfd_elfNN_swap_reloca_in
,
8963 bfd_elfNN_swap_reloca_out
8966 #define ELF_ARCH bfd_arch_aarch64
8967 #define ELF_MACHINE_CODE EM_AARCH64
8968 #define ELF_MAXPAGESIZE 0x10000
8969 #define ELF_MINPAGESIZE 0x1000
8970 #define ELF_COMMONPAGESIZE 0x1000
8972 #define bfd_elfNN_close_and_cleanup \
8973 elfNN_aarch64_close_and_cleanup
8975 #define bfd_elfNN_bfd_free_cached_info \
8976 elfNN_aarch64_bfd_free_cached_info
8978 #define bfd_elfNN_bfd_is_target_special_symbol \
8979 elfNN_aarch64_is_target_special_symbol
8981 #define bfd_elfNN_bfd_link_hash_table_create \
8982 elfNN_aarch64_link_hash_table_create
8984 #define bfd_elfNN_bfd_merge_private_bfd_data \
8985 elfNN_aarch64_merge_private_bfd_data
8987 #define bfd_elfNN_bfd_print_private_bfd_data \
8988 elfNN_aarch64_print_private_bfd_data
8990 #define bfd_elfNN_bfd_reloc_type_lookup \
8991 elfNN_aarch64_reloc_type_lookup
8993 #define bfd_elfNN_bfd_reloc_name_lookup \
8994 elfNN_aarch64_reloc_name_lookup
8996 #define bfd_elfNN_bfd_set_private_flags \
8997 elfNN_aarch64_set_private_flags
8999 #define bfd_elfNN_find_inliner_info \
9000 elfNN_aarch64_find_inliner_info
9002 #define bfd_elfNN_find_nearest_line \
9003 elfNN_aarch64_find_nearest_line
9005 #define bfd_elfNN_mkobject \
9006 elfNN_aarch64_mkobject
9008 #define bfd_elfNN_new_section_hook \
9009 elfNN_aarch64_new_section_hook
9011 #define elf_backend_adjust_dynamic_symbol \
9012 elfNN_aarch64_adjust_dynamic_symbol
9014 #define elf_backend_always_size_sections \
9015 elfNN_aarch64_always_size_sections
9017 #define elf_backend_check_relocs \
9018 elfNN_aarch64_check_relocs
9020 #define elf_backend_copy_indirect_symbol \
9021 elfNN_aarch64_copy_indirect_symbol
9023 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
9024 to them in our hash. */
9025 #define elf_backend_create_dynamic_sections \
9026 elfNN_aarch64_create_dynamic_sections
9028 #define elf_backend_init_index_section \
9029 _bfd_elf_init_2_index_sections
9031 #define elf_backend_finish_dynamic_sections \
9032 elfNN_aarch64_finish_dynamic_sections
9034 #define elf_backend_finish_dynamic_symbol \
9035 elfNN_aarch64_finish_dynamic_symbol
9037 #define elf_backend_gc_sweep_hook \
9038 elfNN_aarch64_gc_sweep_hook
9040 #define elf_backend_object_p \
9041 elfNN_aarch64_object_p
9043 #define elf_backend_output_arch_local_syms \
9044 elfNN_aarch64_output_arch_local_syms
9046 #define elf_backend_plt_sym_val \
9047 elfNN_aarch64_plt_sym_val
9049 #define elf_backend_post_process_headers \
9050 elfNN_aarch64_post_process_headers
9052 #define elf_backend_relocate_section \
9053 elfNN_aarch64_relocate_section
9055 #define elf_backend_reloc_type_class \
9056 elfNN_aarch64_reloc_type_class
9058 #define elf_backend_section_from_shdr \
9059 elfNN_aarch64_section_from_shdr
9061 #define elf_backend_size_dynamic_sections \
9062 elfNN_aarch64_size_dynamic_sections
9064 #define elf_backend_size_info \
9065 elfNN_aarch64_size_info
9067 #define elf_backend_write_section \
9068 elfNN_aarch64_write_section
9070 #define elf_backend_can_refcount 1
9071 #define elf_backend_can_gc_sections 1
9072 #define elf_backend_plt_readonly 1
9073 #define elf_backend_want_got_plt 1
9074 #define elf_backend_want_plt_sym 0
9075 #define elf_backend_may_use_rel_p 0
9076 #define elf_backend_may_use_rela_p 1
9077 #define elf_backend_default_use_rela_p 1
9078 #define elf_backend_rela_normal 1
9079 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
9080 #define elf_backend_default_execstack 0
9081 #define elf_backend_extern_protected_data 1
9083 #undef elf_backend_obj_attrs_section
9084 #define elf_backend_obj_attrs_section ".ARM.attributes"
9086 #include "elfNN-target.h"