merge from gcc
[gdb/gnu.git] / bfd / elfnn-aarch64.c
blob8f0e71699fdc1626d674f06bc029c53410a8f6ea
1 /* AArch64-specific support for NN-bit ELF.
2 Copyright 2009-2013 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* Notes on implementation:
23 Thread Local Store (TLS)
25 Overview:
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:
33 adrp x0, :tlsgd:foo
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
37 bl __tls_get_addr
38 nop
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)
46 .tlsdesccall 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.
81 Implementation:
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.
93 The flow:
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
113 for this symbol.
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. */
138 #include "sysdep.h"
139 #include "bfd.h"
140 #include "libiberty.h"
141 #include "libbfd.h"
142 #include "bfd_stdint.h"
143 #include "elf-bfd.h"
144 #include "bfdlink.h"
145 #include "objalloc.h"
146 #include "elf/aarch64.h"
147 #include "elfxx-aarch64.h"
149 #define ARCH_SIZE NN
151 #if ARCH_SIZE == 64
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
157 #endif
159 #if ARCH_SIZE == 32
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
165 #endif
167 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
168 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
169 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
170 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
171 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
187 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
189 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
190 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC)
203 #define ELIMINATE_COPY_RELOCS 0
205 /* Return size of a relocation entry. HTAB is the bfd's
206 elf_aarch64_link_hash_entry. */
207 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
209 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
210 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
211 #define PLT_ENTRY_SIZE (32)
212 #define PLT_SMALL_ENTRY_SIZE (16)
213 #define PLT_TLSDESC_ENTRY_SIZE (32)
215 /* Encoding of the nop instruction */
216 #define INSN_NOP 0xd503201f
218 #define aarch64_compute_jump_table_size(htab) \
219 (((htab)->root.srelplt == NULL) ? 0 \
220 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
222 /* The first entry in a procedure linkage table looks like this
223 if the distance between the PLTGOT and the PLT is < 4GB use
224 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
225 in x16 and needs to work out PLTGOT[1] by using an address of
226 [x16,#-GOT_ENTRY_SIZE]. */
227 static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
229 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
230 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
231 #if ARCH_SIZE == 64
232 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
233 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
234 #else
235 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
236 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
237 #endif
238 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
239 0x1f, 0x20, 0x03, 0xd5, /* nop */
240 0x1f, 0x20, 0x03, 0xd5, /* nop */
241 0x1f, 0x20, 0x03, 0xd5, /* nop */
244 /* Per function entry in a procedure linkage table looks like this
245 if the distance between the PLTGOT and the PLT is < 4GB use
246 these PLT entries. */
247 static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
249 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
250 #if ARCH_SIZE == 64
251 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
252 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
253 #else
254 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
255 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
256 #endif
257 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
260 static const bfd_byte
261 elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
263 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
264 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
265 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
266 #if ARCH_SIZE == 64
267 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
268 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
269 #else
270 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
271 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
272 #endif
273 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
274 0x1f, 0x20, 0x03, 0xd5, /* nop */
275 0x1f, 0x20, 0x03, 0xd5, /* nop */
278 #define elf_info_to_howto elfNN_aarch64_info_to_howto
279 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
281 #define AARCH64_ELF_ABI_VERSION 0
283 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
284 #define ALL_ONES (~ (bfd_vma) 0)
286 /* Indexed by the bfd interal reloc enumerators.
287 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
288 in reloc.c. */
290 static reloc_howto_type elfNN_aarch64_howto_table[] =
292 EMPTY_HOWTO (0),
294 /* Basic data relocations. */
296 #if ARCH_SIZE == 64
297 HOWTO (R_AARCH64_NULL, /* type */
298 0, /* rightshift */
299 0, /* size (0 = byte, 1 = short, 2 = long) */
300 0, /* bitsize */
301 FALSE, /* pc_relative */
302 0, /* bitpos */
303 complain_overflow_dont, /* complain_on_overflow */
304 bfd_elf_generic_reloc, /* special_function */
305 "R_AARCH64_NULL", /* name */
306 FALSE, /* partial_inplace */
307 0, /* src_mask */
308 0, /* dst_mask */
309 FALSE), /* pcrel_offset */
310 #else
311 HOWTO (R_AARCH64_NONE, /* type */
312 0, /* rightshift */
313 0, /* size (0 = byte, 1 = short, 2 = long) */
314 0, /* bitsize */
315 FALSE, /* pc_relative */
316 0, /* bitpos */
317 complain_overflow_dont, /* complain_on_overflow */
318 bfd_elf_generic_reloc, /* special_function */
319 "R_AARCH64_NONE", /* name */
320 FALSE, /* partial_inplace */
321 0, /* src_mask */
322 0, /* dst_mask */
323 FALSE), /* pcrel_offset */
324 #endif
326 /* .xword: (S+A) */
327 HOWTO64 (AARCH64_R (ABS64), /* type */
328 0, /* rightshift */
329 4, /* size (4 = long long) */
330 64, /* bitsize */
331 FALSE, /* pc_relative */
332 0, /* bitpos */
333 complain_overflow_unsigned, /* complain_on_overflow */
334 bfd_elf_generic_reloc, /* special_function */
335 AARCH64_R_STR (ABS64), /* name */
336 FALSE, /* partial_inplace */
337 ALL_ONES, /* src_mask */
338 ALL_ONES, /* dst_mask */
339 FALSE), /* pcrel_offset */
341 /* .word: (S+A) */
342 HOWTO (AARCH64_R (ABS32), /* type */
343 0, /* rightshift */
344 2, /* size (0 = byte, 1 = short, 2 = long) */
345 32, /* bitsize */
346 FALSE, /* pc_relative */
347 0, /* bitpos */
348 complain_overflow_unsigned, /* complain_on_overflow */
349 bfd_elf_generic_reloc, /* special_function */
350 AARCH64_R_STR (ABS32), /* name */
351 FALSE, /* partial_inplace */
352 0xffffffff, /* src_mask */
353 0xffffffff, /* dst_mask */
354 FALSE), /* pcrel_offset */
356 /* .half: (S+A) */
357 HOWTO (AARCH64_R (ABS16), /* type */
358 0, /* rightshift */
359 1, /* size (0 = byte, 1 = short, 2 = long) */
360 16, /* bitsize */
361 FALSE, /* pc_relative */
362 0, /* bitpos */
363 complain_overflow_unsigned, /* complain_on_overflow */
364 bfd_elf_generic_reloc, /* special_function */
365 AARCH64_R_STR (ABS16), /* name */
366 FALSE, /* partial_inplace */
367 0xffff, /* src_mask */
368 0xffff, /* dst_mask */
369 FALSE), /* pcrel_offset */
371 /* .xword: (S+A-P) */
372 HOWTO64 (AARCH64_R (PREL64), /* type */
373 0, /* rightshift */
374 4, /* size (4 = long long) */
375 64, /* bitsize */
376 TRUE, /* pc_relative */
377 0, /* bitpos */
378 complain_overflow_signed, /* complain_on_overflow */
379 bfd_elf_generic_reloc, /* special_function */
380 AARCH64_R_STR (PREL64), /* name */
381 FALSE, /* partial_inplace */
382 ALL_ONES, /* src_mask */
383 ALL_ONES, /* dst_mask */
384 TRUE), /* pcrel_offset */
386 /* .word: (S+A-P) */
387 HOWTO (AARCH64_R (PREL32), /* type */
388 0, /* rightshift */
389 2, /* size (0 = byte, 1 = short, 2 = long) */
390 32, /* bitsize */
391 TRUE, /* pc_relative */
392 0, /* bitpos */
393 complain_overflow_signed, /* complain_on_overflow */
394 bfd_elf_generic_reloc, /* special_function */
395 AARCH64_R_STR (PREL32), /* name */
396 FALSE, /* partial_inplace */
397 0xffffffff, /* src_mask */
398 0xffffffff, /* dst_mask */
399 TRUE), /* pcrel_offset */
401 /* .half: (S+A-P) */
402 HOWTO (AARCH64_R (PREL16), /* type */
403 0, /* rightshift */
404 1, /* size (0 = byte, 1 = short, 2 = long) */
405 16, /* bitsize */
406 TRUE, /* pc_relative */
407 0, /* bitpos */
408 complain_overflow_signed, /* complain_on_overflow */
409 bfd_elf_generic_reloc, /* special_function */
410 AARCH64_R_STR (PREL16), /* name */
411 FALSE, /* partial_inplace */
412 0xffff, /* src_mask */
413 0xffff, /* dst_mask */
414 TRUE), /* pcrel_offset */
416 /* Group relocations to create a 16, 32, 48 or 64 bit
417 unsigned data or abs address inline. */
419 /* MOVZ: ((S+A) >> 0) & 0xffff */
420 HOWTO (AARCH64_R (MOVW_UABS_G0), /* type */
421 0, /* rightshift */
422 2, /* size (0 = byte, 1 = short, 2 = long) */
423 16, /* bitsize */
424 FALSE, /* pc_relative */
425 0, /* bitpos */
426 complain_overflow_unsigned, /* complain_on_overflow */
427 bfd_elf_generic_reloc, /* special_function */
428 AARCH64_R_STR (MOVW_UABS_G0), /* name */
429 FALSE, /* partial_inplace */
430 0xffff, /* src_mask */
431 0xffff, /* dst_mask */
432 FALSE), /* pcrel_offset */
434 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
435 HOWTO (AARCH64_R (MOVW_UABS_G0_NC), /* type */
436 0, /* rightshift */
437 2, /* size (0 = byte, 1 = short, 2 = long) */
438 16, /* bitsize */
439 FALSE, /* pc_relative */
440 0, /* bitpos */
441 complain_overflow_dont, /* complain_on_overflow */
442 bfd_elf_generic_reloc, /* special_function */
443 AARCH64_R_STR (MOVW_UABS_G0_NC), /* name */
444 FALSE, /* partial_inplace */
445 0xffff, /* src_mask */
446 0xffff, /* dst_mask */
447 FALSE), /* pcrel_offset */
449 /* MOVZ: ((S+A) >> 16) & 0xffff */
450 HOWTO (AARCH64_R (MOVW_UABS_G1), /* type */
451 16, /* rightshift */
452 2, /* size (0 = byte, 1 = short, 2 = long) */
453 16, /* bitsize */
454 FALSE, /* pc_relative */
455 0, /* bitpos */
456 complain_overflow_unsigned, /* complain_on_overflow */
457 bfd_elf_generic_reloc, /* special_function */
458 AARCH64_R_STR (MOVW_UABS_G1), /* name */
459 FALSE, /* partial_inplace */
460 0xffff, /* src_mask */
461 0xffff, /* dst_mask */
462 FALSE), /* pcrel_offset */
464 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
465 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC), /* type */
466 16, /* rightshift */
467 2, /* size (0 = byte, 1 = short, 2 = long) */
468 16, /* bitsize */
469 FALSE, /* pc_relative */
470 0, /* bitpos */
471 complain_overflow_dont, /* complain_on_overflow */
472 bfd_elf_generic_reloc, /* special_function */
473 AARCH64_R_STR (MOVW_UABS_G1_NC), /* name */
474 FALSE, /* partial_inplace */
475 0xffff, /* src_mask */
476 0xffff, /* dst_mask */
477 FALSE), /* pcrel_offset */
479 /* MOVZ: ((S+A) >> 32) & 0xffff */
480 HOWTO64 (AARCH64_R (MOVW_UABS_G2), /* type */
481 32, /* rightshift */
482 2, /* size (0 = byte, 1 = short, 2 = long) */
483 16, /* bitsize */
484 FALSE, /* pc_relative */
485 0, /* bitpos */
486 complain_overflow_unsigned, /* complain_on_overflow */
487 bfd_elf_generic_reloc, /* special_function */
488 AARCH64_R_STR (MOVW_UABS_G2), /* name */
489 FALSE, /* partial_inplace */
490 0xffff, /* src_mask */
491 0xffff, /* dst_mask */
492 FALSE), /* pcrel_offset */
494 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
495 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC), /* type */
496 32, /* rightshift */
497 2, /* size (0 = byte, 1 = short, 2 = long) */
498 16, /* bitsize */
499 FALSE, /* pc_relative */
500 0, /* bitpos */
501 complain_overflow_dont, /* complain_on_overflow */
502 bfd_elf_generic_reloc, /* special_function */
503 AARCH64_R_STR (MOVW_UABS_G2_NC), /* name */
504 FALSE, /* partial_inplace */
505 0xffff, /* src_mask */
506 0xffff, /* dst_mask */
507 FALSE), /* pcrel_offset */
509 /* MOVZ: ((S+A) >> 48) & 0xffff */
510 HOWTO64 (AARCH64_R (MOVW_UABS_G3), /* type */
511 48, /* rightshift */
512 2, /* size (0 = byte, 1 = short, 2 = long) */
513 16, /* bitsize */
514 FALSE, /* pc_relative */
515 0, /* bitpos */
516 complain_overflow_unsigned, /* complain_on_overflow */
517 bfd_elf_generic_reloc, /* special_function */
518 AARCH64_R_STR (MOVW_UABS_G3), /* name */
519 FALSE, /* partial_inplace */
520 0xffff, /* src_mask */
521 0xffff, /* dst_mask */
522 FALSE), /* pcrel_offset */
524 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
525 signed data or abs address inline. Will change instruction
526 to MOVN or MOVZ depending on sign of calculated value. */
528 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
529 HOWTO (AARCH64_R (MOVW_SABS_G0), /* type */
530 0, /* rightshift */
531 2, /* size (0 = byte, 1 = short, 2 = long) */
532 16, /* bitsize */
533 FALSE, /* pc_relative */
534 0, /* bitpos */
535 complain_overflow_signed, /* complain_on_overflow */
536 bfd_elf_generic_reloc, /* special_function */
537 AARCH64_R_STR (MOVW_SABS_G0), /* name */
538 FALSE, /* partial_inplace */
539 0xffff, /* src_mask */
540 0xffff, /* dst_mask */
541 FALSE), /* pcrel_offset */
543 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
544 HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
545 16, /* rightshift */
546 2, /* size (0 = byte, 1 = short, 2 = long) */
547 16, /* bitsize */
548 FALSE, /* pc_relative */
549 0, /* bitpos */
550 complain_overflow_signed, /* complain_on_overflow */
551 bfd_elf_generic_reloc, /* special_function */
552 AARCH64_R_STR (MOVW_SABS_G1), /* name */
553 FALSE, /* partial_inplace */
554 0xffff, /* src_mask */
555 0xffff, /* dst_mask */
556 FALSE), /* pcrel_offset */
558 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
559 HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
560 32, /* rightshift */
561 2, /* size (0 = byte, 1 = short, 2 = long) */
562 16, /* bitsize */
563 FALSE, /* pc_relative */
564 0, /* bitpos */
565 complain_overflow_signed, /* complain_on_overflow */
566 bfd_elf_generic_reloc, /* special_function */
567 AARCH64_R_STR (MOVW_SABS_G2), /* name */
568 FALSE, /* partial_inplace */
569 0xffff, /* src_mask */
570 0xffff, /* dst_mask */
571 FALSE), /* pcrel_offset */
573 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
574 addresses: PG(x) is (x & ~0xfff). */
576 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
577 HOWTO (AARCH64_R (LD_PREL_LO19), /* type */
578 2, /* rightshift */
579 2, /* size (0 = byte, 1 = short, 2 = long) */
580 19, /* bitsize */
581 TRUE, /* pc_relative */
582 0, /* bitpos */
583 complain_overflow_signed, /* complain_on_overflow */
584 bfd_elf_generic_reloc, /* special_function */
585 AARCH64_R_STR (LD_PREL_LO19), /* name */
586 FALSE, /* partial_inplace */
587 0x7ffff, /* src_mask */
588 0x7ffff, /* dst_mask */
589 TRUE), /* pcrel_offset */
591 /* ADR: (S+A-P) & 0x1fffff */
592 HOWTO (AARCH64_R (ADR_PREL_LO21), /* type */
593 0, /* rightshift */
594 2, /* size (0 = byte, 1 = short, 2 = long) */
595 21, /* bitsize */
596 TRUE, /* pc_relative */
597 0, /* bitpos */
598 complain_overflow_signed, /* complain_on_overflow */
599 bfd_elf_generic_reloc, /* special_function */
600 AARCH64_R_STR (ADR_PREL_LO21), /* name */
601 FALSE, /* partial_inplace */
602 0x1fffff, /* src_mask */
603 0x1fffff, /* dst_mask */
604 TRUE), /* pcrel_offset */
606 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
607 HOWTO (AARCH64_R (ADR_PREL_PG_HI21), /* type */
608 12, /* rightshift */
609 2, /* size (0 = byte, 1 = short, 2 = long) */
610 21, /* bitsize */
611 TRUE, /* pc_relative */
612 0, /* bitpos */
613 complain_overflow_signed, /* complain_on_overflow */
614 bfd_elf_generic_reloc, /* special_function */
615 AARCH64_R_STR (ADR_PREL_PG_HI21), /* name */
616 FALSE, /* partial_inplace */
617 0x1fffff, /* src_mask */
618 0x1fffff, /* dst_mask */
619 TRUE), /* pcrel_offset */
621 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
622 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC), /* type */
623 12, /* rightshift */
624 2, /* size (0 = byte, 1 = short, 2 = long) */
625 21, /* bitsize */
626 TRUE, /* pc_relative */
627 0, /* bitpos */
628 complain_overflow_dont, /* complain_on_overflow */
629 bfd_elf_generic_reloc, /* special_function */
630 AARCH64_R_STR (ADR_PREL_PG_HI21_NC), /* name */
631 FALSE, /* partial_inplace */
632 0x1fffff, /* src_mask */
633 0x1fffff, /* dst_mask */
634 TRUE), /* pcrel_offset */
636 /* ADD: (S+A) & 0xfff [no overflow check] */
637 HOWTO (AARCH64_R (ADD_ABS_LO12_NC), /* type */
638 0, /* rightshift */
639 2, /* size (0 = byte, 1 = short, 2 = long) */
640 12, /* bitsize */
641 FALSE, /* pc_relative */
642 10, /* bitpos */
643 complain_overflow_dont, /* complain_on_overflow */
644 bfd_elf_generic_reloc, /* special_function */
645 AARCH64_R_STR (ADD_ABS_LO12_NC), /* name */
646 FALSE, /* partial_inplace */
647 0x3ffc00, /* src_mask */
648 0x3ffc00, /* dst_mask */
649 FALSE), /* pcrel_offset */
651 /* LD/ST8: (S+A) & 0xfff */
652 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC), /* type */
653 0, /* rightshift */
654 2, /* size (0 = byte, 1 = short, 2 = long) */
655 12, /* bitsize */
656 FALSE, /* pc_relative */
657 0, /* bitpos */
658 complain_overflow_dont, /* complain_on_overflow */
659 bfd_elf_generic_reloc, /* special_function */
660 AARCH64_R_STR (LDST8_ABS_LO12_NC), /* name */
661 FALSE, /* partial_inplace */
662 0xfff, /* src_mask */
663 0xfff, /* dst_mask */
664 FALSE), /* pcrel_offset */
666 /* Relocations for control-flow instructions. */
668 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
669 HOWTO (AARCH64_R (TSTBR14), /* type */
670 2, /* rightshift */
671 2, /* size (0 = byte, 1 = short, 2 = long) */
672 14, /* bitsize */
673 TRUE, /* pc_relative */
674 0, /* bitpos */
675 complain_overflow_signed, /* complain_on_overflow */
676 bfd_elf_generic_reloc, /* special_function */
677 AARCH64_R_STR (TSTBR14), /* name */
678 FALSE, /* partial_inplace */
679 0x3fff, /* src_mask */
680 0x3fff, /* dst_mask */
681 TRUE), /* pcrel_offset */
683 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
684 HOWTO (AARCH64_R (CONDBR19), /* type */
685 2, /* rightshift */
686 2, /* size (0 = byte, 1 = short, 2 = long) */
687 19, /* bitsize */
688 TRUE, /* pc_relative */
689 0, /* bitpos */
690 complain_overflow_signed, /* complain_on_overflow */
691 bfd_elf_generic_reloc, /* special_function */
692 AARCH64_R_STR (CONDBR19), /* name */
693 FALSE, /* partial_inplace */
694 0x7ffff, /* src_mask */
695 0x7ffff, /* dst_mask */
696 TRUE), /* pcrel_offset */
698 /* B: ((S+A-P) >> 2) & 0x3ffffff */
699 HOWTO (AARCH64_R (JUMP26), /* type */
700 2, /* rightshift */
701 2, /* size (0 = byte, 1 = short, 2 = long) */
702 26, /* bitsize */
703 TRUE, /* pc_relative */
704 0, /* bitpos */
705 complain_overflow_signed, /* complain_on_overflow */
706 bfd_elf_generic_reloc, /* special_function */
707 AARCH64_R_STR (JUMP26), /* name */
708 FALSE, /* partial_inplace */
709 0x3ffffff, /* src_mask */
710 0x3ffffff, /* dst_mask */
711 TRUE), /* pcrel_offset */
713 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
714 HOWTO (AARCH64_R (CALL26), /* type */
715 2, /* rightshift */
716 2, /* size (0 = byte, 1 = short, 2 = long) */
717 26, /* bitsize */
718 TRUE, /* pc_relative */
719 0, /* bitpos */
720 complain_overflow_signed, /* complain_on_overflow */
721 bfd_elf_generic_reloc, /* special_function */
722 AARCH64_R_STR (CALL26), /* name */
723 FALSE, /* partial_inplace */
724 0x3ffffff, /* src_mask */
725 0x3ffffff, /* dst_mask */
726 TRUE), /* pcrel_offset */
728 /* LD/ST16: (S+A) & 0xffe */
729 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */
730 1, /* rightshift */
731 2, /* size (0 = byte, 1 = short, 2 = long) */
732 12, /* bitsize */
733 FALSE, /* pc_relative */
734 0, /* bitpos */
735 complain_overflow_dont, /* complain_on_overflow */
736 bfd_elf_generic_reloc, /* special_function */
737 AARCH64_R_STR (LDST16_ABS_LO12_NC), /* name */
738 FALSE, /* partial_inplace */
739 0xffe, /* src_mask */
740 0xffe, /* dst_mask */
741 FALSE), /* pcrel_offset */
743 /* LD/ST32: (S+A) & 0xffc */
744 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC), /* type */
745 2, /* rightshift */
746 2, /* size (0 = byte, 1 = short, 2 = long) */
747 12, /* bitsize */
748 FALSE, /* pc_relative */
749 0, /* bitpos */
750 complain_overflow_dont, /* complain_on_overflow */
751 bfd_elf_generic_reloc, /* special_function */
752 AARCH64_R_STR (LDST32_ABS_LO12_NC), /* name */
753 FALSE, /* partial_inplace */
754 0xffc, /* src_mask */
755 0xffc, /* dst_mask */
756 FALSE), /* pcrel_offset */
758 /* LD/ST64: (S+A) & 0xff8 */
759 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC), /* type */
760 3, /* rightshift */
761 2, /* size (0 = byte, 1 = short, 2 = long) */
762 12, /* bitsize */
763 FALSE, /* pc_relative */
764 0, /* bitpos */
765 complain_overflow_dont, /* complain_on_overflow */
766 bfd_elf_generic_reloc, /* special_function */
767 AARCH64_R_STR (LDST64_ABS_LO12_NC), /* name */
768 FALSE, /* partial_inplace */
769 0xff8, /* src_mask */
770 0xff8, /* dst_mask */
771 FALSE), /* pcrel_offset */
773 /* LD/ST128: (S+A) & 0xff0 */
774 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC), /* type */
775 4, /* rightshift */
776 2, /* size (0 = byte, 1 = short, 2 = long) */
777 12, /* bitsize */
778 FALSE, /* pc_relative */
779 0, /* bitpos */
780 complain_overflow_dont, /* complain_on_overflow */
781 bfd_elf_generic_reloc, /* special_function */
782 AARCH64_R_STR (LDST128_ABS_LO12_NC), /* name */
783 FALSE, /* partial_inplace */
784 0xff0, /* src_mask */
785 0xff0, /* dst_mask */
786 FALSE), /* pcrel_offset */
788 /* Set a load-literal immediate field to bits
789 0x1FFFFC of G(S)-P */
790 HOWTO (AARCH64_R (GOT_LD_PREL19), /* type */
791 2, /* rightshift */
792 2, /* size (0 = byte,1 = short,2 = long) */
793 19, /* bitsize */
794 TRUE, /* pc_relative */
795 0, /* bitpos */
796 complain_overflow_signed, /* complain_on_overflow */
797 bfd_elf_generic_reloc, /* special_function */
798 AARCH64_R_STR (GOT_LD_PREL19), /* name */
799 FALSE, /* partial_inplace */
800 0xffffe0, /* src_mask */
801 0xffffe0, /* dst_mask */
802 TRUE), /* pcrel_offset */
804 /* Get to the page for the GOT entry for the symbol
805 (G(S) - P) using an ADRP instruction. */
806 HOWTO (AARCH64_R (ADR_GOT_PAGE), /* type */
807 12, /* rightshift */
808 2, /* size (0 = byte, 1 = short, 2 = long) */
809 21, /* bitsize */
810 TRUE, /* pc_relative */
811 0, /* bitpos */
812 complain_overflow_dont, /* complain_on_overflow */
813 bfd_elf_generic_reloc, /* special_function */
814 AARCH64_R_STR (ADR_GOT_PAGE), /* name */
815 FALSE, /* partial_inplace */
816 0x1fffff, /* src_mask */
817 0x1fffff, /* dst_mask */
818 TRUE), /* pcrel_offset */
820 /* LD64: GOT offset G(S) & 0xff8 */
821 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC), /* type */
822 3, /* rightshift */
823 2, /* size (0 = byte, 1 = short, 2 = long) */
824 12, /* bitsize */
825 FALSE, /* pc_relative */
826 0, /* bitpos */
827 complain_overflow_dont, /* complain_on_overflow */
828 bfd_elf_generic_reloc, /* special_function */
829 AARCH64_R_STR (LD64_GOT_LO12_NC), /* name */
830 FALSE, /* partial_inplace */
831 0xff8, /* src_mask */
832 0xff8, /* dst_mask */
833 FALSE), /* pcrel_offset */
835 /* LD32: GOT offset G(S) & 0xffc */
836 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC), /* type */
837 2, /* rightshift */
838 2, /* size (0 = byte, 1 = short, 2 = long) */
839 12, /* bitsize */
840 FALSE, /* pc_relative */
841 0, /* bitpos */
842 complain_overflow_dont, /* complain_on_overflow */
843 bfd_elf_generic_reloc, /* special_function */
844 AARCH64_R_STR (LD32_GOT_LO12_NC), /* name */
845 FALSE, /* partial_inplace */
846 0xffc, /* src_mask */
847 0xffc, /* dst_mask */
848 FALSE), /* pcrel_offset */
850 /* Get to the page for the GOT entry for the symbol
851 (G(S) - P) using an ADRP instruction. */
852 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21), /* type */
853 12, /* rightshift */
854 2, /* size (0 = byte, 1 = short, 2 = long) */
855 21, /* bitsize */
856 TRUE, /* pc_relative */
857 0, /* bitpos */
858 complain_overflow_dont, /* complain_on_overflow */
859 bfd_elf_generic_reloc, /* special_function */
860 AARCH64_R_STR (TLSGD_ADR_PAGE21), /* name */
861 FALSE, /* partial_inplace */
862 0x1fffff, /* src_mask */
863 0x1fffff, /* dst_mask */
864 TRUE), /* pcrel_offset */
866 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
867 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC), /* type */
868 0, /* rightshift */
869 2, /* size (0 = byte, 1 = short, 2 = long) */
870 12, /* bitsize */
871 FALSE, /* pc_relative */
872 0, /* bitpos */
873 complain_overflow_dont, /* complain_on_overflow */
874 bfd_elf_generic_reloc, /* special_function */
875 AARCH64_R_STR (TLSGD_ADD_LO12_NC), /* name */
876 FALSE, /* partial_inplace */
877 0xfff, /* src_mask */
878 0xfff, /* dst_mask */
879 FALSE), /* pcrel_offset */
881 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
882 16, /* rightshift */
883 2, /* size (0 = byte, 1 = short, 2 = long) */
884 16, /* bitsize */
885 FALSE, /* pc_relative */
886 0, /* bitpos */
887 complain_overflow_dont, /* complain_on_overflow */
888 bfd_elf_generic_reloc, /* special_function */
889 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1), /* name */
890 FALSE, /* partial_inplace */
891 0xffff, /* src_mask */
892 0xffff, /* dst_mask */
893 FALSE), /* pcrel_offset */
895 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC), /* type */
896 0, /* rightshift */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
898 32, /* bitsize */
899 FALSE, /* pc_relative */
900 0, /* bitpos */
901 complain_overflow_dont, /* complain_on_overflow */
902 bfd_elf_generic_reloc, /* special_function */
903 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC), /* name */
904 FALSE, /* partial_inplace */
905 0xffff, /* src_mask */
906 0xffff, /* dst_mask */
907 FALSE), /* pcrel_offset */
909 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21), /* type */
910 12, /* rightshift */
911 2, /* size (0 = byte, 1 = short, 2 = long) */
912 21, /* bitsize */
913 FALSE, /* pc_relative */
914 0, /* bitpos */
915 complain_overflow_dont, /* complain_on_overflow */
916 bfd_elf_generic_reloc, /* special_function */
917 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21), /* name */
918 FALSE, /* partial_inplace */
919 0x1fffff, /* src_mask */
920 0x1fffff, /* dst_mask */
921 FALSE), /* pcrel_offset */
923 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC), /* type */
924 3, /* rightshift */
925 2, /* size (0 = byte, 1 = short, 2 = long) */
926 12, /* bitsize */
927 FALSE, /* pc_relative */
928 0, /* bitpos */
929 complain_overflow_dont, /* complain_on_overflow */
930 bfd_elf_generic_reloc, /* special_function */
931 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC), /* name */
932 FALSE, /* partial_inplace */
933 0xff8, /* src_mask */
934 0xff8, /* dst_mask */
935 FALSE), /* pcrel_offset */
937 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC), /* type */
938 2, /* rightshift */
939 2, /* size (0 = byte, 1 = short, 2 = long) */
940 12, /* bitsize */
941 FALSE, /* pc_relative */
942 0, /* bitpos */
943 complain_overflow_dont, /* complain_on_overflow */
944 bfd_elf_generic_reloc, /* special_function */
945 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC), /* name */
946 FALSE, /* partial_inplace */
947 0xffc, /* src_mask */
948 0xffc, /* dst_mask */
949 FALSE), /* pcrel_offset */
951 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19), /* type */
952 2, /* rightshift */
953 2, /* size (0 = byte, 1 = short, 2 = long) */
954 21, /* bitsize */
955 FALSE, /* pc_relative */
956 0, /* bitpos */
957 complain_overflow_dont, /* complain_on_overflow */
958 bfd_elf_generic_reloc, /* special_function */
959 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19), /* name */
960 FALSE, /* partial_inplace */
961 0x1ffffc, /* src_mask */
962 0x1ffffc, /* dst_mask */
963 FALSE), /* pcrel_offset */
965 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
966 32, /* rightshift */
967 2, /* size (0 = byte, 1 = short, 2 = long) */
968 12, /* bitsize */
969 FALSE, /* pc_relative */
970 0, /* bitpos */
971 complain_overflow_dont, /* complain_on_overflow */
972 bfd_elf_generic_reloc, /* special_function */
973 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2), /* name */
974 FALSE, /* partial_inplace */
975 0xffff, /* src_mask */
976 0xffff, /* dst_mask */
977 FALSE), /* pcrel_offset */
979 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1), /* type */
980 16, /* rightshift */
981 2, /* size (0 = byte, 1 = short, 2 = long) */
982 12, /* bitsize */
983 FALSE, /* pc_relative */
984 0, /* bitpos */
985 complain_overflow_dont, /* complain_on_overflow */
986 bfd_elf_generic_reloc, /* special_function */
987 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1), /* name */
988 FALSE, /* partial_inplace */
989 0xffff, /* src_mask */
990 0xffff, /* dst_mask */
991 FALSE), /* pcrel_offset */
993 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC), /* type */
994 16, /* rightshift */
995 2, /* size (0 = byte, 1 = short, 2 = long) */
996 12, /* bitsize */
997 FALSE, /* pc_relative */
998 0, /* bitpos */
999 complain_overflow_dont, /* complain_on_overflow */
1000 bfd_elf_generic_reloc, /* special_function */
1001 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC), /* name */
1002 FALSE, /* partial_inplace */
1003 0xffff, /* src_mask */
1004 0xffff, /* dst_mask */
1005 FALSE), /* pcrel_offset */
1007 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0), /* type */
1008 0, /* rightshift */
1009 2, /* size (0 = byte, 1 = short, 2 = long) */
1010 12, /* bitsize */
1011 FALSE, /* pc_relative */
1012 0, /* bitpos */
1013 complain_overflow_dont, /* complain_on_overflow */
1014 bfd_elf_generic_reloc, /* special_function */
1015 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0), /* name */
1016 FALSE, /* partial_inplace */
1017 0xffff, /* src_mask */
1018 0xffff, /* dst_mask */
1019 FALSE), /* pcrel_offset */
1021 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC), /* type */
1022 0, /* rightshift */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1024 12, /* bitsize */
1025 FALSE, /* pc_relative */
1026 0, /* bitpos */
1027 complain_overflow_dont, /* complain_on_overflow */
1028 bfd_elf_generic_reloc, /* special_function */
1029 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC), /* name */
1030 FALSE, /* partial_inplace */
1031 0xffff, /* src_mask */
1032 0xffff, /* dst_mask */
1033 FALSE), /* pcrel_offset */
1035 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12), /* type */
1036 12, /* rightshift */
1037 2, /* size (0 = byte, 1 = short, 2 = long) */
1038 12, /* bitsize */
1039 FALSE, /* pc_relative */
1040 0, /* bitpos */
1041 complain_overflow_dont, /* complain_on_overflow */
1042 bfd_elf_generic_reloc, /* special_function */
1043 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12), /* name */
1044 FALSE, /* partial_inplace */
1045 0xfff, /* src_mask */
1046 0xfff, /* dst_mask */
1047 FALSE), /* pcrel_offset */
1049 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12), /* type */
1050 0, /* rightshift */
1051 2, /* size (0 = byte, 1 = short, 2 = long) */
1052 12, /* bitsize */
1053 FALSE, /* pc_relative */
1054 0, /* bitpos */
1055 complain_overflow_dont, /* complain_on_overflow */
1056 bfd_elf_generic_reloc, /* special_function */
1057 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12), /* name */
1058 FALSE, /* partial_inplace */
1059 0xfff, /* src_mask */
1060 0xfff, /* dst_mask */
1061 FALSE), /* pcrel_offset */
1063 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC), /* type */
1064 0, /* rightshift */
1065 2, /* size (0 = byte, 1 = short, 2 = long) */
1066 12, /* bitsize */
1067 FALSE, /* pc_relative */
1068 0, /* bitpos */
1069 complain_overflow_dont, /* complain_on_overflow */
1070 bfd_elf_generic_reloc, /* special_function */
1071 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC), /* name */
1072 FALSE, /* partial_inplace */
1073 0xfff, /* src_mask */
1074 0xfff, /* dst_mask */
1075 FALSE), /* pcrel_offset */
1077 HOWTO (AARCH64_R (TLSDESC_LD_PREL19), /* type */
1078 2, /* rightshift */
1079 2, /* size (0 = byte, 1 = short, 2 = long) */
1080 21, /* bitsize */
1081 TRUE, /* pc_relative */
1082 0, /* bitpos */
1083 complain_overflow_dont, /* complain_on_overflow */
1084 bfd_elf_generic_reloc, /* special_function */
1085 AARCH64_R_STR (TLSDESC_LD_PREL19), /* name */
1086 FALSE, /* partial_inplace */
1087 0x1ffffc, /* src_mask */
1088 0x1ffffc, /* dst_mask */
1089 TRUE), /* pcrel_offset */
1091 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21), /* type */
1092 0, /* rightshift */
1093 2, /* size (0 = byte, 1 = short, 2 = long) */
1094 21, /* bitsize */
1095 TRUE, /* pc_relative */
1096 0, /* bitpos */
1097 complain_overflow_dont, /* complain_on_overflow */
1098 bfd_elf_generic_reloc, /* special_function */
1099 AARCH64_R_STR (TLSDESC_ADR_PREL21), /* name */
1100 FALSE, /* partial_inplace */
1101 0x1fffff, /* src_mask */
1102 0x1fffff, /* dst_mask */
1103 TRUE), /* pcrel_offset */
1105 /* Get to the page for the GOT entry for the symbol
1106 (G(S) - P) using an ADRP instruction. */
1107 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21), /* type */
1108 12, /* rightshift */
1109 2, /* size (0 = byte, 1 = short, 2 = long) */
1110 21, /* bitsize */
1111 TRUE, /* pc_relative */
1112 0, /* bitpos */
1113 complain_overflow_dont, /* complain_on_overflow */
1114 bfd_elf_generic_reloc, /* special_function */
1115 AARCH64_R_STR (TLSDESC_ADR_PAGE21), /* name */
1116 FALSE, /* partial_inplace */
1117 0x1fffff, /* src_mask */
1118 0x1fffff, /* dst_mask */
1119 TRUE), /* pcrel_offset */
1121 /* LD64: GOT offset G(S) & 0xff8. */
1122 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC), /* type */
1123 3, /* rightshift */
1124 2, /* size (0 = byte, 1 = short, 2 = long) */
1125 12, /* bitsize */
1126 FALSE, /* pc_relative */
1127 0, /* bitpos */
1128 complain_overflow_dont, /* complain_on_overflow */
1129 bfd_elf_generic_reloc, /* special_function */
1130 AARCH64_R_STR (TLSDESC_LD64_LO12_NC), /* name */
1131 FALSE, /* partial_inplace */
1132 0xff8, /* src_mask */
1133 0xff8, /* dst_mask */
1134 FALSE), /* pcrel_offset */
1136 /* LD32: GOT offset G(S) & 0xffc. */
1137 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC), /* type */
1138 2, /* rightshift */
1139 2, /* size (0 = byte, 1 = short, 2 = long) */
1140 12, /* bitsize */
1141 FALSE, /* pc_relative */
1142 0, /* bitpos */
1143 complain_overflow_dont, /* complain_on_overflow */
1144 bfd_elf_generic_reloc, /* special_function */
1145 AARCH64_R_STR (TLSDESC_LD32_LO12_NC), /* name */
1146 FALSE, /* partial_inplace */
1147 0xffc, /* src_mask */
1148 0xffc, /* dst_mask */
1149 FALSE), /* pcrel_offset */
1151 /* ADD: GOT offset G(S) & 0xfff. */
1152 HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC), /* type */
1153 0, /* rightshift */
1154 2, /* size (0 = byte, 1 = short, 2 = long) */
1155 12, /* bitsize */
1156 FALSE, /* pc_relative */
1157 0, /* bitpos */
1158 complain_overflow_dont, /* complain_on_overflow */
1159 bfd_elf_generic_reloc, /* special_function */
1160 AARCH64_R_STR (TLSDESC_ADD_LO12_NC), /* name */
1161 FALSE, /* partial_inplace */
1162 0xfff, /* src_mask */
1163 0xfff, /* dst_mask */
1164 FALSE), /* pcrel_offset */
1166 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1), /* type */
1167 16, /* rightshift */
1168 2, /* size (0 = byte, 1 = short, 2 = long) */
1169 12, /* bitsize */
1170 FALSE, /* pc_relative */
1171 0, /* bitpos */
1172 complain_overflow_dont, /* complain_on_overflow */
1173 bfd_elf_generic_reloc, /* special_function */
1174 AARCH64_R_STR (TLSDESC_OFF_G1), /* name */
1175 FALSE, /* partial_inplace */
1176 0xffff, /* src_mask */
1177 0xffff, /* dst_mask */
1178 FALSE), /* pcrel_offset */
1180 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC), /* type */
1181 0, /* rightshift */
1182 2, /* size (0 = byte, 1 = short, 2 = long) */
1183 12, /* bitsize */
1184 FALSE, /* pc_relative */
1185 0, /* bitpos */
1186 complain_overflow_dont, /* complain_on_overflow */
1187 bfd_elf_generic_reloc, /* special_function */
1188 AARCH64_R_STR (TLSDESC_OFF_G0_NC), /* name */
1189 FALSE, /* partial_inplace */
1190 0xffff, /* src_mask */
1191 0xffff, /* dst_mask */
1192 FALSE), /* pcrel_offset */
1194 HOWTO64 (AARCH64_R (TLSDESC_LDR), /* type */
1195 0, /* rightshift */
1196 2, /* size (0 = byte, 1 = short, 2 = long) */
1197 12, /* bitsize */
1198 FALSE, /* pc_relative */
1199 0, /* bitpos */
1200 complain_overflow_dont, /* complain_on_overflow */
1201 bfd_elf_generic_reloc, /* special_function */
1202 AARCH64_R_STR (TLSDESC_LDR), /* name */
1203 FALSE, /* partial_inplace */
1204 0x0, /* src_mask */
1205 0x0, /* dst_mask */
1206 FALSE), /* pcrel_offset */
1208 HOWTO64 (AARCH64_R (TLSDESC_ADD), /* type */
1209 0, /* rightshift */
1210 2, /* size (0 = byte, 1 = short, 2 = long) */
1211 12, /* bitsize */
1212 FALSE, /* pc_relative */
1213 0, /* bitpos */
1214 complain_overflow_dont, /* complain_on_overflow */
1215 bfd_elf_generic_reloc, /* special_function */
1216 AARCH64_R_STR (TLSDESC_ADD), /* name */
1217 FALSE, /* partial_inplace */
1218 0x0, /* src_mask */
1219 0x0, /* dst_mask */
1220 FALSE), /* pcrel_offset */
1222 HOWTO (AARCH64_R (TLSDESC_CALL), /* type */
1223 0, /* rightshift */
1224 2, /* size (0 = byte, 1 = short, 2 = long) */
1225 12, /* bitsize */
1226 FALSE, /* pc_relative */
1227 0, /* bitpos */
1228 complain_overflow_dont, /* complain_on_overflow */
1229 bfd_elf_generic_reloc, /* special_function */
1230 AARCH64_R_STR (TLSDESC_CALL), /* name */
1231 FALSE, /* partial_inplace */
1232 0x0, /* src_mask */
1233 0x0, /* dst_mask */
1234 FALSE), /* pcrel_offset */
1236 HOWTO (AARCH64_R (COPY), /* type */
1237 0, /* rightshift */
1238 2, /* size (0 = byte, 1 = short, 2 = long) */
1239 64, /* bitsize */
1240 FALSE, /* pc_relative */
1241 0, /* bitpos */
1242 complain_overflow_bitfield, /* complain_on_overflow */
1243 bfd_elf_generic_reloc, /* special_function */
1244 AARCH64_R_STR (COPY), /* name */
1245 TRUE, /* partial_inplace */
1246 0xffffffff, /* src_mask */
1247 0xffffffff, /* dst_mask */
1248 FALSE), /* pcrel_offset */
1250 HOWTO (AARCH64_R (GLOB_DAT), /* type */
1251 0, /* rightshift */
1252 2, /* size (0 = byte, 1 = short, 2 = long) */
1253 64, /* bitsize */
1254 FALSE, /* pc_relative */
1255 0, /* bitpos */
1256 complain_overflow_bitfield, /* complain_on_overflow */
1257 bfd_elf_generic_reloc, /* special_function */
1258 AARCH64_R_STR (GLOB_DAT), /* name */
1259 TRUE, /* partial_inplace */
1260 0xffffffff, /* src_mask */
1261 0xffffffff, /* dst_mask */
1262 FALSE), /* pcrel_offset */
1264 HOWTO (AARCH64_R (JUMP_SLOT), /* type */
1265 0, /* rightshift */
1266 2, /* size (0 = byte, 1 = short, 2 = long) */
1267 64, /* bitsize */
1268 FALSE, /* pc_relative */
1269 0, /* bitpos */
1270 complain_overflow_bitfield, /* complain_on_overflow */
1271 bfd_elf_generic_reloc, /* special_function */
1272 AARCH64_R_STR (JUMP_SLOT), /* name */
1273 TRUE, /* partial_inplace */
1274 0xffffffff, /* src_mask */
1275 0xffffffff, /* dst_mask */
1276 FALSE), /* pcrel_offset */
1278 HOWTO (AARCH64_R (RELATIVE), /* type */
1279 0, /* rightshift */
1280 2, /* size (0 = byte, 1 = short, 2 = long) */
1281 64, /* bitsize */
1282 FALSE, /* pc_relative */
1283 0, /* bitpos */
1284 complain_overflow_bitfield, /* complain_on_overflow */
1285 bfd_elf_generic_reloc, /* special_function */
1286 AARCH64_R_STR (RELATIVE), /* name */
1287 TRUE, /* partial_inplace */
1288 ALL_ONES, /* src_mask */
1289 ALL_ONES, /* dst_mask */
1290 FALSE), /* pcrel_offset */
1292 HOWTO (AARCH64_R (TLS_DTPMOD), /* type */
1293 0, /* rightshift */
1294 2, /* size (0 = byte, 1 = short, 2 = long) */
1295 64, /* bitsize */
1296 FALSE, /* pc_relative */
1297 0, /* bitpos */
1298 complain_overflow_dont, /* complain_on_overflow */
1299 bfd_elf_generic_reloc, /* special_function */
1300 AARCH64_R_STR (TLS_DTPMOD), /* name */
1301 FALSE, /* partial_inplace */
1302 0, /* src_mask */
1303 ALL_ONES, /* dst_mask */
1304 FALSE), /* pc_reloffset */
1306 HOWTO (AARCH64_R (TLS_DTPREL), /* type */
1307 0, /* rightshift */
1308 2, /* size (0 = byte, 1 = short, 2 = long) */
1309 64, /* bitsize */
1310 FALSE, /* pc_relative */
1311 0, /* bitpos */
1312 complain_overflow_dont, /* complain_on_overflow */
1313 bfd_elf_generic_reloc, /* special_function */
1314 AARCH64_R_STR (TLS_DTPREL), /* name */
1315 FALSE, /* partial_inplace */
1316 0, /* src_mask */
1317 ALL_ONES, /* dst_mask */
1318 FALSE), /* pcrel_offset */
1320 HOWTO (AARCH64_R (TLS_TPREL), /* type */
1321 0, /* rightshift */
1322 2, /* size (0 = byte, 1 = short, 2 = long) */
1323 64, /* bitsize */
1324 FALSE, /* pc_relative */
1325 0, /* bitpos */
1326 complain_overflow_dont, /* complain_on_overflow */
1327 bfd_elf_generic_reloc, /* special_function */
1328 AARCH64_R_STR (TLS_TPREL), /* name */
1329 FALSE, /* partial_inplace */
1330 0, /* src_mask */
1331 ALL_ONES, /* dst_mask */
1332 FALSE), /* pcrel_offset */
1334 HOWTO (AARCH64_R (TLSDESC), /* type */
1335 0, /* rightshift */
1336 2, /* size (0 = byte, 1 = short, 2 = long) */
1337 64, /* bitsize */
1338 FALSE, /* pc_relative */
1339 0, /* bitpos */
1340 complain_overflow_dont, /* complain_on_overflow */
1341 bfd_elf_generic_reloc, /* special_function */
1342 AARCH64_R_STR (TLSDESC), /* name */
1343 FALSE, /* partial_inplace */
1344 0, /* src_mask */
1345 ALL_ONES, /* dst_mask */
1346 FALSE), /* pcrel_offset */
1348 HOWTO (AARCH64_R (IRELATIVE), /* type */
1349 0, /* rightshift */
1350 2, /* size (0 = byte, 1 = short, 2 = long) */
1351 64, /* bitsize */
1352 FALSE, /* pc_relative */
1353 0, /* bitpos */
1354 complain_overflow_bitfield, /* complain_on_overflow */
1355 bfd_elf_generic_reloc, /* special_function */
1356 AARCH64_R_STR (IRELATIVE), /* name */
1357 FALSE, /* partial_inplace */
1358 0, /* src_mask */
1359 ALL_ONES, /* dst_mask */
1360 FALSE), /* pcrel_offset */
1362 EMPTY_HOWTO (0),
1365 static reloc_howto_type elfNN_aarch64_howto_none =
1366 HOWTO (R_AARCH64_NONE, /* type */
1367 0, /* rightshift */
1368 0, /* size (0 = byte, 1 = short, 2 = long) */
1369 0, /* bitsize */
1370 FALSE, /* pc_relative */
1371 0, /* bitpos */
1372 complain_overflow_dont,/* complain_on_overflow */
1373 bfd_elf_generic_reloc, /* special_function */
1374 "R_AARCH64_NONE", /* name */
1375 FALSE, /* partial_inplace */
1376 0, /* src_mask */
1377 0, /* dst_mask */
1378 FALSE); /* pcrel_offset */
1380 /* Given HOWTO, return the bfd internal relocation enumerator. */
1382 static bfd_reloc_code_real_type
1383 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type *howto)
1385 const int size
1386 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table);
1387 const ptrdiff_t offset
1388 = howto - elfNN_aarch64_howto_table;
1390 if (offset > 0 && offset < size - 1)
1391 return BFD_RELOC_AARCH64_RELOC_START + offset;
1393 if (howto == &elfNN_aarch64_howto_none)
1394 return BFD_RELOC_AARCH64_NONE;
1396 return BFD_RELOC_AARCH64_RELOC_START;
1399 /* Given R_TYPE, return the bfd internal relocation enumerator. */
1401 static bfd_reloc_code_real_type
1402 elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type)
1404 static bfd_boolean initialized_p = FALSE;
1405 /* Indexed by R_TYPE, values are offsets in the howto_table. */
1406 static unsigned int offsets[R_AARCH64_end];
1408 if (initialized_p == FALSE)
1410 unsigned int i;
1412 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
1413 if (elfNN_aarch64_howto_table[i].type != 0)
1414 offsets[elfNN_aarch64_howto_table[i].type] = i;
1416 initialized_p = TRUE;
1419 if (r_type == R_AARCH64_NONE || r_type == R_AARCH64_NULL)
1420 return BFD_RELOC_AARCH64_NONE;
1422 return BFD_RELOC_AARCH64_RELOC_START + offsets[r_type];
1425 struct elf_aarch64_reloc_map
1427 bfd_reloc_code_real_type from;
1428 bfd_reloc_code_real_type to;
1431 /* Map bfd generic reloc to AArch64-specific reloc. */
1432 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map[] =
1434 {BFD_RELOC_NONE, BFD_RELOC_AARCH64_NONE},
1436 /* Basic data relocations. */
1437 {BFD_RELOC_CTOR, BFD_RELOC_AARCH64_NN},
1438 {BFD_RELOC_64, BFD_RELOC_AARCH64_64},
1439 {BFD_RELOC_32, BFD_RELOC_AARCH64_32},
1440 {BFD_RELOC_16, BFD_RELOC_AARCH64_16},
1441 {BFD_RELOC_64_PCREL, BFD_RELOC_AARCH64_64_PCREL},
1442 {BFD_RELOC_32_PCREL, BFD_RELOC_AARCH64_32_PCREL},
1443 {BFD_RELOC_16_PCREL, BFD_RELOC_AARCH64_16_PCREL},
1446 /* Given the bfd internal relocation enumerator in CODE, return the
1447 corresponding howto entry. */
1449 static reloc_howto_type *
1450 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
1452 unsigned int i;
1454 /* Convert bfd generic reloc to AArch64-specific reloc. */
1455 if (code < BFD_RELOC_AARCH64_RELOC_START
1456 || code > BFD_RELOC_AARCH64_RELOC_END)
1457 for (i = 0; i < ARRAY_SIZE (elf_aarch64_reloc_map); i++)
1458 if (elf_aarch64_reloc_map[i].from == code)
1460 code = elf_aarch64_reloc_map[i].to;
1461 break;
1464 if (code > BFD_RELOC_AARCH64_RELOC_START
1465 && code < BFD_RELOC_AARCH64_RELOC_END)
1466 if (elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START].type)
1467 return &elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START];
1469 if (code == BFD_RELOC_AARCH64_NONE)
1470 return &elfNN_aarch64_howto_none;
1472 return NULL;
1475 static reloc_howto_type *
1476 elfNN_aarch64_howto_from_type (unsigned int r_type)
1478 bfd_reloc_code_real_type val;
1479 reloc_howto_type *howto;
1481 #if ARCH_SIZE == 32
1482 if (r_type > 256)
1484 bfd_set_error (bfd_error_bad_value);
1485 return NULL;
1487 #endif
1489 if (r_type == R_AARCH64_NONE)
1490 return &elfNN_aarch64_howto_none;
1492 val = elfNN_aarch64_bfd_reloc_from_type (r_type);
1493 howto = elfNN_aarch64_howto_from_bfd_reloc (val);
1495 if (howto != NULL)
1496 return howto;
1498 bfd_set_error (bfd_error_bad_value);
1499 return NULL;
1502 static void
1503 elfNN_aarch64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
1504 Elf_Internal_Rela *elf_reloc)
1506 unsigned int r_type;
1508 r_type = ELFNN_R_TYPE (elf_reloc->r_info);
1509 bfd_reloc->howto = elfNN_aarch64_howto_from_type (r_type);
1512 static reloc_howto_type *
1513 elfNN_aarch64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1514 bfd_reloc_code_real_type code)
1516 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (code);
1518 if (howto != NULL)
1519 return howto;
1521 bfd_set_error (bfd_error_bad_value);
1522 return NULL;
1525 static reloc_howto_type *
1526 elfNN_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1527 const char *r_name)
1529 unsigned int i;
1531 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
1532 if (elfNN_aarch64_howto_table[i].name != NULL
1533 && strcasecmp (elfNN_aarch64_howto_table[i].name, r_name) == 0)
1534 return &elfNN_aarch64_howto_table[i];
1536 return NULL;
1539 #define TARGET_LITTLE_SYM bfd_elfNN_littleaarch64_vec
1540 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
1541 #define TARGET_BIG_SYM bfd_elfNN_bigaarch64_vec
1542 #define TARGET_BIG_NAME "elfNN-bigaarch64"
1544 /* The linker script knows the section names for placement.
1545 The entry_names are used to do simple name mangling on the stubs.
1546 Given a function name, and its type, the stub can be found. The
1547 name can be changed. The only requirement is the %s be present. */
1548 #define STUB_ENTRY_NAME "__%s_veneer"
1550 /* The name of the dynamic interpreter. This is put in the .interp
1551 section. */
1552 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1554 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
1555 (((1 << 25) - 1) << 2)
1556 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
1557 (-((1 << 25) << 2))
1559 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
1560 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
1562 static int
1563 aarch64_valid_for_adrp_p (bfd_vma value, bfd_vma place)
1565 bfd_signed_vma offset = (bfd_signed_vma) (PG (value) - PG (place)) >> 12;
1566 return offset <= AARCH64_MAX_ADRP_IMM && offset >= AARCH64_MIN_ADRP_IMM;
1569 static int
1570 aarch64_valid_branch_p (bfd_vma value, bfd_vma place)
1572 bfd_signed_vma offset = (bfd_signed_vma) (value - place);
1573 return (offset <= AARCH64_MAX_FWD_BRANCH_OFFSET
1574 && offset >= AARCH64_MAX_BWD_BRANCH_OFFSET);
1577 static const uint32_t aarch64_adrp_branch_stub [] =
1579 0x90000010, /* adrp ip0, X */
1580 /* R_AARCH64_ADR_HI21_PCREL(X) */
1581 0x91000210, /* add ip0, ip0, :lo12:X */
1582 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
1583 0xd61f0200, /* br ip0 */
1586 static const uint32_t aarch64_long_branch_stub[] =
1588 #if ARCH_SIZE == 64
1589 0x58000090, /* ldr ip0, 1f */
1590 #else
1591 0x18000090, /* ldr wip0, 1f */
1592 #endif
1593 0x10000011, /* adr ip1, #0 */
1594 0x8b110210, /* add ip0, ip0, ip1 */
1595 0xd61f0200, /* br ip0 */
1596 0x00000000, /* 1: .xword or .word
1597 R_AARCH64_PRELNN(X) + 12
1599 0x00000000,
1602 /* Section name for stubs is the associated section name plus this
1603 string. */
1604 #define STUB_SUFFIX ".stub"
1606 enum elf_aarch64_stub_type
1608 aarch64_stub_none,
1609 aarch64_stub_adrp_branch,
1610 aarch64_stub_long_branch,
1613 struct elf_aarch64_stub_hash_entry
1615 /* Base hash table entry structure. */
1616 struct bfd_hash_entry root;
1618 /* The stub section. */
1619 asection *stub_sec;
1621 /* Offset within stub_sec of the beginning of this stub. */
1622 bfd_vma stub_offset;
1624 /* Given the symbol's value and its section we can determine its final
1625 value when building the stubs (so the stub knows where to jump). */
1626 bfd_vma target_value;
1627 asection *target_section;
1629 enum elf_aarch64_stub_type stub_type;
1631 /* The symbol table entry, if any, that this was derived from. */
1632 struct elf_aarch64_link_hash_entry *h;
1634 /* Destination symbol type */
1635 unsigned char st_type;
1637 /* Where this stub is being called from, or, in the case of combined
1638 stub sections, the first input section in the group. */
1639 asection *id_sec;
1641 /* The name for the local symbol at the start of this stub. The
1642 stub name in the hash table has to be unique; this does not, so
1643 it can be friendlier. */
1644 char *output_name;
1647 /* Used to build a map of a section. This is required for mixed-endian
1648 code/data. */
1650 typedef struct elf_elf_section_map
1652 bfd_vma vma;
1653 char type;
1655 elf_aarch64_section_map;
1658 typedef struct _aarch64_elf_section_data
1660 struct bfd_elf_section_data elf;
1661 unsigned int mapcount;
1662 unsigned int mapsize;
1663 elf_aarch64_section_map *map;
1665 _aarch64_elf_section_data;
1667 #define elf_aarch64_section_data(sec) \
1668 ((_aarch64_elf_section_data *) elf_section_data (sec))
1670 /* The size of the thread control block which is defined to be two pointers. */
1671 #define TCB_SIZE (ARCH_SIZE/8)*2
1673 struct elf_aarch64_local_symbol
1675 unsigned int got_type;
1676 bfd_signed_vma got_refcount;
1677 bfd_vma got_offset;
1679 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
1680 offset is from the end of the jump table and reserved entries
1681 within the PLTGOT.
1683 The magic value (bfd_vma) -1 indicates that an offset has not be
1684 allocated. */
1685 bfd_vma tlsdesc_got_jump_table_offset;
1688 struct elf_aarch64_obj_tdata
1690 struct elf_obj_tdata root;
1692 /* local symbol descriptors */
1693 struct elf_aarch64_local_symbol *locals;
1695 /* Zero to warn when linking objects with incompatible enum sizes. */
1696 int no_enum_size_warning;
1698 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
1699 int no_wchar_size_warning;
1702 #define elf_aarch64_tdata(bfd) \
1703 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
1705 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
1707 #define is_aarch64_elf(bfd) \
1708 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
1709 && elf_tdata (bfd) != NULL \
1710 && elf_object_id (bfd) == AARCH64_ELF_DATA)
1712 static bfd_boolean
1713 elfNN_aarch64_mkobject (bfd *abfd)
1715 return bfd_elf_allocate_object (abfd, sizeof (struct elf_aarch64_obj_tdata),
1716 AARCH64_ELF_DATA);
1719 #define elf_aarch64_hash_entry(ent) \
1720 ((struct elf_aarch64_link_hash_entry *)(ent))
1722 #define GOT_UNKNOWN 0
1723 #define GOT_NORMAL 1
1724 #define GOT_TLS_GD 2
1725 #define GOT_TLS_IE 4
1726 #define GOT_TLSDESC_GD 8
1728 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
1730 /* AArch64 ELF linker hash entry. */
1731 struct elf_aarch64_link_hash_entry
1733 struct elf_link_hash_entry root;
1735 /* Track dynamic relocs copied for this symbol. */
1736 struct elf_dyn_relocs *dyn_relocs;
1738 /* Since PLT entries have variable size, we need to record the
1739 index into .got.plt instead of recomputing it from the PLT
1740 offset. */
1741 bfd_signed_vma plt_got_offset;
1743 /* Bit mask representing the type of GOT entry(s) if any required by
1744 this symbol. */
1745 unsigned int got_type;
1747 /* A pointer to the most recently used stub hash entry against this
1748 symbol. */
1749 struct elf_aarch64_stub_hash_entry *stub_cache;
1751 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
1752 is from the end of the jump table and reserved entries within the PLTGOT.
1754 The magic value (bfd_vma) -1 indicates that an offset has not
1755 be allocated. */
1756 bfd_vma tlsdesc_got_jump_table_offset;
1759 static unsigned int
1760 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry *h,
1761 bfd *abfd,
1762 unsigned long r_symndx)
1764 if (h)
1765 return elf_aarch64_hash_entry (h)->got_type;
1767 if (! elf_aarch64_locals (abfd))
1768 return GOT_UNKNOWN;
1770 return elf_aarch64_locals (abfd)[r_symndx].got_type;
1773 /* Get the AArch64 elf linker hash table from a link_info structure. */
1774 #define elf_aarch64_hash_table(info) \
1775 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
1777 #define aarch64_stub_hash_lookup(table, string, create, copy) \
1778 ((struct elf_aarch64_stub_hash_entry *) \
1779 bfd_hash_lookup ((table), (string), (create), (copy)))
1781 /* AArch64 ELF linker hash table. */
1782 struct elf_aarch64_link_hash_table
1784 /* The main hash table. */
1785 struct elf_link_hash_table root;
1787 /* Nonzero to force PIC branch veneers. */
1788 int pic_veneer;
1790 /* The number of bytes in the initial entry in the PLT. */
1791 bfd_size_type plt_header_size;
1793 /* The number of bytes in the subsequent PLT etries. */
1794 bfd_size_type plt_entry_size;
1796 /* Short-cuts to get to dynamic linker sections. */
1797 asection *sdynbss;
1798 asection *srelbss;
1800 /* Small local sym cache. */
1801 struct sym_cache sym_cache;
1803 /* For convenience in allocate_dynrelocs. */
1804 bfd *obfd;
1806 /* The amount of space used by the reserved portion of the sgotplt
1807 section, plus whatever space is used by the jump slots. */
1808 bfd_vma sgotplt_jump_table_size;
1810 /* The stub hash table. */
1811 struct bfd_hash_table stub_hash_table;
1813 /* Linker stub bfd. */
1814 bfd *stub_bfd;
1816 /* Linker call-backs. */
1817 asection *(*add_stub_section) (const char *, asection *);
1818 void (*layout_sections_again) (void);
1820 /* Array to keep track of which stub sections have been created, and
1821 information on stub grouping. */
1822 struct map_stub
1824 /* This is the section to which stubs in the group will be
1825 attached. */
1826 asection *link_sec;
1827 /* The stub section. */
1828 asection *stub_sec;
1829 } *stub_group;
1831 /* Assorted information used by elfNN_aarch64_size_stubs. */
1832 unsigned int bfd_count;
1833 int top_index;
1834 asection **input_list;
1836 /* The offset into splt of the PLT entry for the TLS descriptor
1837 resolver. Special values are 0, if not necessary (or not found
1838 to be necessary yet), and -1 if needed but not determined
1839 yet. */
1840 bfd_vma tlsdesc_plt;
1842 /* The GOT offset for the lazy trampoline. Communicated to the
1843 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
1844 indicates an offset is not allocated. */
1845 bfd_vma dt_tlsdesc_got;
1847 /* Used by local STT_GNU_IFUNC symbols. */
1848 htab_t loc_hash_table;
1849 void * loc_hash_memory;
1852 /* Create an entry in an AArch64 ELF linker hash table. */
1854 static struct bfd_hash_entry *
1855 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
1856 struct bfd_hash_table *table,
1857 const char *string)
1859 struct elf_aarch64_link_hash_entry *ret =
1860 (struct elf_aarch64_link_hash_entry *) entry;
1862 /* Allocate the structure if it has not already been allocated by a
1863 subclass. */
1864 if (ret == NULL)
1865 ret = bfd_hash_allocate (table,
1866 sizeof (struct elf_aarch64_link_hash_entry));
1867 if (ret == NULL)
1868 return (struct bfd_hash_entry *) ret;
1870 /* Call the allocation method of the superclass. */
1871 ret = ((struct elf_aarch64_link_hash_entry *)
1872 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1873 table, string));
1874 if (ret != NULL)
1876 ret->dyn_relocs = NULL;
1877 ret->got_type = GOT_UNKNOWN;
1878 ret->plt_got_offset = (bfd_vma) - 1;
1879 ret->stub_cache = NULL;
1880 ret->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
1883 return (struct bfd_hash_entry *) ret;
1886 /* Initialize an entry in the stub hash table. */
1888 static struct bfd_hash_entry *
1889 stub_hash_newfunc (struct bfd_hash_entry *entry,
1890 struct bfd_hash_table *table, const char *string)
1892 /* Allocate the structure if it has not already been allocated by a
1893 subclass. */
1894 if (entry == NULL)
1896 entry = bfd_hash_allocate (table,
1897 sizeof (struct
1898 elf_aarch64_stub_hash_entry));
1899 if (entry == NULL)
1900 return entry;
1903 /* Call the allocation method of the superclass. */
1904 entry = bfd_hash_newfunc (entry, table, string);
1905 if (entry != NULL)
1907 struct elf_aarch64_stub_hash_entry *eh;
1909 /* Initialize the local fields. */
1910 eh = (struct elf_aarch64_stub_hash_entry *) entry;
1911 eh->stub_sec = NULL;
1912 eh->stub_offset = 0;
1913 eh->target_value = 0;
1914 eh->target_section = NULL;
1915 eh->stub_type = aarch64_stub_none;
1916 eh->h = NULL;
1917 eh->id_sec = NULL;
1920 return entry;
1923 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
1924 for local symbol so that we can handle local STT_GNU_IFUNC symbols
1925 as global symbol. We reuse indx and dynstr_index for local symbol
1926 hash since they aren't used by global symbols in this backend. */
1928 static hashval_t
1929 elfNN_aarch64_local_htab_hash (const void *ptr)
1931 struct elf_link_hash_entry *h
1932 = (struct elf_link_hash_entry *) ptr;
1933 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
1936 /* Compare local hash entries. */
1938 static int
1939 elfNN_aarch64_local_htab_eq (const void *ptr1, const void *ptr2)
1941 struct elf_link_hash_entry *h1
1942 = (struct elf_link_hash_entry *) ptr1;
1943 struct elf_link_hash_entry *h2
1944 = (struct elf_link_hash_entry *) ptr2;
1946 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
1949 /* Find and/or create a hash entry for local symbol. */
1951 static struct elf_link_hash_entry *
1952 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table *htab,
1953 bfd *abfd, const Elf_Internal_Rela *rel,
1954 bfd_boolean create)
1956 struct elf_aarch64_link_hash_entry e, *ret;
1957 asection *sec = abfd->sections;
1958 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
1959 ELFNN_R_SYM (rel->r_info));
1960 void **slot;
1962 e.root.indx = sec->id;
1963 e.root.dynstr_index = ELFNN_R_SYM (rel->r_info);
1964 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
1965 create ? INSERT : NO_INSERT);
1967 if (!slot)
1968 return NULL;
1970 if (*slot)
1972 ret = (struct elf_aarch64_link_hash_entry *) *slot;
1973 return &ret->root;
1976 ret = (struct elf_aarch64_link_hash_entry *)
1977 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
1978 sizeof (struct elf_aarch64_link_hash_entry));
1979 if (ret)
1981 memset (ret, 0, sizeof (*ret));
1982 ret->root.indx = sec->id;
1983 ret->root.dynstr_index = ELFNN_R_SYM (rel->r_info);
1984 ret->root.dynindx = -1;
1985 *slot = ret;
1987 return &ret->root;
1990 /* Copy the extra info we tack onto an elf_link_hash_entry. */
1992 static void
1993 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
1994 struct elf_link_hash_entry *dir,
1995 struct elf_link_hash_entry *ind)
1997 struct elf_aarch64_link_hash_entry *edir, *eind;
1999 edir = (struct elf_aarch64_link_hash_entry *) dir;
2000 eind = (struct elf_aarch64_link_hash_entry *) ind;
2002 if (eind->dyn_relocs != NULL)
2004 if (edir->dyn_relocs != NULL)
2006 struct elf_dyn_relocs **pp;
2007 struct elf_dyn_relocs *p;
2009 /* Add reloc counts against the indirect sym to the direct sym
2010 list. Merge any entries against the same section. */
2011 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
2013 struct elf_dyn_relocs *q;
2015 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2016 if (q->sec == p->sec)
2018 q->pc_count += p->pc_count;
2019 q->count += p->count;
2020 *pp = p->next;
2021 break;
2023 if (q == NULL)
2024 pp = &p->next;
2026 *pp = edir->dyn_relocs;
2029 edir->dyn_relocs = eind->dyn_relocs;
2030 eind->dyn_relocs = NULL;
2033 if (ind->root.type == bfd_link_hash_indirect)
2035 /* Copy over PLT info. */
2036 if (dir->got.refcount <= 0)
2038 edir->got_type = eind->got_type;
2039 eind->got_type = GOT_UNKNOWN;
2043 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2046 /* Create an AArch64 elf linker hash table. */
2048 static struct bfd_link_hash_table *
2049 elfNN_aarch64_link_hash_table_create (bfd *abfd)
2051 struct elf_aarch64_link_hash_table *ret;
2052 bfd_size_type amt = sizeof (struct elf_aarch64_link_hash_table);
2054 ret = bfd_zmalloc (amt);
2055 if (ret == NULL)
2056 return NULL;
2058 if (!_bfd_elf_link_hash_table_init
2059 (&ret->root, abfd, elfNN_aarch64_link_hash_newfunc,
2060 sizeof (struct elf_aarch64_link_hash_entry), AARCH64_ELF_DATA))
2062 free (ret);
2063 return NULL;
2066 ret->plt_header_size = PLT_ENTRY_SIZE;
2067 ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
2068 ret->obfd = abfd;
2069 ret->dt_tlsdesc_got = (bfd_vma) - 1;
2071 if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
2072 sizeof (struct elf_aarch64_stub_hash_entry)))
2074 free (ret);
2075 return NULL;
2078 ret->loc_hash_table = htab_try_create (1024,
2079 elfNN_aarch64_local_htab_hash,
2080 elfNN_aarch64_local_htab_eq,
2081 NULL);
2082 ret->loc_hash_memory = objalloc_create ();
2083 if (!ret->loc_hash_table || !ret->loc_hash_memory)
2085 free (ret);
2086 return NULL;
2089 return &ret->root.root;
2092 /* Free the derived linker hash table. */
2094 static void
2095 elfNN_aarch64_hash_table_free (struct bfd_link_hash_table *hash)
2097 struct elf_aarch64_link_hash_table *ret
2098 = (struct elf_aarch64_link_hash_table *) hash;
2100 if (ret->loc_hash_table)
2101 htab_delete (ret->loc_hash_table);
2102 if (ret->loc_hash_memory)
2103 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
2105 bfd_hash_table_free (&ret->stub_hash_table);
2106 _bfd_elf_link_hash_table_free (hash);
2109 static bfd_boolean
2110 aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
2111 bfd_vma offset, bfd_vma value)
2113 reloc_howto_type *howto;
2114 bfd_vma place;
2116 howto = elfNN_aarch64_howto_from_type (r_type);
2117 place = (input_section->output_section->vma + input_section->output_offset
2118 + offset);
2120 r_type = elfNN_aarch64_bfd_reloc_from_type (r_type);
2121 value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE);
2122 return _bfd_aarch64_elf_put_addend (input_bfd,
2123 input_section->contents + offset, r_type,
2124 howto, value);
2127 static enum elf_aarch64_stub_type
2128 aarch64_select_branch_stub (bfd_vma value, bfd_vma place)
2130 if (aarch64_valid_for_adrp_p (value, place))
2131 return aarch64_stub_adrp_branch;
2132 return aarch64_stub_long_branch;
2135 /* Determine the type of stub needed, if any, for a call. */
2137 static enum elf_aarch64_stub_type
2138 aarch64_type_of_stub (struct bfd_link_info *info,
2139 asection *input_sec,
2140 const Elf_Internal_Rela *rel,
2141 unsigned char st_type,
2142 struct elf_aarch64_link_hash_entry *hash,
2143 bfd_vma destination)
2145 bfd_vma location;
2146 bfd_signed_vma branch_offset;
2147 unsigned int r_type;
2148 struct elf_aarch64_link_hash_table *globals;
2149 enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
2150 bfd_boolean via_plt_p;
2152 if (st_type != STT_FUNC)
2153 return stub_type;
2155 globals = elf_aarch64_hash_table (info);
2156 via_plt_p = (globals->root.splt != NULL && hash != NULL
2157 && hash->root.plt.offset != (bfd_vma) - 1);
2159 if (via_plt_p)
2160 return stub_type;
2162 /* Determine where the call point is. */
2163 location = (input_sec->output_offset
2164 + input_sec->output_section->vma + rel->r_offset);
2166 branch_offset = (bfd_signed_vma) (destination - location);
2168 r_type = ELFNN_R_TYPE (rel->r_info);
2170 /* We don't want to redirect any old unconditional jump in this way,
2171 only one which is being used for a sibcall, where it is
2172 acceptable for the IP0 and IP1 registers to be clobbered. */
2173 if ((r_type == AARCH64_R (CALL26) || r_type == AARCH64_R (JUMP26))
2174 && (branch_offset > AARCH64_MAX_FWD_BRANCH_OFFSET
2175 || branch_offset < AARCH64_MAX_BWD_BRANCH_OFFSET))
2177 stub_type = aarch64_stub_long_branch;
2180 return stub_type;
2183 /* Build a name for an entry in the stub hash table. */
2185 static char *
2186 elfNN_aarch64_stub_name (const asection *input_section,
2187 const asection *sym_sec,
2188 const struct elf_aarch64_link_hash_entry *hash,
2189 const Elf_Internal_Rela *rel)
2191 char *stub_name;
2192 bfd_size_type len;
2194 if (hash)
2196 len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
2197 stub_name = bfd_malloc (len);
2198 if (stub_name != NULL)
2199 snprintf (stub_name, len, "%08x_%s+%" BFD_VMA_FMT "x",
2200 (unsigned int) input_section->id,
2201 hash->root.root.root.string,
2202 rel->r_addend);
2204 else
2206 len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2207 stub_name = bfd_malloc (len);
2208 if (stub_name != NULL)
2209 snprintf (stub_name, len, "%08x_%x:%x+%" BFD_VMA_FMT "x",
2210 (unsigned int) input_section->id,
2211 (unsigned int) sym_sec->id,
2212 (unsigned int) ELFNN_R_SYM (rel->r_info),
2213 rel->r_addend);
2216 return stub_name;
2219 /* Look up an entry in the stub hash. Stub entries are cached because
2220 creating the stub name takes a bit of time. */
2222 static struct elf_aarch64_stub_hash_entry *
2223 elfNN_aarch64_get_stub_entry (const asection *input_section,
2224 const asection *sym_sec,
2225 struct elf_link_hash_entry *hash,
2226 const Elf_Internal_Rela *rel,
2227 struct elf_aarch64_link_hash_table *htab)
2229 struct elf_aarch64_stub_hash_entry *stub_entry;
2230 struct elf_aarch64_link_hash_entry *h =
2231 (struct elf_aarch64_link_hash_entry *) hash;
2232 const asection *id_sec;
2234 if ((input_section->flags & SEC_CODE) == 0)
2235 return NULL;
2237 /* If this input section is part of a group of sections sharing one
2238 stub section, then use the id of the first section in the group.
2239 Stub names need to include a section id, as there may well be
2240 more than one stub used to reach say, printf, and we need to
2241 distinguish between them. */
2242 id_sec = htab->stub_group[input_section->id].link_sec;
2244 if (h != NULL && h->stub_cache != NULL
2245 && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
2247 stub_entry = h->stub_cache;
2249 else
2251 char *stub_name;
2253 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, h, rel);
2254 if (stub_name == NULL)
2255 return NULL;
2257 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
2258 stub_name, FALSE, FALSE);
2259 if (h != NULL)
2260 h->stub_cache = stub_entry;
2262 free (stub_name);
2265 return stub_entry;
2268 /* Add a new stub entry to the stub hash. Not all fields of the new
2269 stub entry are initialised. */
2271 static struct elf_aarch64_stub_hash_entry *
2272 elfNN_aarch64_add_stub (const char *stub_name,
2273 asection *section,
2274 struct elf_aarch64_link_hash_table *htab)
2276 asection *link_sec;
2277 asection *stub_sec;
2278 struct elf_aarch64_stub_hash_entry *stub_entry;
2280 link_sec = htab->stub_group[section->id].link_sec;
2281 stub_sec = htab->stub_group[section->id].stub_sec;
2282 if (stub_sec == NULL)
2284 stub_sec = htab->stub_group[link_sec->id].stub_sec;
2285 if (stub_sec == NULL)
2287 size_t namelen;
2288 bfd_size_type len;
2289 char *s_name;
2291 namelen = strlen (link_sec->name);
2292 len = namelen + sizeof (STUB_SUFFIX);
2293 s_name = bfd_alloc (htab->stub_bfd, len);
2294 if (s_name == NULL)
2295 return NULL;
2297 memcpy (s_name, link_sec->name, namelen);
2298 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
2299 stub_sec = (*htab->add_stub_section) (s_name, link_sec);
2300 if (stub_sec == NULL)
2301 return NULL;
2302 htab->stub_group[link_sec->id].stub_sec = stub_sec;
2304 htab->stub_group[section->id].stub_sec = stub_sec;
2307 /* Enter this entry into the linker stub hash table. */
2308 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
2309 TRUE, FALSE);
2310 if (stub_entry == NULL)
2312 (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
2313 section->owner, stub_name);
2314 return NULL;
2317 stub_entry->stub_sec = stub_sec;
2318 stub_entry->stub_offset = 0;
2319 stub_entry->id_sec = link_sec;
2321 return stub_entry;
2324 static bfd_boolean
2325 aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
2326 void *in_arg ATTRIBUTE_UNUSED)
2328 struct elf_aarch64_stub_hash_entry *stub_entry;
2329 asection *stub_sec;
2330 bfd *stub_bfd;
2331 bfd_byte *loc;
2332 bfd_vma sym_value;
2333 unsigned int template_size;
2334 const uint32_t *template;
2335 unsigned int i;
2337 /* Massage our args to the form they really have. */
2338 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
2340 stub_sec = stub_entry->stub_sec;
2342 /* Make a note of the offset within the stubs for this entry. */
2343 stub_entry->stub_offset = stub_sec->size;
2344 loc = stub_sec->contents + stub_entry->stub_offset;
2346 stub_bfd = stub_sec->owner;
2348 /* This is the address of the stub destination. */
2349 sym_value = (stub_entry->target_value
2350 + stub_entry->target_section->output_offset
2351 + stub_entry->target_section->output_section->vma);
2353 if (stub_entry->stub_type == aarch64_stub_long_branch)
2355 bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
2356 + stub_sec->output_offset);
2358 /* See if we can relax the stub. */
2359 if (aarch64_valid_for_adrp_p (sym_value, place))
2360 stub_entry->stub_type = aarch64_select_branch_stub (sym_value, place);
2363 switch (stub_entry->stub_type)
2365 case aarch64_stub_adrp_branch:
2366 template = aarch64_adrp_branch_stub;
2367 template_size = sizeof (aarch64_adrp_branch_stub);
2368 break;
2369 case aarch64_stub_long_branch:
2370 template = aarch64_long_branch_stub;
2371 template_size = sizeof (aarch64_long_branch_stub);
2372 break;
2373 default:
2374 BFD_FAIL ();
2375 return FALSE;
2378 for (i = 0; i < (template_size / sizeof template[0]); i++)
2380 bfd_putl32 (template[i], loc);
2381 loc += 4;
2384 template_size = (template_size + 7) & ~7;
2385 stub_sec->size += template_size;
2387 switch (stub_entry->stub_type)
2389 case aarch64_stub_adrp_branch:
2390 if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
2391 stub_entry->stub_offset, sym_value))
2392 /* The stub would not have been relaxed if the offset was out
2393 of range. */
2394 BFD_FAIL ();
2396 _bfd_final_link_relocate
2397 (elfNN_aarch64_howto_from_type (AARCH64_R (ADD_ABS_LO12_NC)),
2398 stub_bfd,
2399 stub_sec,
2400 stub_sec->contents,
2401 stub_entry->stub_offset + 4,
2402 sym_value,
2404 break;
2406 case aarch64_stub_long_branch:
2407 /* We want the value relative to the address 12 bytes back from the
2408 value itself. */
2409 _bfd_final_link_relocate (elfNN_aarch64_howto_from_type
2410 (AARCH64_R (PRELNN)), stub_bfd, stub_sec,
2411 stub_sec->contents,
2412 stub_entry->stub_offset + 16,
2413 sym_value + 12, 0);
2414 break;
2415 default:
2416 break;
2419 return TRUE;
2422 /* As above, but don't actually build the stub. Just bump offset so
2423 we know stub section sizes. */
2425 static bfd_boolean
2426 aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
2427 void *in_arg ATTRIBUTE_UNUSED)
2429 struct elf_aarch64_stub_hash_entry *stub_entry;
2430 int size;
2432 /* Massage our args to the form they really have. */
2433 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
2435 switch (stub_entry->stub_type)
2437 case aarch64_stub_adrp_branch:
2438 size = sizeof (aarch64_adrp_branch_stub);
2439 break;
2440 case aarch64_stub_long_branch:
2441 size = sizeof (aarch64_long_branch_stub);
2442 break;
2443 default:
2444 BFD_FAIL ();
2445 return FALSE;
2446 break;
2449 size = (size + 7) & ~7;
2450 stub_entry->stub_sec->size += size;
2451 return TRUE;
2454 /* External entry points for sizing and building linker stubs. */
2456 /* Set up various things so that we can make a list of input sections
2457 for each output section included in the link. Returns -1 on error,
2458 0 when no stubs will be needed, and 1 on success. */
2461 elfNN_aarch64_setup_section_lists (bfd *output_bfd,
2462 struct bfd_link_info *info)
2464 bfd *input_bfd;
2465 unsigned int bfd_count;
2466 int top_id, top_index;
2467 asection *section;
2468 asection **input_list, **list;
2469 bfd_size_type amt;
2470 struct elf_aarch64_link_hash_table *htab =
2471 elf_aarch64_hash_table (info);
2473 if (!is_elf_hash_table (htab))
2474 return 0;
2476 /* Count the number of input BFDs and find the top input section id. */
2477 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
2478 input_bfd != NULL; input_bfd = input_bfd->link_next)
2480 bfd_count += 1;
2481 for (section = input_bfd->sections;
2482 section != NULL; section = section->next)
2484 if (top_id < section->id)
2485 top_id = section->id;
2488 htab->bfd_count = bfd_count;
2490 amt = sizeof (struct map_stub) * (top_id + 1);
2491 htab->stub_group = bfd_zmalloc (amt);
2492 if (htab->stub_group == NULL)
2493 return -1;
2495 /* We can't use output_bfd->section_count here to find the top output
2496 section index as some sections may have been removed, and
2497 _bfd_strip_section_from_output doesn't renumber the indices. */
2498 for (section = output_bfd->sections, top_index = 0;
2499 section != NULL; section = section->next)
2501 if (top_index < section->index)
2502 top_index = section->index;
2505 htab->top_index = top_index;
2506 amt = sizeof (asection *) * (top_index + 1);
2507 input_list = bfd_malloc (amt);
2508 htab->input_list = input_list;
2509 if (input_list == NULL)
2510 return -1;
2512 /* For sections we aren't interested in, mark their entries with a
2513 value we can check later. */
2514 list = input_list + top_index;
2516 *list = bfd_abs_section_ptr;
2517 while (list-- != input_list);
2519 for (section = output_bfd->sections;
2520 section != NULL; section = section->next)
2522 if ((section->flags & SEC_CODE) != 0)
2523 input_list[section->index] = NULL;
2526 return 1;
2529 /* Used by elfNN_aarch64_next_input_section and group_sections. */
2530 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
2532 /* The linker repeatedly calls this function for each input section,
2533 in the order that input sections are linked into output sections.
2534 Build lists of input sections to determine groupings between which
2535 we may insert linker stubs. */
2537 void
2538 elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec)
2540 struct elf_aarch64_link_hash_table *htab =
2541 elf_aarch64_hash_table (info);
2543 if (isec->output_section->index <= htab->top_index)
2545 asection **list = htab->input_list + isec->output_section->index;
2547 if (*list != bfd_abs_section_ptr)
2549 /* Steal the link_sec pointer for our list. */
2550 /* This happens to make the list in reverse order,
2551 which is what we want. */
2552 PREV_SEC (isec) = *list;
2553 *list = isec;
2558 /* See whether we can group stub sections together. Grouping stub
2559 sections may result in fewer stubs. More importantly, we need to
2560 put all .init* and .fini* stubs at the beginning of the .init or
2561 .fini output sections respectively, because glibc splits the
2562 _init and _fini functions into multiple parts. Putting a stub in
2563 the middle of a function is not a good idea. */
2565 static void
2566 group_sections (struct elf_aarch64_link_hash_table *htab,
2567 bfd_size_type stub_group_size,
2568 bfd_boolean stubs_always_before_branch)
2570 asection **list = htab->input_list + htab->top_index;
2574 asection *tail = *list;
2576 if (tail == bfd_abs_section_ptr)
2577 continue;
2579 while (tail != NULL)
2581 asection *curr;
2582 asection *prev;
2583 bfd_size_type total;
2585 curr = tail;
2586 total = tail->size;
2587 while ((prev = PREV_SEC (curr)) != NULL
2588 && ((total += curr->output_offset - prev->output_offset)
2589 < stub_group_size))
2590 curr = prev;
2592 /* OK, the size from the start of CURR to the end is less
2593 than stub_group_size and thus can be handled by one stub
2594 section. (Or the tail section is itself larger than
2595 stub_group_size, in which case we may be toast.)
2596 We should really be keeping track of the total size of
2597 stubs added here, as stubs contribute to the final output
2598 section size. */
2601 prev = PREV_SEC (tail);
2602 /* Set up this stub group. */
2603 htab->stub_group[tail->id].link_sec = curr;
2605 while (tail != curr && (tail = prev) != NULL);
2607 /* But wait, there's more! Input sections up to stub_group_size
2608 bytes before the stub section can be handled by it too. */
2609 if (!stubs_always_before_branch)
2611 total = 0;
2612 while (prev != NULL
2613 && ((total += tail->output_offset - prev->output_offset)
2614 < stub_group_size))
2616 tail = prev;
2617 prev = PREV_SEC (tail);
2618 htab->stub_group[tail->id].link_sec = curr;
2621 tail = prev;
2624 while (list-- != htab->input_list);
2626 free (htab->input_list);
2629 #undef PREV_SEC
2631 /* Determine and set the size of the stub section for a final link.
2633 The basic idea here is to examine all the relocations looking for
2634 PC-relative calls to a target that is unreachable with a "bl"
2635 instruction. */
2637 bfd_boolean
2638 elfNN_aarch64_size_stubs (bfd *output_bfd,
2639 bfd *stub_bfd,
2640 struct bfd_link_info *info,
2641 bfd_signed_vma group_size,
2642 asection * (*add_stub_section) (const char *,
2643 asection *),
2644 void (*layout_sections_again) (void))
2646 bfd_size_type stub_group_size;
2647 bfd_boolean stubs_always_before_branch;
2648 bfd_boolean stub_changed = 0;
2649 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
2651 /* Propagate mach to stub bfd, because it may not have been
2652 finalized when we created stub_bfd. */
2653 bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
2654 bfd_get_mach (output_bfd));
2656 /* Stash our params away. */
2657 htab->stub_bfd = stub_bfd;
2658 htab->add_stub_section = add_stub_section;
2659 htab->layout_sections_again = layout_sections_again;
2660 stubs_always_before_branch = group_size < 0;
2661 if (group_size < 0)
2662 stub_group_size = -group_size;
2663 else
2664 stub_group_size = group_size;
2666 if (stub_group_size == 1)
2668 /* Default values. */
2669 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
2670 stub_group_size = 127 * 1024 * 1024;
2673 group_sections (htab, stub_group_size, stubs_always_before_branch);
2675 while (1)
2677 bfd *input_bfd;
2678 unsigned int bfd_indx;
2679 asection *stub_sec;
2681 for (input_bfd = info->input_bfds, bfd_indx = 0;
2682 input_bfd != NULL; input_bfd = input_bfd->link_next, bfd_indx++)
2684 Elf_Internal_Shdr *symtab_hdr;
2685 asection *section;
2686 Elf_Internal_Sym *local_syms = NULL;
2688 /* We'll need the symbol table in a second. */
2689 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2690 if (symtab_hdr->sh_info == 0)
2691 continue;
2693 /* Walk over each section attached to the input bfd. */
2694 for (section = input_bfd->sections;
2695 section != NULL; section = section->next)
2697 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
2699 /* If there aren't any relocs, then there's nothing more
2700 to do. */
2701 if ((section->flags & SEC_RELOC) == 0
2702 || section->reloc_count == 0
2703 || (section->flags & SEC_CODE) == 0)
2704 continue;
2706 /* If this section is a link-once section that will be
2707 discarded, then don't create any stubs. */
2708 if (section->output_section == NULL
2709 || section->output_section->owner != output_bfd)
2710 continue;
2712 /* Get the relocs. */
2713 internal_relocs
2714 = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
2715 NULL, info->keep_memory);
2716 if (internal_relocs == NULL)
2717 goto error_ret_free_local;
2719 /* Now examine each relocation. */
2720 irela = internal_relocs;
2721 irelaend = irela + section->reloc_count;
2722 for (; irela < irelaend; irela++)
2724 unsigned int r_type, r_indx;
2725 enum elf_aarch64_stub_type stub_type;
2726 struct elf_aarch64_stub_hash_entry *stub_entry;
2727 asection *sym_sec;
2728 bfd_vma sym_value;
2729 bfd_vma destination;
2730 struct elf_aarch64_link_hash_entry *hash;
2731 const char *sym_name;
2732 char *stub_name;
2733 const asection *id_sec;
2734 unsigned char st_type;
2735 bfd_size_type len;
2737 r_type = ELFNN_R_TYPE (irela->r_info);
2738 r_indx = ELFNN_R_SYM (irela->r_info);
2740 if (r_type >= (unsigned int) R_AARCH64_end)
2742 bfd_set_error (bfd_error_bad_value);
2743 error_ret_free_internal:
2744 if (elf_section_data (section)->relocs == NULL)
2745 free (internal_relocs);
2746 goto error_ret_free_local;
2749 /* Only look for stubs on unconditional branch and
2750 branch and link instructions. */
2751 if (r_type != (unsigned int) AARCH64_R (CALL26)
2752 && r_type != (unsigned int) AARCH64_R (JUMP26))
2753 continue;
2755 /* Now determine the call target, its name, value,
2756 section. */
2757 sym_sec = NULL;
2758 sym_value = 0;
2759 destination = 0;
2760 hash = NULL;
2761 sym_name = NULL;
2762 if (r_indx < symtab_hdr->sh_info)
2764 /* It's a local symbol. */
2765 Elf_Internal_Sym *sym;
2766 Elf_Internal_Shdr *hdr;
2768 if (local_syms == NULL)
2770 local_syms
2771 = (Elf_Internal_Sym *) symtab_hdr->contents;
2772 if (local_syms == NULL)
2773 local_syms
2774 = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
2775 symtab_hdr->sh_info, 0,
2776 NULL, NULL, NULL);
2777 if (local_syms == NULL)
2778 goto error_ret_free_internal;
2781 sym = local_syms + r_indx;
2782 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
2783 sym_sec = hdr->bfd_section;
2784 if (!sym_sec)
2785 /* This is an undefined symbol. It can never
2786 be resolved. */
2787 continue;
2789 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
2790 sym_value = sym->st_value;
2791 destination = (sym_value + irela->r_addend
2792 + sym_sec->output_offset
2793 + sym_sec->output_section->vma);
2794 st_type = ELF_ST_TYPE (sym->st_info);
2795 sym_name
2796 = bfd_elf_string_from_elf_section (input_bfd,
2797 symtab_hdr->sh_link,
2798 sym->st_name);
2800 else
2802 int e_indx;
2804 e_indx = r_indx - symtab_hdr->sh_info;
2805 hash = ((struct elf_aarch64_link_hash_entry *)
2806 elf_sym_hashes (input_bfd)[e_indx]);
2808 while (hash->root.root.type == bfd_link_hash_indirect
2809 || hash->root.root.type == bfd_link_hash_warning)
2810 hash = ((struct elf_aarch64_link_hash_entry *)
2811 hash->root.root.u.i.link);
2813 if (hash->root.root.type == bfd_link_hash_defined
2814 || hash->root.root.type == bfd_link_hash_defweak)
2816 struct elf_aarch64_link_hash_table *globals =
2817 elf_aarch64_hash_table (info);
2818 sym_sec = hash->root.root.u.def.section;
2819 sym_value = hash->root.root.u.def.value;
2820 /* For a destination in a shared library,
2821 use the PLT stub as target address to
2822 decide whether a branch stub is
2823 needed. */
2824 if (globals->root.splt != NULL && hash != NULL
2825 && hash->root.plt.offset != (bfd_vma) - 1)
2827 sym_sec = globals->root.splt;
2828 sym_value = hash->root.plt.offset;
2829 if (sym_sec->output_section != NULL)
2830 destination = (sym_value
2831 + sym_sec->output_offset
2833 sym_sec->output_section->vma);
2835 else if (sym_sec->output_section != NULL)
2836 destination = (sym_value + irela->r_addend
2837 + sym_sec->output_offset
2838 + sym_sec->output_section->vma);
2840 else if (hash->root.root.type == bfd_link_hash_undefined
2841 || (hash->root.root.type
2842 == bfd_link_hash_undefweak))
2844 /* For a shared library, use the PLT stub as
2845 target address to decide whether a long
2846 branch stub is needed.
2847 For absolute code, they cannot be handled. */
2848 struct elf_aarch64_link_hash_table *globals =
2849 elf_aarch64_hash_table (info);
2851 if (globals->root.splt != NULL && hash != NULL
2852 && hash->root.plt.offset != (bfd_vma) - 1)
2854 sym_sec = globals->root.splt;
2855 sym_value = hash->root.plt.offset;
2856 if (sym_sec->output_section != NULL)
2857 destination = (sym_value
2858 + sym_sec->output_offset
2860 sym_sec->output_section->vma);
2862 else
2863 continue;
2865 else
2867 bfd_set_error (bfd_error_bad_value);
2868 goto error_ret_free_internal;
2870 st_type = ELF_ST_TYPE (hash->root.type);
2871 sym_name = hash->root.root.root.string;
2874 /* Determine what (if any) linker stub is needed. */
2875 stub_type = aarch64_type_of_stub
2876 (info, section, irela, st_type, hash, destination);
2877 if (stub_type == aarch64_stub_none)
2878 continue;
2880 /* Support for grouping stub sections. */
2881 id_sec = htab->stub_group[section->id].link_sec;
2883 /* Get the name of this stub. */
2884 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash,
2885 irela);
2886 if (!stub_name)
2887 goto error_ret_free_internal;
2889 stub_entry =
2890 aarch64_stub_hash_lookup (&htab->stub_hash_table,
2891 stub_name, FALSE, FALSE);
2892 if (stub_entry != NULL)
2894 /* The proper stub has already been created. */
2895 free (stub_name);
2896 continue;
2899 stub_entry = elfNN_aarch64_add_stub (stub_name, section,
2900 htab);
2901 if (stub_entry == NULL)
2903 free (stub_name);
2904 goto error_ret_free_internal;
2907 stub_entry->target_value = sym_value;
2908 stub_entry->target_section = sym_sec;
2909 stub_entry->stub_type = stub_type;
2910 stub_entry->h = hash;
2911 stub_entry->st_type = st_type;
2913 if (sym_name == NULL)
2914 sym_name = "unnamed";
2915 len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
2916 stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
2917 if (stub_entry->output_name == NULL)
2919 free (stub_name);
2920 goto error_ret_free_internal;
2923 snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
2924 sym_name);
2926 stub_changed = TRUE;
2929 /* We're done with the internal relocs, free them. */
2930 if (elf_section_data (section)->relocs == NULL)
2931 free (internal_relocs);
2935 if (!stub_changed)
2936 break;
2938 /* OK, we've added some stubs. Find out the new size of the
2939 stub sections. */
2940 for (stub_sec = htab->stub_bfd->sections;
2941 stub_sec != NULL; stub_sec = stub_sec->next)
2942 stub_sec->size = 0;
2944 bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
2946 /* Ask the linker to do its stuff. */
2947 (*htab->layout_sections_again) ();
2948 stub_changed = FALSE;
2951 return TRUE;
2953 error_ret_free_local:
2954 return FALSE;
2957 /* Build all the stubs associated with the current output file. The
2958 stubs are kept in a hash table attached to the main linker hash
2959 table. We also set up the .plt entries for statically linked PIC
2960 functions here. This function is called via aarch64_elf_finish in the
2961 linker. */
2963 bfd_boolean
2964 elfNN_aarch64_build_stubs (struct bfd_link_info *info)
2966 asection *stub_sec;
2967 struct bfd_hash_table *table;
2968 struct elf_aarch64_link_hash_table *htab;
2970 htab = elf_aarch64_hash_table (info);
2972 for (stub_sec = htab->stub_bfd->sections;
2973 stub_sec != NULL; stub_sec = stub_sec->next)
2975 bfd_size_type size;
2977 /* Ignore non-stub sections. */
2978 if (!strstr (stub_sec->name, STUB_SUFFIX))
2979 continue;
2981 /* Allocate memory to hold the linker stubs. */
2982 size = stub_sec->size;
2983 stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
2984 if (stub_sec->contents == NULL && size != 0)
2985 return FALSE;
2986 stub_sec->size = 0;
2989 /* Build the stubs as directed by the stub hash table. */
2990 table = &htab->stub_hash_table;
2991 bfd_hash_traverse (table, aarch64_build_one_stub, info);
2993 return TRUE;
2997 /* Add an entry to the code/data map for section SEC. */
2999 static void
3000 elfNN_aarch64_section_map_add (asection *sec, char type, bfd_vma vma)
3002 struct _aarch64_elf_section_data *sec_data =
3003 elf_aarch64_section_data (sec);
3004 unsigned int newidx;
3006 if (sec_data->map == NULL)
3008 sec_data->map = bfd_malloc (sizeof (elf_aarch64_section_map));
3009 sec_data->mapcount = 0;
3010 sec_data->mapsize = 1;
3013 newidx = sec_data->mapcount++;
3015 if (sec_data->mapcount > sec_data->mapsize)
3017 sec_data->mapsize *= 2;
3018 sec_data->map = bfd_realloc_or_free
3019 (sec_data->map, sec_data->mapsize * sizeof (elf_aarch64_section_map));
3022 if (sec_data->map)
3024 sec_data->map[newidx].vma = vma;
3025 sec_data->map[newidx].type = type;
3030 /* Initialise maps of insn/data for input BFDs. */
3031 void
3032 bfd_elfNN_aarch64_init_maps (bfd *abfd)
3034 Elf_Internal_Sym *isymbuf;
3035 Elf_Internal_Shdr *hdr;
3036 unsigned int i, localsyms;
3038 /* Make sure that we are dealing with an AArch64 elf binary. */
3039 if (!is_aarch64_elf (abfd))
3040 return;
3042 if ((abfd->flags & DYNAMIC) != 0)
3043 return;
3045 hdr = &elf_symtab_hdr (abfd);
3046 localsyms = hdr->sh_info;
3048 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
3049 should contain the number of local symbols, which should come before any
3050 global symbols. Mapping symbols are always local. */
3051 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL);
3053 /* No internal symbols read? Skip this BFD. */
3054 if (isymbuf == NULL)
3055 return;
3057 for (i = 0; i < localsyms; i++)
3059 Elf_Internal_Sym *isym = &isymbuf[i];
3060 asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3061 const char *name;
3063 if (sec != NULL && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
3065 name = bfd_elf_string_from_elf_section (abfd,
3066 hdr->sh_link,
3067 isym->st_name);
3069 if (bfd_is_aarch64_special_symbol_name
3070 (name, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP))
3071 elfNN_aarch64_section_map_add (sec, name[1], isym->st_value);
3076 /* Set option values needed during linking. */
3077 void
3078 bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
3079 struct bfd_link_info *link_info,
3080 int no_enum_warn,
3081 int no_wchar_warn, int pic_veneer)
3083 struct elf_aarch64_link_hash_table *globals;
3085 globals = elf_aarch64_hash_table (link_info);
3086 globals->pic_veneer = pic_veneer;
3088 BFD_ASSERT (is_aarch64_elf (output_bfd));
3089 elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
3090 elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
3093 static bfd_vma
3094 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
3095 struct elf_aarch64_link_hash_table
3096 *globals, struct bfd_link_info *info,
3097 bfd_vma value, bfd *output_bfd,
3098 bfd_boolean *unresolved_reloc_p)
3100 bfd_vma off = (bfd_vma) - 1;
3101 asection *basegot = globals->root.sgot;
3102 bfd_boolean dyn = globals->root.dynamic_sections_created;
3104 if (h != NULL)
3106 BFD_ASSERT (basegot != NULL);
3107 off = h->got.offset;
3108 BFD_ASSERT (off != (bfd_vma) - 1);
3109 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
3110 || (info->shared
3111 && SYMBOL_REFERENCES_LOCAL (info, h))
3112 || (ELF_ST_VISIBILITY (h->other)
3113 && h->root.type == bfd_link_hash_undefweak))
3115 /* This is actually a static link, or it is a -Bsymbolic link
3116 and the symbol is defined locally. We must initialize this
3117 entry in the global offset table. Since the offset must
3118 always be a multiple of 8 (4 in the case of ILP32), we use
3119 the least significant bit to record whether we have
3120 initialized it already.
3121 When doing a dynamic link, we create a .rel(a).got relocation
3122 entry to initialize the value. This is done in the
3123 finish_dynamic_symbol routine. */
3124 if ((off & 1) != 0)
3125 off &= ~1;
3126 else
3128 bfd_put_NN (output_bfd, value, basegot->contents + off);
3129 h->got.offset |= 1;
3132 else
3133 *unresolved_reloc_p = FALSE;
3135 off = off + basegot->output_section->vma + basegot->output_offset;
3138 return off;
3141 /* Change R_TYPE to a more efficient access model where possible,
3142 return the new reloc type. */
3144 static bfd_reloc_code_real_type
3145 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
3146 struct elf_link_hash_entry *h)
3148 bfd_boolean is_local = h == NULL;
3150 switch (r_type)
3152 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3153 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3154 return (is_local
3155 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
3156 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
3158 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3159 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
3160 return (is_local
3161 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
3162 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
3164 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3165 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
3167 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
3168 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
3170 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3171 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3172 /* Instructions with these relocations will become NOPs. */
3173 return BFD_RELOC_AARCH64_NONE;
3175 default:
3176 break;
3179 return r_type;
3182 static unsigned int
3183 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
3185 switch (r_type)
3187 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
3188 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
3189 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
3190 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
3191 return GOT_NORMAL;
3193 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3194 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3195 return GOT_TLS_GD;
3197 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3198 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3199 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3200 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
3201 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
3202 return GOT_TLSDESC_GD;
3204 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3205 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
3206 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
3207 return GOT_TLS_IE;
3209 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
3210 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
3211 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
3212 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
3213 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
3214 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
3215 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
3216 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
3217 return GOT_UNKNOWN;
3219 default:
3220 break;
3222 return GOT_UNKNOWN;
3225 static bfd_boolean
3226 aarch64_can_relax_tls (bfd *input_bfd,
3227 struct bfd_link_info *info,
3228 bfd_reloc_code_real_type r_type,
3229 struct elf_link_hash_entry *h,
3230 unsigned long r_symndx)
3232 unsigned int symbol_got_type;
3233 unsigned int reloc_got_type;
3235 if (! IS_AARCH64_TLS_RELOC (r_type))
3236 return FALSE;
3238 symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
3239 reloc_got_type = aarch64_reloc_got_type (r_type);
3241 if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
3242 return TRUE;
3244 if (info->shared)
3245 return FALSE;
3247 if (h && h->root.type == bfd_link_hash_undefweak)
3248 return FALSE;
3250 return TRUE;
3253 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
3254 enumerator. */
3256 static bfd_reloc_code_real_type
3257 aarch64_tls_transition (bfd *input_bfd,
3258 struct bfd_link_info *info,
3259 unsigned int r_type,
3260 struct elf_link_hash_entry *h,
3261 unsigned long r_symndx)
3263 bfd_reloc_code_real_type bfd_r_type
3264 = elfNN_aarch64_bfd_reloc_from_type (r_type);
3266 if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
3267 return bfd_r_type;
3269 return aarch64_tls_transition_without_check (bfd_r_type, h);
3272 /* Return the base VMA address which should be subtracted from real addresses
3273 when resolving R_AARCH64_TLS_DTPREL relocation. */
3275 static bfd_vma
3276 dtpoff_base (struct bfd_link_info *info)
3278 /* If tls_sec is NULL, we should have signalled an error already. */
3279 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3280 return elf_hash_table (info)->tls_sec->vma;
3283 /* Return the base VMA address which should be subtracted from real addresses
3284 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
3286 static bfd_vma
3287 tpoff_base (struct bfd_link_info *info)
3289 struct elf_link_hash_table *htab = elf_hash_table (info);
3291 /* If tls_sec is NULL, we should have signalled an error already. */
3292 if (htab->tls_sec == NULL)
3293 return 0;
3295 bfd_vma base = align_power ((bfd_vma) TCB_SIZE,
3296 htab->tls_sec->alignment_power);
3297 return htab->tls_sec->vma - base;
3300 static bfd_vma *
3301 symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
3302 unsigned long r_symndx)
3304 /* Calculate the address of the GOT entry for symbol
3305 referred to in h. */
3306 if (h != NULL)
3307 return &h->got.offset;
3308 else
3310 /* local symbol */
3311 struct elf_aarch64_local_symbol *l;
3313 l = elf_aarch64_locals (input_bfd);
3314 return &l[r_symndx].got_offset;
3318 static void
3319 symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
3320 unsigned long r_symndx)
3322 bfd_vma *p;
3323 p = symbol_got_offset_ref (input_bfd, h, r_symndx);
3324 *p |= 1;
3327 static int
3328 symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
3329 unsigned long r_symndx)
3331 bfd_vma value;
3332 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
3333 return value & 1;
3336 static bfd_vma
3337 symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
3338 unsigned long r_symndx)
3340 bfd_vma value;
3341 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
3342 value &= ~1;
3343 return value;
3346 static bfd_vma *
3347 symbol_tlsdesc_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
3348 unsigned long r_symndx)
3350 /* Calculate the address of the GOT entry for symbol
3351 referred to in h. */
3352 if (h != NULL)
3354 struct elf_aarch64_link_hash_entry *eh;
3355 eh = (struct elf_aarch64_link_hash_entry *) h;
3356 return &eh->tlsdesc_got_jump_table_offset;
3358 else
3360 /* local symbol */
3361 struct elf_aarch64_local_symbol *l;
3363 l = elf_aarch64_locals (input_bfd);
3364 return &l[r_symndx].tlsdesc_got_jump_table_offset;
3368 static void
3369 symbol_tlsdesc_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
3370 unsigned long r_symndx)
3372 bfd_vma *p;
3373 p = symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
3374 *p |= 1;
3377 static int
3378 symbol_tlsdesc_got_offset_mark_p (bfd *input_bfd,
3379 struct elf_link_hash_entry *h,
3380 unsigned long r_symndx)
3382 bfd_vma value;
3383 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
3384 return value & 1;
3387 static bfd_vma
3388 symbol_tlsdesc_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
3389 unsigned long r_symndx)
3391 bfd_vma value;
3392 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
3393 value &= ~1;
3394 return value;
3397 /* Perform a relocation as part of a final link. */
3398 static bfd_reloc_status_type
3399 elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
3400 bfd *input_bfd,
3401 bfd *output_bfd,
3402 asection *input_section,
3403 bfd_byte *contents,
3404 Elf_Internal_Rela *rel,
3405 bfd_vma value,
3406 struct bfd_link_info *info,
3407 asection *sym_sec,
3408 struct elf_link_hash_entry *h,
3409 bfd_boolean *unresolved_reloc_p,
3410 bfd_boolean save_addend,
3411 bfd_vma *saved_addend,
3412 Elf_Internal_Sym *sym)
3414 Elf_Internal_Shdr *symtab_hdr;
3415 unsigned int r_type = howto->type;
3416 bfd_reloc_code_real_type bfd_r_type
3417 = elfNN_aarch64_bfd_reloc_from_howto (howto);
3418 bfd_reloc_code_real_type new_bfd_r_type;
3419 unsigned long r_symndx;
3420 bfd_byte *hit_data = contents + rel->r_offset;
3421 bfd_vma place;
3422 bfd_signed_vma signed_addend;
3423 struct elf_aarch64_link_hash_table *globals;
3424 bfd_boolean weak_undef_p;
3426 globals = elf_aarch64_hash_table (info);
3428 symtab_hdr = &elf_symtab_hdr (input_bfd);
3430 BFD_ASSERT (is_aarch64_elf (input_bfd));
3432 r_symndx = ELFNN_R_SYM (rel->r_info);
3434 /* It is possible to have linker relaxations on some TLS access
3435 models. Update our information here. */
3436 new_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, h, r_symndx);
3437 if (new_bfd_r_type != bfd_r_type)
3439 bfd_r_type = new_bfd_r_type;
3440 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
3441 BFD_ASSERT (howto != NULL);
3442 r_type = howto->type;
3445 place = input_section->output_section->vma
3446 + input_section->output_offset + rel->r_offset;
3448 /* Get addend, accumulating the addend for consecutive relocs
3449 which refer to the same offset. */
3450 signed_addend = saved_addend ? *saved_addend : 0;
3451 signed_addend += rel->r_addend;
3453 weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
3454 : bfd_is_und_section (sym_sec));
3456 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
3457 it here if it is defined in a non-shared object. */
3458 if (h != NULL
3459 && h->type == STT_GNU_IFUNC
3460 && h->def_regular)
3462 asection *plt;
3463 const char *name;
3464 asection *base_got;
3465 bfd_vma off;
3467 if ((input_section->flags & SEC_ALLOC) == 0
3468 || h->plt.offset == (bfd_vma) -1)
3469 abort ();
3471 /* STT_GNU_IFUNC symbol must go through PLT. */
3472 plt = globals->root.splt ? globals->root.splt : globals->root.iplt;
3473 value = (plt->output_section->vma + plt->output_offset + h->plt.offset);
3475 switch (bfd_r_type)
3477 default:
3478 if (h->root.root.string)
3479 name = h->root.root.string;
3480 else
3481 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
3482 NULL);
3483 (*_bfd_error_handler)
3484 (_("%B: relocation %s against STT_GNU_IFUNC "
3485 "symbol `%s' isn't handled by %s"), input_bfd,
3486 howto->name, name, __FUNCTION__);
3487 bfd_set_error (bfd_error_bad_value);
3488 return FALSE;
3490 case BFD_RELOC_AARCH64_NN:
3491 if (rel->r_addend != 0)
3493 if (h->root.root.string)
3494 name = h->root.root.string;
3495 else
3496 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
3497 sym, NULL);
3498 (*_bfd_error_handler)
3499 (_("%B: relocation %s against STT_GNU_IFUNC "
3500 "symbol `%s' has non-zero addend: %d"),
3501 input_bfd, howto->name, name, rel->r_addend);
3502 bfd_set_error (bfd_error_bad_value);
3503 return FALSE;
3506 /* Generate dynamic relocation only when there is a
3507 non-GOT reference in a shared object. */
3508 if (info->shared && h->non_got_ref)
3510 Elf_Internal_Rela outrel;
3511 asection *sreloc;
3513 /* Need a dynamic relocation to get the real function
3514 address. */
3515 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
3516 info,
3517 input_section,
3518 rel->r_offset);
3519 if (outrel.r_offset == (bfd_vma) -1
3520 || outrel.r_offset == (bfd_vma) -2)
3521 abort ();
3523 outrel.r_offset += (input_section->output_section->vma
3524 + input_section->output_offset);
3526 if (h->dynindx == -1
3527 || h->forced_local
3528 || info->executable)
3530 /* This symbol is resolved locally. */
3531 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
3532 outrel.r_addend = (h->root.u.def.value
3533 + h->root.u.def.section->output_section->vma
3534 + h->root.u.def.section->output_offset);
3536 else
3538 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
3539 outrel.r_addend = 0;
3542 sreloc = globals->root.irelifunc;
3543 elf_append_rela (output_bfd, sreloc, &outrel);
3545 /* If this reloc is against an external symbol, we
3546 do not want to fiddle with the addend. Otherwise,
3547 we need to include the symbol value so that it
3548 becomes an addend for the dynamic reloc. For an
3549 internal symbol, we have updated addend. */
3550 return bfd_reloc_ok;
3552 /* FALLTHROUGH */
3553 case BFD_RELOC_AARCH64_JUMP26:
3554 case BFD_RELOC_AARCH64_CALL26:
3555 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3556 signed_addend,
3557 weak_undef_p);
3558 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
3559 howto, value);
3560 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
3561 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
3562 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
3563 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
3564 base_got = globals->root.sgot;
3565 off = h->got.offset;
3567 if (base_got == NULL)
3568 abort ();
3570 if (off == (bfd_vma) -1)
3572 bfd_vma plt_index;
3574 /* We can't use h->got.offset here to save state, or
3575 even just remember the offset, as finish_dynamic_symbol
3576 would use that as offset into .got. */
3578 if (globals->root.splt != NULL)
3580 plt_index = h->plt.offset / globals->plt_entry_size - 1;
3581 off = (plt_index + 3) * GOT_ENTRY_SIZE;
3582 base_got = globals->root.sgotplt;
3584 else
3586 plt_index = h->plt.offset / globals->plt_entry_size;
3587 off = plt_index * GOT_ENTRY_SIZE;
3588 base_got = globals->root.igotplt;
3591 if (h->dynindx == -1
3592 || h->forced_local
3593 || info->symbolic)
3595 /* This references the local definition. We must
3596 initialize this entry in the global offset table.
3597 Since the offset must always be a multiple of 8,
3598 we use the least significant bit to record
3599 whether we have initialized it already.
3601 When doing a dynamic link, we create a .rela.got
3602 relocation entry to initialize the value. This
3603 is done in the finish_dynamic_symbol routine. */
3604 if ((off & 1) != 0)
3605 off &= ~1;
3606 else
3608 bfd_put_NN (output_bfd, value,
3609 base_got->contents + off);
3610 /* Note that this is harmless as -1 | 1 still is -1. */
3611 h->got.offset |= 1;
3614 value = (base_got->output_section->vma
3615 + base_got->output_offset + off);
3617 else
3618 value = aarch64_calculate_got_entry_vma (h, globals, info,
3619 value, output_bfd,
3620 unresolved_reloc_p);
3621 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3622 0, weak_undef_p);
3623 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
3624 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
3625 case BFD_RELOC_AARCH64_ADD_LO12:
3626 break;
3630 switch (bfd_r_type)
3632 case BFD_RELOC_AARCH64_NONE:
3633 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3634 *unresolved_reloc_p = FALSE;
3635 return bfd_reloc_ok;
3637 case BFD_RELOC_AARCH64_NN:
3639 /* When generating a shared object or relocatable executable, these
3640 relocations are copied into the output file to be resolved at
3641 run time. */
3642 if (((info->shared == TRUE) || globals->root.is_relocatable_executable)
3643 && (input_section->flags & SEC_ALLOC)
3644 && (h == NULL
3645 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3646 || h->root.type != bfd_link_hash_undefweak))
3648 Elf_Internal_Rela outrel;
3649 bfd_byte *loc;
3650 bfd_boolean skip, relocate;
3651 asection *sreloc;
3653 *unresolved_reloc_p = FALSE;
3655 skip = FALSE;
3656 relocate = FALSE;
3658 outrel.r_addend = signed_addend;
3659 outrel.r_offset =
3660 _bfd_elf_section_offset (output_bfd, info, input_section,
3661 rel->r_offset);
3662 if (outrel.r_offset == (bfd_vma) - 1)
3663 skip = TRUE;
3664 else if (outrel.r_offset == (bfd_vma) - 2)
3666 skip = TRUE;
3667 relocate = TRUE;
3670 outrel.r_offset += (input_section->output_section->vma
3671 + input_section->output_offset);
3673 if (skip)
3674 memset (&outrel, 0, sizeof outrel);
3675 else if (h != NULL
3676 && h->dynindx != -1
3677 && (!info->shared || !info->symbolic || !h->def_regular))
3678 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
3679 else
3681 int symbol;
3683 /* On SVR4-ish systems, the dynamic loader cannot
3684 relocate the text and data segments independently,
3685 so the symbol does not matter. */
3686 symbol = 0;
3687 outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
3688 outrel.r_addend += value;
3691 sreloc = elf_section_data (input_section)->sreloc;
3692 if (sreloc == NULL || sreloc->contents == NULL)
3693 return bfd_reloc_notsupported;
3695 loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
3696 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
3698 if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
3700 /* Sanity to check that we have previously allocated
3701 sufficient space in the relocation section for the
3702 number of relocations we actually want to emit. */
3703 abort ();
3706 /* If this reloc is against an external symbol, we do not want to
3707 fiddle with the addend. Otherwise, we need to include the symbol
3708 value so that it becomes an addend for the dynamic reloc. */
3709 if (!relocate)
3710 return bfd_reloc_ok;
3712 return _bfd_final_link_relocate (howto, input_bfd, input_section,
3713 contents, rel->r_offset, value,
3714 signed_addend);
3716 else
3717 value += signed_addend;
3718 break;
3720 case BFD_RELOC_AARCH64_JUMP26:
3721 case BFD_RELOC_AARCH64_CALL26:
3723 asection *splt = globals->root.splt;
3724 bfd_boolean via_plt_p =
3725 splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
3727 /* A call to an undefined weak symbol is converted to a jump to
3728 the next instruction unless a PLT entry will be created.
3729 The jump to the next instruction is optimized as a NOP.
3730 Do the same for local undefined symbols. */
3731 if (weak_undef_p && ! via_plt_p)
3733 bfd_putl32 (INSN_NOP, hit_data);
3734 return bfd_reloc_ok;
3737 /* If the call goes through a PLT entry, make sure to
3738 check distance to the right destination address. */
3739 if (via_plt_p)
3741 value = (splt->output_section->vma
3742 + splt->output_offset + h->plt.offset);
3743 *unresolved_reloc_p = FALSE;
3746 /* If the target symbol is global and marked as a function the
3747 relocation applies a function call or a tail call. In this
3748 situation we can veneer out of range branches. The veneers
3749 use IP0 and IP1 hence cannot be used arbitrary out of range
3750 branches that occur within the body of a function. */
3751 if (h && h->type == STT_FUNC)
3753 /* Check if a stub has to be inserted because the destination
3754 is too far away. */
3755 if (! aarch64_valid_branch_p (value, place))
3757 /* The target is out of reach, so redirect the branch to
3758 the local stub for this function. */
3759 struct elf_aarch64_stub_hash_entry *stub_entry;
3760 stub_entry = elfNN_aarch64_get_stub_entry (input_section,
3761 sym_sec, h,
3762 rel, globals);
3763 if (stub_entry != NULL)
3764 value = (stub_entry->stub_offset
3765 + stub_entry->stub_sec->output_offset
3766 + stub_entry->stub_sec->output_section->vma);
3770 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3771 signed_addend, weak_undef_p);
3772 break;
3774 case BFD_RELOC_AARCH64_16:
3775 #if ARCH_SIZE == 64
3776 case BFD_RELOC_AARCH64_32:
3777 #endif
3778 case BFD_RELOC_AARCH64_ADD_LO12:
3779 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
3780 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
3781 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
3782 case BFD_RELOC_AARCH64_BRANCH19:
3783 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
3784 case BFD_RELOC_AARCH64_LDST8_LO12:
3785 case BFD_RELOC_AARCH64_LDST16_LO12:
3786 case BFD_RELOC_AARCH64_LDST32_LO12:
3787 case BFD_RELOC_AARCH64_LDST64_LO12:
3788 case BFD_RELOC_AARCH64_LDST128_LO12:
3789 case BFD_RELOC_AARCH64_MOVW_G0_S:
3790 case BFD_RELOC_AARCH64_MOVW_G1_S:
3791 case BFD_RELOC_AARCH64_MOVW_G2_S:
3792 case BFD_RELOC_AARCH64_MOVW_G0:
3793 case BFD_RELOC_AARCH64_MOVW_G0_NC:
3794 case BFD_RELOC_AARCH64_MOVW_G1:
3795 case BFD_RELOC_AARCH64_MOVW_G1_NC:
3796 case BFD_RELOC_AARCH64_MOVW_G2:
3797 case BFD_RELOC_AARCH64_MOVW_G2_NC:
3798 case BFD_RELOC_AARCH64_MOVW_G3:
3799 case BFD_RELOC_AARCH64_16_PCREL:
3800 case BFD_RELOC_AARCH64_32_PCREL:
3801 case BFD_RELOC_AARCH64_64_PCREL:
3802 case BFD_RELOC_AARCH64_TSTBR14:
3803 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3804 signed_addend, weak_undef_p);
3805 break;
3807 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
3808 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
3809 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
3810 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
3811 if (globals->root.sgot == NULL)
3812 BFD_ASSERT (h != NULL);
3814 if (h != NULL)
3816 value = aarch64_calculate_got_entry_vma (h, globals, info, value,
3817 output_bfd,
3818 unresolved_reloc_p);
3819 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3820 0, weak_undef_p);
3822 break;
3824 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3825 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3826 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
3827 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
3828 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
3829 if (globals->root.sgot == NULL)
3830 return bfd_reloc_notsupported;
3832 value = (symbol_got_offset (input_bfd, h, r_symndx)
3833 + globals->root.sgot->output_section->vma
3834 + globals->root.sgot->output_section->output_offset);
3836 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3837 0, weak_undef_p);
3838 *unresolved_reloc_p = FALSE;
3839 break;
3841 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
3842 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
3843 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
3844 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
3845 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
3846 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
3847 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
3848 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
3849 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3850 signed_addend - tpoff_base (info),
3851 weak_undef_p);
3852 *unresolved_reloc_p = FALSE;
3853 break;
3855 case BFD_RELOC_AARCH64_TLSDESC_ADD:
3856 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3857 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3858 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
3859 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
3860 case BFD_RELOC_AARCH64_TLSDESC_LDR:
3861 if (globals->root.sgot == NULL)
3862 return bfd_reloc_notsupported;
3864 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
3865 + globals->root.sgotplt->output_section->vma
3866 + globals->root.sgotplt->output_section->output_offset
3867 + globals->sgotplt_jump_table_size);
3869 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
3870 0, weak_undef_p);
3871 *unresolved_reloc_p = FALSE;
3872 break;
3874 default:
3875 return bfd_reloc_notsupported;
3878 if (saved_addend)
3879 *saved_addend = value;
3881 /* Only apply the final relocation in a sequence. */
3882 if (save_addend)
3883 return bfd_reloc_continue;
3885 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
3886 howto, value);
3889 /* Handle TLS relaxations. Relaxing is possible for symbols that use
3890 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
3891 link.
3893 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
3894 is to then call final_link_relocate. Return other values in the
3895 case of error. */
3897 static bfd_reloc_status_type
3898 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
3899 bfd *input_bfd, bfd_byte *contents,
3900 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h)
3902 bfd_boolean is_local = h == NULL;
3903 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
3904 unsigned long insn;
3906 BFD_ASSERT (globals && input_bfd && contents && rel);
3908 switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
3910 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3911 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
3912 if (is_local)
3914 /* GD->LE relaxation:
3915 adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
3917 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
3919 bfd_putl32 (0xd2a00000, contents + rel->r_offset);
3920 return bfd_reloc_continue;
3922 else
3924 /* GD->IE relaxation:
3925 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
3927 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
3929 insn = bfd_getl32 (contents + rel->r_offset);
3930 return bfd_reloc_continue;
3933 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
3934 if (is_local)
3936 /* GD->LE relaxation:
3937 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
3939 bfd_putl32 (0xf2800000, contents + rel->r_offset);
3940 return bfd_reloc_continue;
3942 else
3944 /* GD->IE relaxation:
3945 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
3947 insn = bfd_getl32 (contents + rel->r_offset);
3948 insn &= 0xfffffff0;
3949 bfd_putl32 (insn, contents + rel->r_offset);
3950 return bfd_reloc_continue;
3953 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
3954 if (is_local)
3956 /* GD->LE relaxation
3957 add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
3958 bl __tls_get_addr => mrs x1, tpidr_el0
3959 nop => add x0, x1, x0
3962 /* First kill the tls_get_addr reloc on the bl instruction. */
3963 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
3964 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
3966 bfd_putl32 (0xf2800000, contents + rel->r_offset);
3967 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
3968 bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
3969 return bfd_reloc_continue;
3971 else
3973 /* GD->IE relaxation
3974 ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
3975 BL __tls_get_addr => mrs x1, tpidr_el0
3976 R_AARCH64_CALL26
3977 NOP => add x0, x1, x0
3980 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
3982 /* Remove the relocation on the BL instruction. */
3983 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
3985 bfd_putl32 (0xf9400000, contents + rel->r_offset);
3987 /* We choose to fixup the BL and NOP instructions using the
3988 offset from the second relocation to allow flexibility in
3989 scheduling instructions between the ADD and BL. */
3990 bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
3991 bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
3992 return bfd_reloc_continue;
3995 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
3996 case BFD_RELOC_AARCH64_TLSDESC_CALL:
3997 /* GD->IE/LE relaxation:
3998 add x0, x0, #:tlsdesc_lo12:var => nop
3999 blr xd => nop
4001 bfd_putl32 (INSN_NOP, contents + rel->r_offset);
4002 return bfd_reloc_ok;
4004 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4005 /* IE->LE relaxation:
4006 adrp xd, :gottprel:var => movz xd, :tprel_g1:var
4008 if (is_local)
4010 insn = bfd_getl32 (contents + rel->r_offset);
4011 bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
4013 return bfd_reloc_continue;
4015 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
4016 /* IE->LE relaxation:
4017 ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
4019 if (is_local)
4021 insn = bfd_getl32 (contents + rel->r_offset);
4022 bfd_putl32 (0xf2800000 | (insn & 0x1f), contents + rel->r_offset);
4024 return bfd_reloc_continue;
4026 default:
4027 return bfd_reloc_continue;
4030 return bfd_reloc_ok;
4033 /* Relocate an AArch64 ELF section. */
4035 static bfd_boolean
4036 elfNN_aarch64_relocate_section (bfd *output_bfd,
4037 struct bfd_link_info *info,
4038 bfd *input_bfd,
4039 asection *input_section,
4040 bfd_byte *contents,
4041 Elf_Internal_Rela *relocs,
4042 Elf_Internal_Sym *local_syms,
4043 asection **local_sections)
4045 Elf_Internal_Shdr *symtab_hdr;
4046 struct elf_link_hash_entry **sym_hashes;
4047 Elf_Internal_Rela *rel;
4048 Elf_Internal_Rela *relend;
4049 const char *name;
4050 struct elf_aarch64_link_hash_table *globals;
4051 bfd_boolean save_addend = FALSE;
4052 bfd_vma addend = 0;
4054 globals = elf_aarch64_hash_table (info);
4056 symtab_hdr = &elf_symtab_hdr (input_bfd);
4057 sym_hashes = elf_sym_hashes (input_bfd);
4059 rel = relocs;
4060 relend = relocs + input_section->reloc_count;
4061 for (; rel < relend; rel++)
4063 unsigned int r_type;
4064 bfd_reloc_code_real_type bfd_r_type;
4065 bfd_reloc_code_real_type relaxed_bfd_r_type;
4066 reloc_howto_type *howto;
4067 unsigned long r_symndx;
4068 Elf_Internal_Sym *sym;
4069 asection *sec;
4070 struct elf_link_hash_entry *h;
4071 bfd_vma relocation;
4072 bfd_reloc_status_type r;
4073 arelent bfd_reloc;
4074 char sym_type;
4075 bfd_boolean unresolved_reloc = FALSE;
4076 char *error_message = NULL;
4078 r_symndx = ELFNN_R_SYM (rel->r_info);
4079 r_type = ELFNN_R_TYPE (rel->r_info);
4081 bfd_reloc.howto = elfNN_aarch64_howto_from_type (r_type);
4082 howto = bfd_reloc.howto;
4084 if (howto == NULL)
4086 (*_bfd_error_handler)
4087 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
4088 input_bfd, input_section, r_type);
4089 return FALSE;
4091 bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
4093 h = NULL;
4094 sym = NULL;
4095 sec = NULL;
4097 if (r_symndx < symtab_hdr->sh_info)
4099 sym = local_syms + r_symndx;
4100 sym_type = ELFNN_ST_TYPE (sym->st_info);
4101 sec = local_sections[r_symndx];
4103 /* An object file might have a reference to a local
4104 undefined symbol. This is a daft object file, but we
4105 should at least do something about it. */
4106 if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
4107 && bfd_is_und_section (sec)
4108 && ELF_ST_BIND (sym->st_info) != STB_WEAK)
4110 if (!info->callbacks->undefined_symbol
4111 (info, bfd_elf_string_from_elf_section
4112 (input_bfd, symtab_hdr->sh_link, sym->st_name),
4113 input_bfd, input_section, rel->r_offset, TRUE))
4114 return FALSE;
4117 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
4119 /* Relocate against local STT_GNU_IFUNC symbol. */
4120 if (!info->relocatable
4121 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4123 h = elfNN_aarch64_get_local_sym_hash (globals, input_bfd,
4124 rel, FALSE);
4125 if (h == NULL)
4126 abort ();
4128 /* Set STT_GNU_IFUNC symbol value. */
4129 h->root.u.def.value = sym->st_value;
4130 h->root.u.def.section = sec;
4133 else
4135 bfd_boolean warned;
4137 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4138 r_symndx, symtab_hdr, sym_hashes,
4139 h, sec, relocation,
4140 unresolved_reloc, warned);
4142 sym_type = h->type;
4145 if (sec != NULL && discarded_section (sec))
4146 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
4147 rel, 1, relend, howto, 0, contents);
4149 if (info->relocatable)
4151 /* This is a relocatable link. We don't have to change
4152 anything, unless the reloc is against a section symbol,
4153 in which case we have to adjust according to where the
4154 section symbol winds up in the output section. */
4155 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4156 rel->r_addend += sec->output_offset;
4157 continue;
4160 if (h != NULL)
4161 name = h->root.root.string;
4162 else
4164 name = (bfd_elf_string_from_elf_section
4165 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4166 if (name == NULL || *name == '\0')
4167 name = bfd_section_name (input_bfd, sec);
4170 if (r_symndx != 0
4171 && r_type != R_AARCH64_NONE
4172 && r_type != R_AARCH64_NULL
4173 && (h == NULL
4174 || h->root.type == bfd_link_hash_defined
4175 || h->root.type == bfd_link_hash_defweak)
4176 && IS_AARCH64_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
4178 (*_bfd_error_handler)
4179 ((sym_type == STT_TLS
4180 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
4181 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
4182 input_bfd,
4183 input_section, (long) rel->r_offset, howto->name, name);
4186 /* We relax only if we can see that there can be a valid transition
4187 from a reloc type to another.
4188 We call elfNN_aarch64_final_link_relocate unless we're completely
4189 done, i.e., the relaxation produced the final output we want. */
4191 relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
4192 h, r_symndx);
4193 if (relaxed_bfd_r_type != bfd_r_type)
4195 bfd_r_type = relaxed_bfd_r_type;
4196 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
4197 BFD_ASSERT (howto != NULL);
4198 r_type = howto->type;
4199 r = elfNN_aarch64_tls_relax (globals, input_bfd, contents, rel, h);
4200 unresolved_reloc = 0;
4202 else
4203 r = bfd_reloc_continue;
4205 /* There may be multiple consecutive relocations for the
4206 same offset. In that case we are supposed to treat the
4207 output of each relocation as the addend for the next. */
4208 if (rel + 1 < relend
4209 && rel->r_offset == rel[1].r_offset
4210 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NONE
4211 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NULL)
4212 save_addend = TRUE;
4213 else
4214 save_addend = FALSE;
4216 if (r == bfd_reloc_continue)
4217 r = elfNN_aarch64_final_link_relocate (howto, input_bfd, output_bfd,
4218 input_section, contents, rel,
4219 relocation, info, sec,
4220 h, &unresolved_reloc,
4221 save_addend, &addend, sym);
4223 switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
4225 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
4226 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
4227 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
4229 bfd_boolean need_relocs = FALSE;
4230 bfd_byte *loc;
4231 int indx;
4232 bfd_vma off;
4234 off = symbol_got_offset (input_bfd, h, r_symndx);
4235 indx = h && h->dynindx != -1 ? h->dynindx : 0;
4237 need_relocs =
4238 (info->shared || indx != 0) &&
4239 (h == NULL
4240 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4241 || h->root.type != bfd_link_hash_undefweak);
4243 BFD_ASSERT (globals->root.srelgot != NULL);
4245 if (need_relocs)
4247 Elf_Internal_Rela rela;
4248 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPMOD));
4249 rela.r_addend = 0;
4250 rela.r_offset = globals->root.sgot->output_section->vma +
4251 globals->root.sgot->output_offset + off;
4254 loc = globals->root.srelgot->contents;
4255 loc += globals->root.srelgot->reloc_count++
4256 * RELOC_SIZE (htab);
4257 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4259 if (indx == 0)
4261 bfd_put_NN (output_bfd,
4262 relocation - dtpoff_base (info),
4263 globals->root.sgot->contents + off
4264 + GOT_ENTRY_SIZE);
4266 else
4268 /* This TLS symbol is global. We emit a
4269 relocation to fixup the tls offset at load
4270 time. */
4271 rela.r_info =
4272 ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPREL));
4273 rela.r_addend = 0;
4274 rela.r_offset =
4275 (globals->root.sgot->output_section->vma
4276 + globals->root.sgot->output_offset + off
4277 + GOT_ENTRY_SIZE);
4279 loc = globals->root.srelgot->contents;
4280 loc += globals->root.srelgot->reloc_count++
4281 * RELOC_SIZE (globals);
4282 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4283 bfd_put_NN (output_bfd, (bfd_vma) 0,
4284 globals->root.sgot->contents + off
4285 + GOT_ENTRY_SIZE);
4288 else
4290 bfd_put_NN (output_bfd, (bfd_vma) 1,
4291 globals->root.sgot->contents + off);
4292 bfd_put_NN (output_bfd,
4293 relocation - dtpoff_base (info),
4294 globals->root.sgot->contents + off
4295 + GOT_ENTRY_SIZE);
4298 symbol_got_offset_mark (input_bfd, h, r_symndx);
4300 break;
4302 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4303 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
4304 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
4306 bfd_boolean need_relocs = FALSE;
4307 bfd_byte *loc;
4308 int indx;
4309 bfd_vma off;
4311 off = symbol_got_offset (input_bfd, h, r_symndx);
4313 indx = h && h->dynindx != -1 ? h->dynindx : 0;
4315 need_relocs =
4316 (info->shared || indx != 0) &&
4317 (h == NULL
4318 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4319 || h->root.type != bfd_link_hash_undefweak);
4321 BFD_ASSERT (globals->root.srelgot != NULL);
4323 if (need_relocs)
4325 Elf_Internal_Rela rela;
4327 if (indx == 0)
4328 rela.r_addend = relocation - dtpoff_base (info);
4329 else
4330 rela.r_addend = 0;
4332 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_TPREL));
4333 rela.r_offset = globals->root.sgot->output_section->vma +
4334 globals->root.sgot->output_offset + off;
4336 loc = globals->root.srelgot->contents;
4337 loc += globals->root.srelgot->reloc_count++
4338 * RELOC_SIZE (htab);
4340 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4342 bfd_put_NN (output_bfd, rela.r_addend,
4343 globals->root.sgot->contents + off);
4345 else
4346 bfd_put_NN (output_bfd, relocation - tpoff_base (info),
4347 globals->root.sgot->contents + off);
4349 symbol_got_offset_mark (input_bfd, h, r_symndx);
4351 break;
4353 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
4354 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
4355 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
4356 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
4357 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
4358 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
4359 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
4360 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
4361 break;
4363 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4364 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4365 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
4366 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
4368 bfd_boolean need_relocs = FALSE;
4369 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
4370 bfd_vma off = symbol_tlsdesc_got_offset (input_bfd, h, r_symndx);
4372 need_relocs = (h == NULL
4373 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4374 || h->root.type != bfd_link_hash_undefweak);
4376 BFD_ASSERT (globals->root.srelgot != NULL);
4377 BFD_ASSERT (globals->root.sgot != NULL);
4379 if (need_relocs)
4381 bfd_byte *loc;
4382 Elf_Internal_Rela rela;
4383 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
4385 rela.r_addend = 0;
4386 rela.r_offset = (globals->root.sgotplt->output_section->vma
4387 + globals->root.sgotplt->output_offset
4388 + off + globals->sgotplt_jump_table_size);
4390 if (indx == 0)
4391 rela.r_addend = relocation - dtpoff_base (info);
4393 /* Allocate the next available slot in the PLT reloc
4394 section to hold our R_AARCH64_TLSDESC, the next
4395 available slot is determined from reloc_count,
4396 which we step. But note, reloc_count was
4397 artifically moved down while allocating slots for
4398 real PLT relocs such that all of the PLT relocs
4399 will fit above the initial reloc_count and the
4400 extra stuff will fit below. */
4401 loc = globals->root.srelplt->contents;
4402 loc += globals->root.srelplt->reloc_count++
4403 * RELOC_SIZE (globals);
4405 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4407 bfd_put_NN (output_bfd, (bfd_vma) 0,
4408 globals->root.sgotplt->contents + off +
4409 globals->sgotplt_jump_table_size);
4410 bfd_put_NN (output_bfd, (bfd_vma) 0,
4411 globals->root.sgotplt->contents + off +
4412 globals->sgotplt_jump_table_size +
4413 GOT_ENTRY_SIZE);
4416 symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
4418 break;
4419 default:
4420 break;
4423 if (!save_addend)
4424 addend = 0;
4427 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
4428 because such sections are not SEC_ALLOC and thus ld.so will
4429 not process them. */
4430 if (unresolved_reloc
4431 && !((input_section->flags & SEC_DEBUGGING) != 0
4432 && h->def_dynamic)
4433 && _bfd_elf_section_offset (output_bfd, info, input_section,
4434 +rel->r_offset) != (bfd_vma) - 1)
4436 (*_bfd_error_handler)
4438 ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
4439 input_bfd, input_section, (long) rel->r_offset, howto->name,
4440 h->root.root.string);
4441 return FALSE;
4444 if (r != bfd_reloc_ok && r != bfd_reloc_continue)
4446 switch (r)
4448 case bfd_reloc_overflow:
4449 /* If the overflowing reloc was to an undefined symbol,
4450 we have already printed one error message and there
4451 is no point complaining again. */
4452 if ((!h ||
4453 h->root.type != bfd_link_hash_undefined)
4454 && (!((*info->callbacks->reloc_overflow)
4455 (info, (h ? &h->root : NULL), name, howto->name,
4456 (bfd_vma) 0, input_bfd, input_section,
4457 rel->r_offset))))
4458 return FALSE;
4459 break;
4461 case bfd_reloc_undefined:
4462 if (!((*info->callbacks->undefined_symbol)
4463 (info, name, input_bfd, input_section,
4464 rel->r_offset, TRUE)))
4465 return FALSE;
4466 break;
4468 case bfd_reloc_outofrange:
4469 error_message = _("out of range");
4470 goto common_error;
4472 case bfd_reloc_notsupported:
4473 error_message = _("unsupported relocation");
4474 goto common_error;
4476 case bfd_reloc_dangerous:
4477 /* error_message should already be set. */
4478 goto common_error;
4480 default:
4481 error_message = _("unknown error");
4482 /* Fall through. */
4484 common_error:
4485 BFD_ASSERT (error_message != NULL);
4486 if (!((*info->callbacks->reloc_dangerous)
4487 (info, error_message, input_bfd, input_section,
4488 rel->r_offset)))
4489 return FALSE;
4490 break;
4495 return TRUE;
4498 /* Set the right machine number. */
4500 static bfd_boolean
4501 elfNN_aarch64_object_p (bfd *abfd)
4503 #if ARCH_SIZE == 32
4504 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64_ilp32);
4505 #else
4506 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64);
4507 #endif
4508 return TRUE;
4511 /* Function to keep AArch64 specific flags in the ELF header. */
4513 static bfd_boolean
4514 elfNN_aarch64_set_private_flags (bfd *abfd, flagword flags)
4516 if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
4519 else
4521 elf_elfheader (abfd)->e_flags = flags;
4522 elf_flags_init (abfd) = TRUE;
4525 return TRUE;
4528 /* Copy backend specific data from one object module to another. */
4530 static bfd_boolean
4531 elfNN_aarch64_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
4533 flagword in_flags;
4535 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
4536 return TRUE;
4538 in_flags = elf_elfheader (ibfd)->e_flags;
4540 elf_elfheader (obfd)->e_flags = in_flags;
4541 elf_flags_init (obfd) = TRUE;
4543 /* Also copy the EI_OSABI field. */
4544 elf_elfheader (obfd)->e_ident[EI_OSABI] =
4545 elf_elfheader (ibfd)->e_ident[EI_OSABI];
4547 /* Copy object attributes. */
4548 _bfd_elf_copy_obj_attributes (ibfd, obfd);
4550 return TRUE;
4553 /* Merge backend specific data from an object file to the output
4554 object file when linking. */
4556 static bfd_boolean
4557 elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
4559 flagword out_flags;
4560 flagword in_flags;
4561 bfd_boolean flags_compatible = TRUE;
4562 asection *sec;
4564 /* Check if we have the same endianess. */
4565 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
4566 return FALSE;
4568 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
4569 return TRUE;
4571 /* The input BFD must have had its flags initialised. */
4572 /* The following seems bogus to me -- The flags are initialized in
4573 the assembler but I don't think an elf_flags_init field is
4574 written into the object. */
4575 /* BFD_ASSERT (elf_flags_init (ibfd)); */
4577 in_flags = elf_elfheader (ibfd)->e_flags;
4578 out_flags = elf_elfheader (obfd)->e_flags;
4580 if (!elf_flags_init (obfd))
4582 /* If the input is the default architecture and had the default
4583 flags then do not bother setting the flags for the output
4584 architecture, instead allow future merges to do this. If no
4585 future merges ever set these flags then they will retain their
4586 uninitialised values, which surprise surprise, correspond
4587 to the default values. */
4588 if (bfd_get_arch_info (ibfd)->the_default
4589 && elf_elfheader (ibfd)->e_flags == 0)
4590 return TRUE;
4592 elf_flags_init (obfd) = TRUE;
4593 elf_elfheader (obfd)->e_flags = in_flags;
4595 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4596 && bfd_get_arch_info (obfd)->the_default)
4597 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4598 bfd_get_mach (ibfd));
4600 return TRUE;
4603 /* Identical flags must be compatible. */
4604 if (in_flags == out_flags)
4605 return TRUE;
4607 /* Check to see if the input BFD actually contains any sections. If
4608 not, its flags may not have been initialised either, but it
4609 cannot actually cause any incompatiblity. Do not short-circuit
4610 dynamic objects; their section list may be emptied by
4611 elf_link_add_object_symbols.
4613 Also check to see if there are no code sections in the input.
4614 In this case there is no need to check for code specific flags.
4615 XXX - do we need to worry about floating-point format compatability
4616 in data sections ? */
4617 if (!(ibfd->flags & DYNAMIC))
4619 bfd_boolean null_input_bfd = TRUE;
4620 bfd_boolean only_data_sections = TRUE;
4622 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
4624 if ((bfd_get_section_flags (ibfd, sec)
4625 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
4626 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
4627 only_data_sections = FALSE;
4629 null_input_bfd = FALSE;
4630 break;
4633 if (null_input_bfd || only_data_sections)
4634 return TRUE;
4637 return flags_compatible;
4640 /* Display the flags field. */
4642 static bfd_boolean
4643 elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
4645 FILE *file = (FILE *) ptr;
4646 unsigned long flags;
4648 BFD_ASSERT (abfd != NULL && ptr != NULL);
4650 /* Print normal ELF private data. */
4651 _bfd_elf_print_private_bfd_data (abfd, ptr);
4653 flags = elf_elfheader (abfd)->e_flags;
4654 /* Ignore init flag - it may not be set, despite the flags field
4655 containing valid data. */
4657 /* xgettext:c-format */
4658 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
4660 if (flags)
4661 fprintf (file, _("<Unrecognised flag bits set>"));
4663 fputc ('\n', file);
4665 return TRUE;
4668 /* Update the got entry reference counts for the section being removed. */
4670 static bfd_boolean
4671 elfNN_aarch64_gc_sweep_hook (bfd *abfd,
4672 struct bfd_link_info *info,
4673 asection *sec,
4674 const Elf_Internal_Rela * relocs)
4676 struct elf_aarch64_link_hash_table *htab;
4677 Elf_Internal_Shdr *symtab_hdr;
4678 struct elf_link_hash_entry **sym_hashes;
4679 struct elf_aarch64_local_symbol *locals;
4680 const Elf_Internal_Rela *rel, *relend;
4682 if (info->relocatable)
4683 return TRUE;
4685 htab = elf_aarch64_hash_table (info);
4687 if (htab == NULL)
4688 return FALSE;
4690 elf_section_data (sec)->local_dynrel = NULL;
4692 symtab_hdr = &elf_symtab_hdr (abfd);
4693 sym_hashes = elf_sym_hashes (abfd);
4695 locals = elf_aarch64_locals (abfd);
4697 relend = relocs + sec->reloc_count;
4698 for (rel = relocs; rel < relend; rel++)
4700 unsigned long r_symndx;
4701 unsigned int r_type;
4702 struct elf_link_hash_entry *h = NULL;
4704 r_symndx = ELFNN_R_SYM (rel->r_info);
4706 if (r_symndx >= symtab_hdr->sh_info)
4709 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4710 while (h->root.type == bfd_link_hash_indirect
4711 || h->root.type == bfd_link_hash_warning)
4712 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4714 else
4716 Elf_Internal_Sym *isym;
4718 /* A local symbol. */
4719 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
4720 abfd, r_symndx);
4722 /* Check relocation against local STT_GNU_IFUNC symbol. */
4723 if (isym != NULL
4724 && ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
4726 h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel, FALSE);
4727 if (h == NULL)
4728 abort ();
4732 if (h)
4734 struct elf_aarch64_link_hash_entry *eh;
4735 struct elf_dyn_relocs **pp;
4736 struct elf_dyn_relocs *p;
4738 eh = (struct elf_aarch64_link_hash_entry *) h;
4740 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
4741 if (p->sec == sec)
4743 /* Everything must go for SEC. */
4744 *pp = p->next;
4745 break;
4749 r_type = ELFNN_R_TYPE (rel->r_info);
4750 switch (aarch64_tls_transition (abfd,info, r_type, h ,r_symndx))
4752 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4753 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
4754 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
4755 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
4756 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
4757 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
4758 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
4759 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
4760 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
4761 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
4762 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4763 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
4764 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
4765 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
4766 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
4767 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
4768 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
4769 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
4770 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
4771 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
4772 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
4773 if (h != NULL)
4775 if (h->got.refcount > 0)
4776 h->got.refcount -= 1;
4778 if (h->type == STT_GNU_IFUNC)
4780 if (h->plt.refcount > 0)
4781 h->plt.refcount -= 1;
4784 else if (locals != NULL)
4786 if (locals[r_symndx].got_refcount > 0)
4787 locals[r_symndx].got_refcount -= 1;
4789 break;
4791 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
4792 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
4793 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
4794 if (h != NULL && info->executable)
4796 if (h->plt.refcount > 0)
4797 h->plt.refcount -= 1;
4799 break;
4801 case BFD_RELOC_AARCH64_CALL26:
4802 case BFD_RELOC_AARCH64_JUMP26:
4803 /* If this is a local symbol then we resolve it
4804 directly without creating a PLT entry. */
4805 if (h == NULL)
4806 continue;
4808 if (h->plt.refcount > 0)
4809 h->plt.refcount -= 1;
4810 break;
4812 case BFD_RELOC_AARCH64_NN:
4813 if (h != NULL && info->executable)
4815 if (h->plt.refcount > 0)
4816 h->plt.refcount -= 1;
4818 break;
4820 default:
4821 break;
4825 return TRUE;
4828 /* Adjust a symbol defined by a dynamic object and referenced by a
4829 regular object. The current definition is in some section of the
4830 dynamic object, but we're not including those sections. We have to
4831 change the definition to something the rest of the link can
4832 understand. */
4834 static bfd_boolean
4835 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
4836 struct elf_link_hash_entry *h)
4838 struct elf_aarch64_link_hash_table *htab;
4839 asection *s;
4841 /* If this is a function, put it in the procedure linkage table. We
4842 will fill in the contents of the procedure linkage table later,
4843 when we know the address of the .got section. */
4844 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
4846 if (h->plt.refcount <= 0
4847 || (h->type != STT_GNU_IFUNC
4848 && (SYMBOL_CALLS_LOCAL (info, h)
4849 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4850 && h->root.type == bfd_link_hash_undefweak))))
4852 /* This case can occur if we saw a CALL26 reloc in
4853 an input file, but the symbol wasn't referred to
4854 by a dynamic object or all references were
4855 garbage collected. In which case we can end up
4856 resolving. */
4857 h->plt.offset = (bfd_vma) - 1;
4858 h->needs_plt = 0;
4861 return TRUE;
4863 else
4864 /* It's possible that we incorrectly decided a .plt reloc was
4865 needed for an R_X86_64_PC32 reloc to a non-function sym in
4866 check_relocs. We can't decide accurately between function and
4867 non-function syms in check-relocs; Objects loaded later in
4868 the link may change h->type. So fix it now. */
4869 h->plt.offset = (bfd_vma) - 1;
4872 /* If this is a weak symbol, and there is a real definition, the
4873 processor independent code will have arranged for us to see the
4874 real definition first, and we can just use the same value. */
4875 if (h->u.weakdef != NULL)
4877 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
4878 || h->u.weakdef->root.type == bfd_link_hash_defweak);
4879 h->root.u.def.section = h->u.weakdef->root.u.def.section;
4880 h->root.u.def.value = h->u.weakdef->root.u.def.value;
4881 if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
4882 h->non_got_ref = h->u.weakdef->non_got_ref;
4883 return TRUE;
4886 /* If we are creating a shared library, we must presume that the
4887 only references to the symbol are via the global offset table.
4888 For such cases we need not do anything here; the relocations will
4889 be handled correctly by relocate_section. */
4890 if (info->shared)
4891 return TRUE;
4893 /* If there are no references to this symbol that do not use the
4894 GOT, we don't need to generate a copy reloc. */
4895 if (!h->non_got_ref)
4896 return TRUE;
4898 /* If -z nocopyreloc was given, we won't generate them either. */
4899 if (info->nocopyreloc)
4901 h->non_got_ref = 0;
4902 return TRUE;
4905 /* We must allocate the symbol in our .dynbss section, which will
4906 become part of the .bss section of the executable. There will be
4907 an entry for this symbol in the .dynsym section. The dynamic
4908 object will contain position independent code, so all references
4909 from the dynamic object to this symbol will go through the global
4910 offset table. The dynamic linker will use the .dynsym entry to
4911 determine the address it must put in the global offset table, so
4912 both the dynamic object and the regular object will refer to the
4913 same memory location for the variable. */
4915 htab = elf_aarch64_hash_table (info);
4917 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
4918 to copy the initial value out of the dynamic object and into the
4919 runtime process image. */
4920 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
4922 htab->srelbss->size += RELOC_SIZE (htab);
4923 h->needs_copy = 1;
4926 s = htab->sdynbss;
4928 return _bfd_elf_adjust_dynamic_copy (h, s);
4932 static bfd_boolean
4933 elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
4935 struct elf_aarch64_local_symbol *locals;
4936 locals = elf_aarch64_locals (abfd);
4937 if (locals == NULL)
4939 locals = (struct elf_aarch64_local_symbol *)
4940 bfd_zalloc (abfd, number * sizeof (struct elf_aarch64_local_symbol));
4941 if (locals == NULL)
4942 return FALSE;
4943 elf_aarch64_locals (abfd) = locals;
4945 return TRUE;
4948 /* Create the .got section to hold the global offset table. */
4950 static bfd_boolean
4951 aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
4953 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
4954 flagword flags;
4955 asection *s;
4956 struct elf_link_hash_entry *h;
4957 struct elf_link_hash_table *htab = elf_hash_table (info);
4959 /* This function may be called more than once. */
4960 s = bfd_get_linker_section (abfd, ".got");
4961 if (s != NULL)
4962 return TRUE;
4964 flags = bed->dynamic_sec_flags;
4966 s = bfd_make_section_anyway_with_flags (abfd,
4967 (bed->rela_plts_and_copies_p
4968 ? ".rela.got" : ".rel.got"),
4969 (bed->dynamic_sec_flags
4970 | SEC_READONLY));
4971 if (s == NULL
4972 || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
4973 return FALSE;
4974 htab->srelgot = s;
4976 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
4977 if (s == NULL
4978 || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
4979 return FALSE;
4980 htab->sgot = s;
4981 htab->sgot->size += GOT_ENTRY_SIZE;
4983 if (bed->want_got_sym)
4985 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
4986 (or .got.plt) section. We don't do this in the linker script
4987 because we don't want to define the symbol if we are not creating
4988 a global offset table. */
4989 h = _bfd_elf_define_linkage_sym (abfd, info, s,
4990 "_GLOBAL_OFFSET_TABLE_");
4991 elf_hash_table (info)->hgot = h;
4992 if (h == NULL)
4993 return FALSE;
4996 if (bed->want_got_plt)
4998 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
4999 if (s == NULL
5000 || !bfd_set_section_alignment (abfd, s,
5001 bed->s->log_file_align))
5002 return FALSE;
5003 htab->sgotplt = s;
5006 /* The first bit of the global offset table is the header. */
5007 s->size += bed->got_header_size;
5009 return TRUE;
5012 /* Look through the relocs for a section during the first phase. */
5014 static bfd_boolean
5015 elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
5016 asection *sec, const Elf_Internal_Rela *relocs)
5018 Elf_Internal_Shdr *symtab_hdr;
5019 struct elf_link_hash_entry **sym_hashes;
5020 const Elf_Internal_Rela *rel;
5021 const Elf_Internal_Rela *rel_end;
5022 asection *sreloc;
5024 struct elf_aarch64_link_hash_table *htab;
5026 if (info->relocatable)
5027 return TRUE;
5029 BFD_ASSERT (is_aarch64_elf (abfd));
5031 htab = elf_aarch64_hash_table (info);
5032 sreloc = NULL;
5034 symtab_hdr = &elf_symtab_hdr (abfd);
5035 sym_hashes = elf_sym_hashes (abfd);
5037 rel_end = relocs + sec->reloc_count;
5038 for (rel = relocs; rel < rel_end; rel++)
5040 struct elf_link_hash_entry *h;
5041 unsigned long r_symndx;
5042 unsigned int r_type;
5043 bfd_reloc_code_real_type bfd_r_type;
5044 Elf_Internal_Sym *isym;
5046 r_symndx = ELFNN_R_SYM (rel->r_info);
5047 r_type = ELFNN_R_TYPE (rel->r_info);
5049 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
5051 (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
5052 r_symndx);
5053 return FALSE;
5056 if (r_symndx < symtab_hdr->sh_info)
5058 /* A local symbol. */
5059 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
5060 abfd, r_symndx);
5061 if (isym == NULL)
5062 return FALSE;
5064 /* Check relocation against local STT_GNU_IFUNC symbol. */
5065 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
5067 h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel,
5068 TRUE);
5069 if (h == NULL)
5070 return FALSE;
5072 /* Fake a STT_GNU_IFUNC symbol. */
5073 h->type = STT_GNU_IFUNC;
5074 h->def_regular = 1;
5075 h->ref_regular = 1;
5076 h->forced_local = 1;
5077 h->root.type = bfd_link_hash_defined;
5079 else
5080 h = NULL;
5082 else
5084 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
5085 while (h->root.type == bfd_link_hash_indirect
5086 || h->root.type == bfd_link_hash_warning)
5087 h = (struct elf_link_hash_entry *) h->root.u.i.link;
5089 /* PR15323, ref flags aren't set for references in the same
5090 object. */
5091 h->root.non_ir_ref = 1;
5094 /* Could be done earlier, if h were already available. */
5095 bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
5097 if (h != NULL)
5099 /* Create the ifunc sections for static executables. If we
5100 never see an indirect function symbol nor we are building
5101 a static executable, those sections will be empty and
5102 won't appear in output. */
5103 switch (bfd_r_type)
5105 default:
5106 break;
5108 case BFD_RELOC_AARCH64_NN:
5109 case BFD_RELOC_AARCH64_CALL26:
5110 case BFD_RELOC_AARCH64_JUMP26:
5111 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
5112 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
5113 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
5114 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
5115 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
5116 case BFD_RELOC_AARCH64_ADD_LO12:
5117 if (htab->root.dynobj == NULL)
5118 htab->root.dynobj = abfd;
5119 if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
5120 return FALSE;
5121 break;
5124 /* It is referenced by a non-shared object. */
5125 h->ref_regular = 1;
5126 h->root.non_ir_ref = 1;
5129 switch (bfd_r_type)
5131 case BFD_RELOC_AARCH64_NN:
5133 /* We don't need to handle relocs into sections not going into
5134 the "real" output. */
5135 if ((sec->flags & SEC_ALLOC) == 0)
5136 break;
5138 if (h != NULL)
5140 if (!info->shared)
5141 h->non_got_ref = 1;
5143 h->plt.refcount += 1;
5144 h->pointer_equality_needed = 1;
5147 /* No need to do anything if we're not creating a shared
5148 object. */
5149 if (! info->shared)
5150 break;
5153 struct elf_dyn_relocs *p;
5154 struct elf_dyn_relocs **head;
5156 /* We must copy these reloc types into the output file.
5157 Create a reloc section in dynobj and make room for
5158 this reloc. */
5159 if (sreloc == NULL)
5161 if (htab->root.dynobj == NULL)
5162 htab->root.dynobj = abfd;
5164 sreloc = _bfd_elf_make_dynamic_reloc_section
5165 (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ TRUE);
5167 if (sreloc == NULL)
5168 return FALSE;
5171 /* If this is a global symbol, we count the number of
5172 relocations we need for this symbol. */
5173 if (h != NULL)
5175 struct elf_aarch64_link_hash_entry *eh;
5176 eh = (struct elf_aarch64_link_hash_entry *) h;
5177 head = &eh->dyn_relocs;
5179 else
5181 /* Track dynamic relocs needed for local syms too.
5182 We really need local syms available to do this
5183 easily. Oh well. */
5185 asection *s;
5186 void **vpp;
5188 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
5189 abfd, r_symndx);
5190 if (isym == NULL)
5191 return FALSE;
5193 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
5194 if (s == NULL)
5195 s = sec;
5197 /* Beware of type punned pointers vs strict aliasing
5198 rules. */
5199 vpp = &(elf_section_data (s)->local_dynrel);
5200 head = (struct elf_dyn_relocs **) vpp;
5203 p = *head;
5204 if (p == NULL || p->sec != sec)
5206 bfd_size_type amt = sizeof *p;
5207 p = ((struct elf_dyn_relocs *)
5208 bfd_zalloc (htab->root.dynobj, amt));
5209 if (p == NULL)
5210 return FALSE;
5211 p->next = *head;
5212 *head = p;
5213 p->sec = sec;
5216 p->count += 1;
5219 break;
5221 /* RR: We probably want to keep a consistency check that
5222 there are no dangling GOT_PAGE relocs. */
5223 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
5224 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
5225 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
5226 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
5227 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
5228 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
5229 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
5230 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
5231 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
5232 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
5233 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
5234 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
5235 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
5236 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
5237 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
5238 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
5239 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
5240 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
5241 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
5242 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
5243 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
5245 unsigned got_type;
5246 unsigned old_got_type;
5248 got_type = aarch64_reloc_got_type (bfd_r_type);
5250 if (h)
5252 h->got.refcount += 1;
5253 old_got_type = elf_aarch64_hash_entry (h)->got_type;
5255 else
5257 struct elf_aarch64_local_symbol *locals;
5259 if (!elfNN_aarch64_allocate_local_symbols
5260 (abfd, symtab_hdr->sh_info))
5261 return FALSE;
5263 locals = elf_aarch64_locals (abfd);
5264 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
5265 locals[r_symndx].got_refcount += 1;
5266 old_got_type = locals[r_symndx].got_type;
5269 /* If a variable is accessed with both general dynamic TLS
5270 methods, two slots may be created. */
5271 if (GOT_TLS_GD_ANY_P (old_got_type) && GOT_TLS_GD_ANY_P (got_type))
5272 got_type |= old_got_type;
5274 /* We will already have issued an error message if there
5275 is a TLS/non-TLS mismatch, based on the symbol type.
5276 So just combine any TLS types needed. */
5277 if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
5278 && got_type != GOT_NORMAL)
5279 got_type |= old_got_type;
5281 /* If the symbol is accessed by both IE and GD methods, we
5282 are able to relax. Turn off the GD flag, without
5283 messing up with any other kind of TLS types that may be
5284 involved. */
5285 if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
5286 got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
5288 if (old_got_type != got_type)
5290 if (h != NULL)
5291 elf_aarch64_hash_entry (h)->got_type = got_type;
5292 else
5294 struct elf_aarch64_local_symbol *locals;
5295 locals = elf_aarch64_locals (abfd);
5296 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
5297 locals[r_symndx].got_type = got_type;
5301 if (htab->root.dynobj == NULL)
5302 htab->root.dynobj = abfd;
5303 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
5304 return FALSE;
5305 break;
5308 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
5309 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
5310 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
5311 if (h != NULL && info->executable)
5313 /* If this reloc is in a read-only section, we might
5314 need a copy reloc. We can't check reliably at this
5315 stage whether the section is read-only, as input
5316 sections have not yet been mapped to output sections.
5317 Tentatively set the flag for now, and correct in
5318 adjust_dynamic_symbol. */
5319 h->non_got_ref = 1;
5320 h->plt.refcount += 1;
5321 h->pointer_equality_needed = 1;
5323 /* FIXME:: RR need to handle these in shared libraries
5324 and essentially bomb out as these being non-PIC
5325 relocations in shared libraries. */
5326 break;
5328 case BFD_RELOC_AARCH64_CALL26:
5329 case BFD_RELOC_AARCH64_JUMP26:
5330 /* If this is a local symbol then we resolve it
5331 directly without creating a PLT entry. */
5332 if (h == NULL)
5333 continue;
5335 h->needs_plt = 1;
5336 if (h->plt.refcount <= 0)
5337 h->plt.refcount = 1;
5338 else
5339 h->plt.refcount += 1;
5340 break;
5342 default:
5343 break;
5347 return TRUE;
5350 /* Treat mapping symbols as special target symbols. */
5352 static bfd_boolean
5353 elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED,
5354 asymbol *sym)
5356 return bfd_is_aarch64_special_symbol_name (sym->name,
5357 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
5360 /* This is a copy of elf_find_function () from elf.c except that
5361 AArch64 mapping symbols are ignored when looking for function names. */
5363 static bfd_boolean
5364 aarch64_elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
5365 asection *section,
5366 asymbol **symbols,
5367 bfd_vma offset,
5368 const char **filename_ptr,
5369 const char **functionname_ptr)
5371 const char *filename = NULL;
5372 asymbol *func = NULL;
5373 bfd_vma low_func = 0;
5374 asymbol **p;
5376 for (p = symbols; *p != NULL; p++)
5378 elf_symbol_type *q;
5380 q = (elf_symbol_type *) * p;
5382 switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
5384 default:
5385 break;
5386 case STT_FILE:
5387 filename = bfd_asymbol_name (&q->symbol);
5388 break;
5389 case STT_FUNC:
5390 case STT_NOTYPE:
5391 /* Skip mapping symbols. */
5392 if ((q->symbol.flags & BSF_LOCAL)
5393 && (bfd_is_aarch64_special_symbol_name
5394 (q->symbol.name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)))
5395 continue;
5396 /* Fall through. */
5397 if (bfd_get_section (&q->symbol) == section
5398 && q->symbol.value >= low_func && q->symbol.value <= offset)
5400 func = (asymbol *) q;
5401 low_func = q->symbol.value;
5403 break;
5407 if (func == NULL)
5408 return FALSE;
5410 if (filename_ptr)
5411 *filename_ptr = filename;
5412 if (functionname_ptr)
5413 *functionname_ptr = bfd_asymbol_name (func);
5415 return TRUE;
5419 /* Find the nearest line to a particular section and offset, for error
5420 reporting. This code is a duplicate of the code in elf.c, except
5421 that it uses aarch64_elf_find_function. */
5423 static bfd_boolean
5424 elfNN_aarch64_find_nearest_line (bfd *abfd,
5425 asection *section,
5426 asymbol **symbols,
5427 bfd_vma offset,
5428 const char **filename_ptr,
5429 const char **functionname_ptr,
5430 unsigned int *line_ptr)
5432 bfd_boolean found = FALSE;
5434 /* We skip _bfd_dwarf1_find_nearest_line since no known AArch64
5435 toolchain uses it. */
5437 if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
5438 section, symbols, offset,
5439 filename_ptr, functionname_ptr,
5440 line_ptr, NULL, 0,
5441 &elf_tdata (abfd)->dwarf2_find_line_info))
5443 if (!*functionname_ptr)
5444 aarch64_elf_find_function (abfd, section, symbols, offset,
5445 *filename_ptr ? NULL : filename_ptr,
5446 functionname_ptr);
5448 return TRUE;
5451 if (!_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
5452 &found, filename_ptr,
5453 functionname_ptr, line_ptr,
5454 &elf_tdata (abfd)->line_info))
5455 return FALSE;
5457 if (found && (*functionname_ptr || *line_ptr))
5458 return TRUE;
5460 if (symbols == NULL)
5461 return FALSE;
5463 if (!aarch64_elf_find_function (abfd, section, symbols, offset,
5464 filename_ptr, functionname_ptr))
5465 return FALSE;
5467 *line_ptr = 0;
5468 return TRUE;
5471 static bfd_boolean
5472 elfNN_aarch64_find_inliner_info (bfd *abfd,
5473 const char **filename_ptr,
5474 const char **functionname_ptr,
5475 unsigned int *line_ptr)
5477 bfd_boolean found;
5478 found = _bfd_dwarf2_find_inliner_info
5479 (abfd, filename_ptr,
5480 functionname_ptr, line_ptr, &elf_tdata (abfd)->dwarf2_find_line_info);
5481 return found;
5485 static void
5486 elfNN_aarch64_post_process_headers (bfd *abfd,
5487 struct bfd_link_info *link_info)
5489 Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
5491 i_ehdrp = elf_elfheader (abfd);
5492 i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
5494 _bfd_elf_set_osabi (abfd, link_info);
5497 static enum elf_reloc_type_class
5498 elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
5499 const asection *rel_sec ATTRIBUTE_UNUSED,
5500 const Elf_Internal_Rela *rela)
5502 switch ((int) ELFNN_R_TYPE (rela->r_info))
5504 case AARCH64_R (RELATIVE):
5505 return reloc_class_relative;
5506 case AARCH64_R (JUMP_SLOT):
5507 return reloc_class_plt;
5508 case AARCH64_R (COPY):
5509 return reloc_class_copy;
5510 default:
5511 return reloc_class_normal;
5515 /* Set the right machine number for an AArch64 ELF file. */
5517 static bfd_boolean
5518 elfNN_aarch64_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
5520 if (hdr->sh_type == SHT_NOTE)
5521 *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
5523 return TRUE;
5526 /* Handle an AArch64 specific section when reading an object file. This is
5527 called when bfd_section_from_shdr finds a section with an unknown
5528 type. */
5530 static bfd_boolean
5531 elfNN_aarch64_section_from_shdr (bfd *abfd,
5532 Elf_Internal_Shdr *hdr,
5533 const char *name, int shindex)
5535 /* There ought to be a place to keep ELF backend specific flags, but
5536 at the moment there isn't one. We just keep track of the
5537 sections by their name, instead. Fortunately, the ABI gives
5538 names for all the AArch64 specific sections, so we will probably get
5539 away with this. */
5540 switch (hdr->sh_type)
5542 case SHT_AARCH64_ATTRIBUTES:
5543 break;
5545 default:
5546 return FALSE;
5549 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5550 return FALSE;
5552 return TRUE;
5555 /* A structure used to record a list of sections, independently
5556 of the next and prev fields in the asection structure. */
5557 typedef struct section_list
5559 asection *sec;
5560 struct section_list *next;
5561 struct section_list *prev;
5563 section_list;
5565 /* Unfortunately we need to keep a list of sections for which
5566 an _aarch64_elf_section_data structure has been allocated. This
5567 is because it is possible for functions like elfNN_aarch64_write_section
5568 to be called on a section which has had an elf_data_structure
5569 allocated for it (and so the used_by_bfd field is valid) but
5570 for which the AArch64 extended version of this structure - the
5571 _aarch64_elf_section_data structure - has not been allocated. */
5572 static section_list *sections_with_aarch64_elf_section_data = NULL;
5574 static void
5575 record_section_with_aarch64_elf_section_data (asection *sec)
5577 struct section_list *entry;
5579 entry = bfd_malloc (sizeof (*entry));
5580 if (entry == NULL)
5581 return;
5582 entry->sec = sec;
5583 entry->next = sections_with_aarch64_elf_section_data;
5584 entry->prev = NULL;
5585 if (entry->next != NULL)
5586 entry->next->prev = entry;
5587 sections_with_aarch64_elf_section_data = entry;
5590 static struct section_list *
5591 find_aarch64_elf_section_entry (asection *sec)
5593 struct section_list *entry;
5594 static struct section_list *last_entry = NULL;
5596 /* This is a short cut for the typical case where the sections are added
5597 to the sections_with_aarch64_elf_section_data list in forward order and
5598 then looked up here in backwards order. This makes a real difference
5599 to the ld-srec/sec64k.exp linker test. */
5600 entry = sections_with_aarch64_elf_section_data;
5601 if (last_entry != NULL)
5603 if (last_entry->sec == sec)
5604 entry = last_entry;
5605 else if (last_entry->next != NULL && last_entry->next->sec == sec)
5606 entry = last_entry->next;
5609 for (; entry; entry = entry->next)
5610 if (entry->sec == sec)
5611 break;
5613 if (entry)
5614 /* Record the entry prior to this one - it is the entry we are
5615 most likely to want to locate next time. Also this way if we
5616 have been called from
5617 unrecord_section_with_aarch64_elf_section_data () we will not
5618 be caching a pointer that is about to be freed. */
5619 last_entry = entry->prev;
5621 return entry;
5624 static void
5625 unrecord_section_with_aarch64_elf_section_data (asection *sec)
5627 struct section_list *entry;
5629 entry = find_aarch64_elf_section_entry (sec);
5631 if (entry)
5633 if (entry->prev != NULL)
5634 entry->prev->next = entry->next;
5635 if (entry->next != NULL)
5636 entry->next->prev = entry->prev;
5637 if (entry == sections_with_aarch64_elf_section_data)
5638 sections_with_aarch64_elf_section_data = entry->next;
5639 free (entry);
5644 typedef struct
5646 void *finfo;
5647 struct bfd_link_info *info;
5648 asection *sec;
5649 int sec_shndx;
5650 int (*func) (void *, const char *, Elf_Internal_Sym *,
5651 asection *, struct elf_link_hash_entry *);
5652 } output_arch_syminfo;
5654 enum map_symbol_type
5656 AARCH64_MAP_INSN,
5657 AARCH64_MAP_DATA
5661 /* Output a single mapping symbol. */
5663 static bfd_boolean
5664 elfNN_aarch64_output_map_sym (output_arch_syminfo *osi,
5665 enum map_symbol_type type, bfd_vma offset)
5667 static const char *names[2] = { "$x", "$d" };
5668 Elf_Internal_Sym sym;
5670 sym.st_value = (osi->sec->output_section->vma
5671 + osi->sec->output_offset + offset);
5672 sym.st_size = 0;
5673 sym.st_other = 0;
5674 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
5675 sym.st_shndx = osi->sec_shndx;
5676 return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
5681 /* Output mapping symbols for PLT entries associated with H. */
5683 static bfd_boolean
5684 elfNN_aarch64_output_plt_map (struct elf_link_hash_entry *h, void *inf)
5686 output_arch_syminfo *osi = (output_arch_syminfo *) inf;
5687 bfd_vma addr;
5689 if (h->root.type == bfd_link_hash_indirect)
5690 return TRUE;
5692 if (h->root.type == bfd_link_hash_warning)
5693 /* When warning symbols are created, they **replace** the "real"
5694 entry in the hash table, thus we never get to see the real
5695 symbol in a hash traversal. So look at it now. */
5696 h = (struct elf_link_hash_entry *) h->root.u.i.link;
5698 if (h->plt.offset == (bfd_vma) - 1)
5699 return TRUE;
5701 addr = h->plt.offset;
5702 if (addr == 32)
5704 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
5705 return FALSE;
5707 return TRUE;
5711 /* Output a single local symbol for a generated stub. */
5713 static bfd_boolean
5714 elfNN_aarch64_output_stub_sym (output_arch_syminfo *osi, const char *name,
5715 bfd_vma offset, bfd_vma size)
5717 Elf_Internal_Sym sym;
5719 sym.st_value = (osi->sec->output_section->vma
5720 + osi->sec->output_offset + offset);
5721 sym.st_size = size;
5722 sym.st_other = 0;
5723 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
5724 sym.st_shndx = osi->sec_shndx;
5725 return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
5728 static bfd_boolean
5729 aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
5731 struct elf_aarch64_stub_hash_entry *stub_entry;
5732 asection *stub_sec;
5733 bfd_vma addr;
5734 char *stub_name;
5735 output_arch_syminfo *osi;
5737 /* Massage our args to the form they really have. */
5738 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
5739 osi = (output_arch_syminfo *) in_arg;
5741 stub_sec = stub_entry->stub_sec;
5743 /* Ensure this stub is attached to the current section being
5744 processed. */
5745 if (stub_sec != osi->sec)
5746 return TRUE;
5748 addr = (bfd_vma) stub_entry->stub_offset;
5750 stub_name = stub_entry->output_name;
5752 switch (stub_entry->stub_type)
5754 case aarch64_stub_adrp_branch:
5755 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
5756 sizeof (aarch64_adrp_branch_stub)))
5757 return FALSE;
5758 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
5759 return FALSE;
5760 break;
5761 case aarch64_stub_long_branch:
5762 if (!elfNN_aarch64_output_stub_sym
5763 (osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
5764 return FALSE;
5765 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
5766 return FALSE;
5767 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_DATA, addr + 16))
5768 return FALSE;
5769 break;
5770 default:
5771 BFD_FAIL ();
5774 return TRUE;
5777 /* Output mapping symbols for linker generated sections. */
5779 static bfd_boolean
5780 elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
5781 struct bfd_link_info *info,
5782 void *finfo,
5783 int (*func) (void *, const char *,
5784 Elf_Internal_Sym *,
5785 asection *,
5786 struct elf_link_hash_entry
5789 output_arch_syminfo osi;
5790 struct elf_aarch64_link_hash_table *htab;
5792 htab = elf_aarch64_hash_table (info);
5794 osi.finfo = finfo;
5795 osi.info = info;
5796 osi.func = func;
5798 /* Long calls stubs. */
5799 if (htab->stub_bfd && htab->stub_bfd->sections)
5801 asection *stub_sec;
5803 for (stub_sec = htab->stub_bfd->sections;
5804 stub_sec != NULL; stub_sec = stub_sec->next)
5806 /* Ignore non-stub sections. */
5807 if (!strstr (stub_sec->name, STUB_SUFFIX))
5808 continue;
5810 osi.sec = stub_sec;
5812 osi.sec_shndx = _bfd_elf_section_from_bfd_section
5813 (output_bfd, osi.sec->output_section);
5815 bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
5816 &osi);
5820 /* Finally, output mapping symbols for the PLT. */
5821 if (!htab->root.splt || htab->root.splt->size == 0)
5822 return TRUE;
5824 /* For now live without mapping symbols for the plt. */
5825 osi.sec_shndx = _bfd_elf_section_from_bfd_section
5826 (output_bfd, htab->root.splt->output_section);
5827 osi.sec = htab->root.splt;
5829 elf_link_hash_traverse (&htab->root, elfNN_aarch64_output_plt_map,
5830 (void *) &osi);
5832 return TRUE;
5836 /* Allocate target specific section data. */
5838 static bfd_boolean
5839 elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec)
5841 if (!sec->used_by_bfd)
5843 _aarch64_elf_section_data *sdata;
5844 bfd_size_type amt = sizeof (*sdata);
5846 sdata = bfd_zalloc (abfd, amt);
5847 if (sdata == NULL)
5848 return FALSE;
5849 sec->used_by_bfd = sdata;
5852 record_section_with_aarch64_elf_section_data (sec);
5854 return _bfd_elf_new_section_hook (abfd, sec);
5858 static void
5859 unrecord_section_via_map_over_sections (bfd *abfd ATTRIBUTE_UNUSED,
5860 asection *sec,
5861 void *ignore ATTRIBUTE_UNUSED)
5863 unrecord_section_with_aarch64_elf_section_data (sec);
5866 static bfd_boolean
5867 elfNN_aarch64_close_and_cleanup (bfd *abfd)
5869 if (abfd->sections)
5870 bfd_map_over_sections (abfd,
5871 unrecord_section_via_map_over_sections, NULL);
5873 return _bfd_elf_close_and_cleanup (abfd);
5876 static bfd_boolean
5877 elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
5879 if (abfd->sections)
5880 bfd_map_over_sections (abfd,
5881 unrecord_section_via_map_over_sections, NULL);
5883 return _bfd_free_cached_info (abfd);
5886 /* Create dynamic sections. This is different from the ARM backend in that
5887 the got, plt, gotplt and their relocation sections are all created in the
5888 standard part of the bfd elf backend. */
5890 static bfd_boolean
5891 elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
5892 struct bfd_link_info *info)
5894 struct elf_aarch64_link_hash_table *htab;
5896 /* We need to create .got section. */
5897 if (!aarch64_elf_create_got_section (dynobj, info))
5898 return FALSE;
5900 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
5901 return FALSE;
5903 htab = elf_aarch64_hash_table (info);
5904 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
5905 if (!info->shared)
5906 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
5908 if (!htab->sdynbss || (!info->shared && !htab->srelbss))
5909 abort ();
5911 return TRUE;
5915 /* Allocate space in .plt, .got and associated reloc sections for
5916 dynamic relocs. */
5918 static bfd_boolean
5919 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
5921 struct bfd_link_info *info;
5922 struct elf_aarch64_link_hash_table *htab;
5923 struct elf_aarch64_link_hash_entry *eh;
5924 struct elf_dyn_relocs *p;
5926 /* An example of a bfd_link_hash_indirect symbol is versioned
5927 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
5928 -> __gxx_personality_v0(bfd_link_hash_defined)
5930 There is no need to process bfd_link_hash_indirect symbols here
5931 because we will also be presented with the concrete instance of
5932 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
5933 called to copy all relevant data from the generic to the concrete
5934 symbol instance.
5936 if (h->root.type == bfd_link_hash_indirect)
5937 return TRUE;
5939 if (h->root.type == bfd_link_hash_warning)
5940 h = (struct elf_link_hash_entry *) h->root.u.i.link;
5942 info = (struct bfd_link_info *) inf;
5943 htab = elf_aarch64_hash_table (info);
5945 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
5946 here if it is defined and referenced in a non-shared object. */
5947 if (h->type == STT_GNU_IFUNC
5948 && h->def_regular)
5949 return TRUE;
5950 else if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
5952 /* Make sure this symbol is output as a dynamic symbol.
5953 Undefined weak syms won't yet be marked as dynamic. */
5954 if (h->dynindx == -1 && !h->forced_local)
5956 if (!bfd_elf_link_record_dynamic_symbol (info, h))
5957 return FALSE;
5960 if (info->shared || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
5962 asection *s = htab->root.splt;
5964 /* If this is the first .plt entry, make room for the special
5965 first entry. */
5966 if (s->size == 0)
5967 s->size += htab->plt_header_size;
5969 h->plt.offset = s->size;
5971 /* If this symbol is not defined in a regular file, and we are
5972 not generating a shared library, then set the symbol to this
5973 location in the .plt. This is required to make function
5974 pointers compare as equal between the normal executable and
5975 the shared library. */
5976 if (!info->shared && !h->def_regular)
5978 h->root.u.def.section = s;
5979 h->root.u.def.value = h->plt.offset;
5982 /* Make room for this entry. For now we only create the
5983 small model PLT entries. We later need to find a way
5984 of relaxing into these from the large model PLT entries. */
5985 s->size += PLT_SMALL_ENTRY_SIZE;
5987 /* We also need to make an entry in the .got.plt section, which
5988 will be placed in the .got section by the linker script. */
5989 htab->root.sgotplt->size += GOT_ENTRY_SIZE;
5991 /* We also need to make an entry in the .rela.plt section. */
5992 htab->root.srelplt->size += RELOC_SIZE (htab);
5994 /* We need to ensure that all GOT entries that serve the PLT
5995 are consecutive with the special GOT slots [0] [1] and
5996 [2]. Any addtional relocations, such as
5997 R_AARCH64_TLSDESC, must be placed after the PLT related
5998 entries. We abuse the reloc_count such that during
5999 sizing we adjust reloc_count to indicate the number of
6000 PLT related reserved entries. In subsequent phases when
6001 filling in the contents of the reloc entries, PLT related
6002 entries are placed by computing their PLT index (0
6003 .. reloc_count). While other none PLT relocs are placed
6004 at the slot indicated by reloc_count and reloc_count is
6005 updated. */
6007 htab->root.srelplt->reloc_count++;
6009 else
6011 h->plt.offset = (bfd_vma) - 1;
6012 h->needs_plt = 0;
6015 else
6017 h->plt.offset = (bfd_vma) - 1;
6018 h->needs_plt = 0;
6021 eh = (struct elf_aarch64_link_hash_entry *) h;
6022 eh->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
6024 if (h->got.refcount > 0)
6026 bfd_boolean dyn;
6027 unsigned got_type = elf_aarch64_hash_entry (h)->got_type;
6029 h->got.offset = (bfd_vma) - 1;
6031 dyn = htab->root.dynamic_sections_created;
6033 /* Make sure this symbol is output as a dynamic symbol.
6034 Undefined weak syms won't yet be marked as dynamic. */
6035 if (dyn && h->dynindx == -1 && !h->forced_local)
6037 if (!bfd_elf_link_record_dynamic_symbol (info, h))
6038 return FALSE;
6041 if (got_type == GOT_UNKNOWN)
6044 else if (got_type == GOT_NORMAL)
6046 h->got.offset = htab->root.sgot->size;
6047 htab->root.sgot->size += GOT_ENTRY_SIZE;
6048 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
6049 || h->root.type != bfd_link_hash_undefweak)
6050 && (info->shared
6051 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
6053 htab->root.srelgot->size += RELOC_SIZE (htab);
6056 else
6058 int indx;
6059 if (got_type & GOT_TLSDESC_GD)
6061 eh->tlsdesc_got_jump_table_offset =
6062 (htab->root.sgotplt->size
6063 - aarch64_compute_jump_table_size (htab));
6064 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
6065 h->got.offset = (bfd_vma) - 2;
6068 if (got_type & GOT_TLS_GD)
6070 h->got.offset = htab->root.sgot->size;
6071 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
6074 if (got_type & GOT_TLS_IE)
6076 h->got.offset = htab->root.sgot->size;
6077 htab->root.sgot->size += GOT_ENTRY_SIZE;
6080 indx = h && h->dynindx != -1 ? h->dynindx : 0;
6081 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
6082 || h->root.type != bfd_link_hash_undefweak)
6083 && (info->shared
6084 || indx != 0
6085 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
6087 if (got_type & GOT_TLSDESC_GD)
6089 htab->root.srelplt->size += RELOC_SIZE (htab);
6090 /* Note reloc_count not incremented here! We have
6091 already adjusted reloc_count for this relocation
6092 type. */
6094 /* TLSDESC PLT is now needed, but not yet determined. */
6095 htab->tlsdesc_plt = (bfd_vma) - 1;
6098 if (got_type & GOT_TLS_GD)
6099 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
6101 if (got_type & GOT_TLS_IE)
6102 htab->root.srelgot->size += RELOC_SIZE (htab);
6106 else
6108 h->got.offset = (bfd_vma) - 1;
6111 if (eh->dyn_relocs == NULL)
6112 return TRUE;
6114 /* In the shared -Bsymbolic case, discard space allocated for
6115 dynamic pc-relative relocs against symbols which turn out to be
6116 defined in regular objects. For the normal shared case, discard
6117 space for pc-relative relocs that have become local due to symbol
6118 visibility changes. */
6120 if (info->shared)
6122 /* Relocs that use pc_count are those that appear on a call
6123 insn, or certain REL relocs that can generated via assembly.
6124 We want calls to protected symbols to resolve directly to the
6125 function rather than going via the plt. If people want
6126 function pointer comparisons to work as expected then they
6127 should avoid writing weird assembly. */
6128 if (SYMBOL_CALLS_LOCAL (info, h))
6130 struct elf_dyn_relocs **pp;
6132 for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
6134 p->count -= p->pc_count;
6135 p->pc_count = 0;
6136 if (p->count == 0)
6137 *pp = p->next;
6138 else
6139 pp = &p->next;
6143 /* Also discard relocs on undefined weak syms with non-default
6144 visibility. */
6145 if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
6147 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
6148 eh->dyn_relocs = NULL;
6150 /* Make sure undefined weak symbols are output as a dynamic
6151 symbol in PIEs. */
6152 else if (h->dynindx == -1
6153 && !h->forced_local
6154 && !bfd_elf_link_record_dynamic_symbol (info, h))
6155 return FALSE;
6159 else if (ELIMINATE_COPY_RELOCS)
6161 /* For the non-shared case, discard space for relocs against
6162 symbols which turn out to need copy relocs or are not
6163 dynamic. */
6165 if (!h->non_got_ref
6166 && ((h->def_dynamic
6167 && !h->def_regular)
6168 || (htab->root.dynamic_sections_created
6169 && (h->root.type == bfd_link_hash_undefweak
6170 || h->root.type == bfd_link_hash_undefined))))
6172 /* Make sure this symbol is output as a dynamic symbol.
6173 Undefined weak syms won't yet be marked as dynamic. */
6174 if (h->dynindx == -1
6175 && !h->forced_local
6176 && !bfd_elf_link_record_dynamic_symbol (info, h))
6177 return FALSE;
6179 /* If that succeeded, we know we'll be keeping all the
6180 relocs. */
6181 if (h->dynindx != -1)
6182 goto keep;
6185 eh->dyn_relocs = NULL;
6187 keep:;
6190 /* Finally, allocate space. */
6191 for (p = eh->dyn_relocs; p != NULL; p = p->next)
6193 asection *sreloc;
6195 sreloc = elf_section_data (p->sec)->sreloc;
6197 BFD_ASSERT (sreloc != NULL);
6199 sreloc->size += p->count * RELOC_SIZE (htab);
6202 return TRUE;
6205 /* Allocate space in .plt, .got and associated reloc sections for
6206 ifunc dynamic relocs. */
6208 static bfd_boolean
6209 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
6210 void *inf)
6212 struct bfd_link_info *info;
6213 struct elf_aarch64_link_hash_table *htab;
6214 struct elf_aarch64_link_hash_entry *eh;
6216 /* An example of a bfd_link_hash_indirect symbol is versioned
6217 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
6218 -> __gxx_personality_v0(bfd_link_hash_defined)
6220 There is no need to process bfd_link_hash_indirect symbols here
6221 because we will also be presented with the concrete instance of
6222 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
6223 called to copy all relevant data from the generic to the concrete
6224 symbol instance.
6226 if (h->root.type == bfd_link_hash_indirect)
6227 return TRUE;
6229 if (h->root.type == bfd_link_hash_warning)
6230 h = (struct elf_link_hash_entry *) h->root.u.i.link;
6232 info = (struct bfd_link_info *) inf;
6233 htab = elf_aarch64_hash_table (info);
6235 eh = (struct elf_aarch64_link_hash_entry *) h;
6237 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
6238 here if it is defined and referenced in a non-shared object. */
6239 if (h->type == STT_GNU_IFUNC
6240 && h->def_regular)
6241 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
6242 &eh->dyn_relocs,
6243 htab->plt_entry_size,
6244 htab->plt_header_size,
6245 GOT_ENTRY_SIZE);
6246 return TRUE;
6249 /* Allocate space in .plt, .got and associated reloc sections for
6250 local dynamic relocs. */
6252 static bfd_boolean
6253 elfNN_aarch64_allocate_local_dynrelocs (void **slot, void *inf)
6255 struct elf_link_hash_entry *h
6256 = (struct elf_link_hash_entry *) *slot;
6258 if (h->type != STT_GNU_IFUNC
6259 || !h->def_regular
6260 || !h->ref_regular
6261 || !h->forced_local
6262 || h->root.type != bfd_link_hash_defined)
6263 abort ();
6265 return elfNN_aarch64_allocate_dynrelocs (h, inf);
6268 /* Allocate space in .plt, .got and associated reloc sections for
6269 local ifunc dynamic relocs. */
6271 static bfd_boolean
6272 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
6274 struct elf_link_hash_entry *h
6275 = (struct elf_link_hash_entry *) *slot;
6277 if (h->type != STT_GNU_IFUNC
6278 || !h->def_regular
6279 || !h->ref_regular
6280 || !h->forced_local
6281 || h->root.type != bfd_link_hash_defined)
6282 abort ();
6284 return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
6287 /* This is the most important function of all . Innocuosly named
6288 though ! */
6289 static bfd_boolean
6290 elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
6291 struct bfd_link_info *info)
6293 struct elf_aarch64_link_hash_table *htab;
6294 bfd *dynobj;
6295 asection *s;
6296 bfd_boolean relocs;
6297 bfd *ibfd;
6299 htab = elf_aarch64_hash_table ((info));
6300 dynobj = htab->root.dynobj;
6302 BFD_ASSERT (dynobj != NULL);
6304 if (htab->root.dynamic_sections_created)
6306 if (info->executable)
6308 s = bfd_get_linker_section (dynobj, ".interp");
6309 if (s == NULL)
6310 abort ();
6311 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
6312 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
6316 /* Set up .got offsets for local syms, and space for local dynamic
6317 relocs. */
6318 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
6320 struct elf_aarch64_local_symbol *locals = NULL;
6321 Elf_Internal_Shdr *symtab_hdr;
6322 asection *srel;
6323 unsigned int i;
6325 if (!is_aarch64_elf (ibfd))
6326 continue;
6328 for (s = ibfd->sections; s != NULL; s = s->next)
6330 struct elf_dyn_relocs *p;
6332 for (p = (struct elf_dyn_relocs *)
6333 (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
6335 if (!bfd_is_abs_section (p->sec)
6336 && bfd_is_abs_section (p->sec->output_section))
6338 /* Input section has been discarded, either because
6339 it is a copy of a linkonce section or due to
6340 linker script /DISCARD/, so we'll be discarding
6341 the relocs too. */
6343 else if (p->count != 0)
6345 srel = elf_section_data (p->sec)->sreloc;
6346 srel->size += p->count * RELOC_SIZE (htab);
6347 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
6348 info->flags |= DF_TEXTREL;
6353 locals = elf_aarch64_locals (ibfd);
6354 if (!locals)
6355 continue;
6357 symtab_hdr = &elf_symtab_hdr (ibfd);
6358 srel = htab->root.srelgot;
6359 for (i = 0; i < symtab_hdr->sh_info; i++)
6361 locals[i].got_offset = (bfd_vma) - 1;
6362 locals[i].tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
6363 if (locals[i].got_refcount > 0)
6365 unsigned got_type = locals[i].got_type;
6366 if (got_type & GOT_TLSDESC_GD)
6368 locals[i].tlsdesc_got_jump_table_offset =
6369 (htab->root.sgotplt->size
6370 - aarch64_compute_jump_table_size (htab));
6371 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
6372 locals[i].got_offset = (bfd_vma) - 2;
6375 if (got_type & GOT_TLS_GD)
6377 locals[i].got_offset = htab->root.sgot->size;
6378 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
6381 if (got_type & GOT_TLS_IE)
6383 locals[i].got_offset = htab->root.sgot->size;
6384 htab->root.sgot->size += GOT_ENTRY_SIZE;
6387 if (got_type == GOT_UNKNOWN)
6391 if (got_type == GOT_NORMAL)
6395 if (info->shared)
6397 if (got_type & GOT_TLSDESC_GD)
6399 htab->root.srelplt->size += RELOC_SIZE (htab);
6400 /* Note RELOC_COUNT not incremented here! */
6401 htab->tlsdesc_plt = (bfd_vma) - 1;
6404 if (got_type & GOT_TLS_GD)
6405 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
6407 if (got_type & GOT_TLS_IE)
6408 htab->root.srelgot->size += RELOC_SIZE (htab);
6411 else
6413 locals[i].got_refcount = (bfd_vma) - 1;
6419 /* Allocate global sym .plt and .got entries, and space for global
6420 sym dynamic relocs. */
6421 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
6422 info);
6424 /* Allocate global ifunc sym .plt and .got entries, and space for global
6425 ifunc sym dynamic relocs. */
6426 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_ifunc_dynrelocs,
6427 info);
6429 /* Allocate .plt and .got entries, and space for local symbols. */
6430 htab_traverse (htab->loc_hash_table,
6431 elfNN_aarch64_allocate_local_dynrelocs,
6432 info);
6434 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
6435 htab_traverse (htab->loc_hash_table,
6436 elfNN_aarch64_allocate_local_ifunc_dynrelocs,
6437 info);
6439 /* For every jump slot reserved in the sgotplt, reloc_count is
6440 incremented. However, when we reserve space for TLS descriptors,
6441 it's not incremented, so in order to compute the space reserved
6442 for them, it suffices to multiply the reloc count by the jump
6443 slot size. */
6445 if (htab->root.srelplt)
6446 htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab);
6448 if (htab->tlsdesc_plt)
6450 if (htab->root.splt->size == 0)
6451 htab->root.splt->size += PLT_ENTRY_SIZE;
6453 htab->tlsdesc_plt = htab->root.splt->size;
6454 htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
6456 /* If we're not using lazy TLS relocations, don't generate the
6457 GOT entry required. */
6458 if (!(info->flags & DF_BIND_NOW))
6460 htab->dt_tlsdesc_got = htab->root.sgot->size;
6461 htab->root.sgot->size += GOT_ENTRY_SIZE;
6465 /* We now have determined the sizes of the various dynamic sections.
6466 Allocate memory for them. */
6467 relocs = FALSE;
6468 for (s = dynobj->sections; s != NULL; s = s->next)
6470 if ((s->flags & SEC_LINKER_CREATED) == 0)
6471 continue;
6473 if (s == htab->root.splt
6474 || s == htab->root.sgot
6475 || s == htab->root.sgotplt
6476 || s == htab->root.iplt
6477 || s == htab->root.igotplt || s == htab->sdynbss)
6479 /* Strip this section if we don't need it; see the
6480 comment below. */
6482 else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
6484 if (s->size != 0 && s != htab->root.srelplt)
6485 relocs = TRUE;
6487 /* We use the reloc_count field as a counter if we need
6488 to copy relocs into the output file. */
6489 if (s != htab->root.srelplt)
6490 s->reloc_count = 0;
6492 else
6494 /* It's not one of our sections, so don't allocate space. */
6495 continue;
6498 if (s->size == 0)
6500 /* If we don't need this section, strip it from the
6501 output file. This is mostly to handle .rela.bss and
6502 .rela.plt. We must create both sections in
6503 create_dynamic_sections, because they must be created
6504 before the linker maps input sections to output
6505 sections. The linker does that before
6506 adjust_dynamic_symbol is called, and it is that
6507 function which decides whether anything needs to go
6508 into these sections. */
6510 s->flags |= SEC_EXCLUDE;
6511 continue;
6514 if ((s->flags & SEC_HAS_CONTENTS) == 0)
6515 continue;
6517 /* Allocate memory for the section contents. We use bfd_zalloc
6518 here in case unused entries are not reclaimed before the
6519 section's contents are written out. This should not happen,
6520 but this way if it does, we get a R_AARCH64_NONE reloc instead
6521 of garbage. */
6522 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
6523 if (s->contents == NULL)
6524 return FALSE;
6527 if (htab->root.dynamic_sections_created)
6529 /* Add some entries to the .dynamic section. We fill in the
6530 values later, in elfNN_aarch64_finish_dynamic_sections, but we
6531 must add the entries now so that we get the correct size for
6532 the .dynamic section. The DT_DEBUG entry is filled in by the
6533 dynamic linker and used by the debugger. */
6534 #define add_dynamic_entry(TAG, VAL) \
6535 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
6537 if (info->executable)
6539 if (!add_dynamic_entry (DT_DEBUG, 0))
6540 return FALSE;
6543 if (htab->root.splt->size != 0)
6545 if (!add_dynamic_entry (DT_PLTGOT, 0)
6546 || !add_dynamic_entry (DT_PLTRELSZ, 0)
6547 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
6548 || !add_dynamic_entry (DT_JMPREL, 0))
6549 return FALSE;
6551 if (htab->tlsdesc_plt
6552 && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
6553 || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
6554 return FALSE;
6557 if (relocs)
6559 if (!add_dynamic_entry (DT_RELA, 0)
6560 || !add_dynamic_entry (DT_RELASZ, 0)
6561 || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
6562 return FALSE;
6564 /* If any dynamic relocs apply to a read-only section,
6565 then we need a DT_TEXTREL entry. */
6566 if ((info->flags & DF_TEXTREL) != 0)
6568 if (!add_dynamic_entry (DT_TEXTREL, 0))
6569 return FALSE;
6573 #undef add_dynamic_entry
6575 return TRUE;
6578 static inline void
6579 elf_aarch64_update_plt_entry (bfd *output_bfd,
6580 bfd_reloc_code_real_type r_type,
6581 bfd_byte *plt_entry, bfd_vma value)
6583 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
6585 _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
6588 static void
6589 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
6590 struct elf_aarch64_link_hash_table
6591 *htab, bfd *output_bfd,
6592 struct bfd_link_info *info)
6594 bfd_byte *plt_entry;
6595 bfd_vma plt_index;
6596 bfd_vma got_offset;
6597 bfd_vma gotplt_entry_address;
6598 bfd_vma plt_entry_address;
6599 Elf_Internal_Rela rela;
6600 bfd_byte *loc;
6601 asection *plt, *gotplt, *relplt;
6603 /* When building a static executable, use .iplt, .igot.plt and
6604 .rela.iplt sections for STT_GNU_IFUNC symbols. */
6605 if (htab->root.splt != NULL)
6607 plt = htab->root.splt;
6608 gotplt = htab->root.sgotplt;
6609 relplt = htab->root.srelplt;
6611 else
6613 plt = htab->root.iplt;
6614 gotplt = htab->root.igotplt;
6615 relplt = htab->root.irelplt;
6618 /* Get the index in the procedure linkage table which
6619 corresponds to this symbol. This is the index of this symbol
6620 in all the symbols for which we are making plt entries. The
6621 first entry in the procedure linkage table is reserved.
6623 Get the offset into the .got table of the entry that
6624 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
6625 bytes. The first three are reserved for the dynamic linker.
6627 For static executables, we don't reserve anything. */
6629 if (plt == htab->root.splt)
6631 plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
6632 got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
6634 else
6636 plt_index = h->plt.offset / htab->plt_entry_size;
6637 got_offset = plt_index * GOT_ENTRY_SIZE;
6640 plt_entry = plt->contents + h->plt.offset;
6641 plt_entry_address = plt->output_section->vma
6642 + plt->output_section->output_offset + h->plt.offset;
6643 gotplt_entry_address = gotplt->output_section->vma +
6644 gotplt->output_offset + got_offset;
6646 /* Copy in the boiler-plate for the PLTn entry. */
6647 memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
6649 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
6650 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
6651 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
6652 plt_entry,
6653 PG (gotplt_entry_address) -
6654 PG (plt_entry_address));
6656 /* Fill in the lo12 bits for the load from the pltgot. */
6657 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
6658 plt_entry + 4,
6659 PG_OFFSET (gotplt_entry_address));
6661 /* Fill in the lo12 bits for the add from the pltgot entry. */
6662 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
6663 plt_entry + 8,
6664 PG_OFFSET (gotplt_entry_address));
6666 /* All the GOTPLT Entries are essentially initialized to PLT0. */
6667 bfd_put_NN (output_bfd,
6668 plt->output_section->vma + plt->output_offset,
6669 gotplt->contents + got_offset);
6671 rela.r_offset = gotplt_entry_address;
6673 if (h->dynindx == -1
6674 || ((info->executable
6675 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
6676 && h->def_regular
6677 && h->type == STT_GNU_IFUNC))
6679 /* If an STT_GNU_IFUNC symbol is locally defined, generate
6680 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
6681 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
6682 rela.r_addend = (h->root.u.def.value
6683 + h->root.u.def.section->output_section->vma
6684 + h->root.u.def.section->output_offset);
6686 else
6688 /* Fill in the entry in the .rela.plt section. */
6689 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
6690 rela.r_addend = 0;
6693 /* Compute the relocation entry to used based on PLT index and do
6694 not adjust reloc_count. The reloc_count has already been adjusted
6695 to account for this entry. */
6696 loc = relplt->contents + plt_index * RELOC_SIZE (htab);
6697 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6700 /* Size sections even though they're not dynamic. We use it to setup
6701 _TLS_MODULE_BASE_, if needed. */
6703 static bfd_boolean
6704 elfNN_aarch64_always_size_sections (bfd *output_bfd,
6705 struct bfd_link_info *info)
6707 asection *tls_sec;
6709 if (info->relocatable)
6710 return TRUE;
6712 tls_sec = elf_hash_table (info)->tls_sec;
6714 if (tls_sec)
6716 struct elf_link_hash_entry *tlsbase;
6718 tlsbase = elf_link_hash_lookup (elf_hash_table (info),
6719 "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
6721 if (tlsbase)
6723 struct bfd_link_hash_entry *h = NULL;
6724 const struct elf_backend_data *bed =
6725 get_elf_backend_data (output_bfd);
6727 if (!(_bfd_generic_link_add_one_symbol
6728 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
6729 tls_sec, 0, NULL, FALSE, bed->collect, &h)))
6730 return FALSE;
6732 tlsbase->type = STT_TLS;
6733 tlsbase = (struct elf_link_hash_entry *) h;
6734 tlsbase->def_regular = 1;
6735 tlsbase->other = STV_HIDDEN;
6736 (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
6740 return TRUE;
6743 /* Finish up dynamic symbol handling. We set the contents of various
6744 dynamic sections here. */
6745 static bfd_boolean
6746 elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
6747 struct bfd_link_info *info,
6748 struct elf_link_hash_entry *h,
6749 Elf_Internal_Sym *sym)
6751 struct elf_aarch64_link_hash_table *htab;
6752 htab = elf_aarch64_hash_table (info);
6754 if (h->plt.offset != (bfd_vma) - 1)
6756 asection *plt, *gotplt, *relplt;
6758 /* This symbol has an entry in the procedure linkage table. Set
6759 it up. */
6761 /* When building a static executable, use .iplt, .igot.plt and
6762 .rela.iplt sections for STT_GNU_IFUNC symbols. */
6763 if (htab->root.splt != NULL)
6765 plt = htab->root.splt;
6766 gotplt = htab->root.sgotplt;
6767 relplt = htab->root.srelplt;
6769 else
6771 plt = htab->root.iplt;
6772 gotplt = htab->root.igotplt;
6773 relplt = htab->root.irelplt;
6776 /* This symbol has an entry in the procedure linkage table. Set
6777 it up. */
6778 if ((h->dynindx == -1
6779 && !((h->forced_local || info->executable)
6780 && h->def_regular
6781 && h->type == STT_GNU_IFUNC))
6782 || plt == NULL
6783 || gotplt == NULL
6784 || relplt == NULL)
6785 abort ();
6787 elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd, info);
6788 if (!h->def_regular)
6790 /* Mark the symbol as undefined, rather than as defined in
6791 the .plt section. Leave the value alone. This is a clue
6792 for the dynamic linker, to make function pointer
6793 comparisons work between an application and shared
6794 library. */
6795 sym->st_shndx = SHN_UNDEF;
6799 if (h->got.offset != (bfd_vma) - 1
6800 && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL)
6802 Elf_Internal_Rela rela;
6803 bfd_byte *loc;
6805 /* This symbol has an entry in the global offset table. Set it
6806 up. */
6807 if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
6808 abort ();
6810 rela.r_offset = (htab->root.sgot->output_section->vma
6811 + htab->root.sgot->output_offset
6812 + (h->got.offset & ~(bfd_vma) 1));
6814 if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
6816 if (!h->def_regular)
6817 return FALSE;
6819 BFD_ASSERT ((h->got.offset & 1) != 0);
6820 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
6821 rela.r_addend = (h->root.u.def.value
6822 + h->root.u.def.section->output_section->vma
6823 + h->root.u.def.section->output_offset);
6825 else
6827 BFD_ASSERT ((h->got.offset & 1) == 0);
6828 bfd_put_NN (output_bfd, (bfd_vma) 0,
6829 htab->root.sgot->contents + h->got.offset);
6830 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
6831 rela.r_addend = 0;
6834 loc = htab->root.srelgot->contents;
6835 loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
6836 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6839 if (h->needs_copy)
6841 Elf_Internal_Rela rela;
6842 bfd_byte *loc;
6844 /* This symbol needs a copy reloc. Set it up. */
6846 if (h->dynindx == -1
6847 || (h->root.type != bfd_link_hash_defined
6848 && h->root.type != bfd_link_hash_defweak)
6849 || htab->srelbss == NULL)
6850 abort ();
6852 rela.r_offset = (h->root.u.def.value
6853 + h->root.u.def.section->output_section->vma
6854 + h->root.u.def.section->output_offset);
6855 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
6856 rela.r_addend = 0;
6857 loc = htab->srelbss->contents;
6858 loc += htab->srelbss->reloc_count++ * RELOC_SIZE (htab);
6859 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6862 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
6863 be NULL for local symbols. */
6864 if (sym != NULL
6865 && (h == elf_hash_table (info)->hdynamic
6866 || h == elf_hash_table (info)->hgot))
6867 sym->st_shndx = SHN_ABS;
6869 return TRUE;
6872 /* Finish up local dynamic symbol handling. We set the contents of
6873 various dynamic sections here. */
6875 static bfd_boolean
6876 elfNN_aarch64_finish_local_dynamic_symbol (void **slot, void *inf)
6878 struct elf_link_hash_entry *h
6879 = (struct elf_link_hash_entry *) *slot;
6880 struct bfd_link_info *info
6881 = (struct bfd_link_info *) inf;
6883 return elfNN_aarch64_finish_dynamic_symbol (info->output_bfd,
6884 info, h, NULL);
6887 static void
6888 elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
6889 struct elf_aarch64_link_hash_table
6890 *htab)
6892 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
6893 small and large plts and at the minute just generates
6894 the small PLT. */
6896 /* PLT0 of the small PLT looks like this in ELF64 -
6897 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
6898 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
6899 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
6900 // symbol resolver
6901 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
6902 // GOTPLT entry for this.
6903 br x17
6904 PLT0 will be slightly different in ELF32 due to different got entry
6905 size.
6907 bfd_vma plt_got_2nd_ent; /* Address of GOT[2]. */
6908 bfd_vma plt_base;
6911 memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry,
6912 PLT_ENTRY_SIZE);
6913 elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
6914 PLT_ENTRY_SIZE;
6916 plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
6917 + htab->root.sgotplt->output_offset
6918 + GOT_ENTRY_SIZE * 2);
6920 plt_base = htab->root.splt->output_section->vma +
6921 htab->root.splt->output_section->output_offset;
6923 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
6924 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
6925 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
6926 htab->root.splt->contents + 4,
6927 PG (plt_got_2nd_ent) - PG (plt_base + 4));
6929 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
6930 htab->root.splt->contents + 8,
6931 PG_OFFSET (plt_got_2nd_ent));
6933 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
6934 htab->root.splt->contents + 12,
6935 PG_OFFSET (plt_got_2nd_ent));
6938 static bfd_boolean
6939 elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
6940 struct bfd_link_info *info)
6942 struct elf_aarch64_link_hash_table *htab;
6943 bfd *dynobj;
6944 asection *sdyn;
6946 htab = elf_aarch64_hash_table (info);
6947 dynobj = htab->root.dynobj;
6948 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
6950 if (htab->root.dynamic_sections_created)
6952 ElfNN_External_Dyn *dyncon, *dynconend;
6954 if (sdyn == NULL || htab->root.sgot == NULL)
6955 abort ();
6957 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
6958 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
6959 for (; dyncon < dynconend; dyncon++)
6961 Elf_Internal_Dyn dyn;
6962 asection *s;
6964 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
6966 switch (dyn.d_tag)
6968 default:
6969 continue;
6971 case DT_PLTGOT:
6972 s = htab->root.sgotplt;
6973 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
6974 break;
6976 case DT_JMPREL:
6977 dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
6978 break;
6980 case DT_PLTRELSZ:
6981 s = htab->root.srelplt->output_section;
6982 dyn.d_un.d_val = s->size;
6983 break;
6985 case DT_RELASZ:
6986 /* The procedure linkage table relocs (DT_JMPREL) should
6987 not be included in the overall relocs (DT_RELA).
6988 Therefore, we override the DT_RELASZ entry here to
6989 make it not include the JMPREL relocs. Since the
6990 linker script arranges for .rela.plt to follow all
6991 other relocation sections, we don't have to worry
6992 about changing the DT_RELA entry. */
6993 if (htab->root.srelplt != NULL)
6995 s = htab->root.srelplt->output_section;
6996 dyn.d_un.d_val -= s->size;
6998 break;
7000 case DT_TLSDESC_PLT:
7001 s = htab->root.splt;
7002 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
7003 + htab->tlsdesc_plt;
7004 break;
7006 case DT_TLSDESC_GOT:
7007 s = htab->root.sgot;
7008 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
7009 + htab->dt_tlsdesc_got;
7010 break;
7013 bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
7018 /* Fill in the special first entry in the procedure linkage table. */
7019 if (htab->root.splt && htab->root.splt->size > 0)
7021 elfNN_aarch64_init_small_plt0_entry (output_bfd, htab);
7023 elf_section_data (htab->root.splt->output_section)->
7024 this_hdr.sh_entsize = htab->plt_entry_size;
7027 if (htab->tlsdesc_plt)
7029 bfd_put_NN (output_bfd, (bfd_vma) 0,
7030 htab->root.sgot->contents + htab->dt_tlsdesc_got);
7032 memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
7033 elfNN_aarch64_tlsdesc_small_plt_entry,
7034 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));
7037 bfd_vma adrp1_addr =
7038 htab->root.splt->output_section->vma
7039 + htab->root.splt->output_offset + htab->tlsdesc_plt + 4;
7041 bfd_vma adrp2_addr = adrp1_addr + 4;
7043 bfd_vma got_addr =
7044 htab->root.sgot->output_section->vma
7045 + htab->root.sgot->output_offset;
7047 bfd_vma pltgot_addr =
7048 htab->root.sgotplt->output_section->vma
7049 + htab->root.sgotplt->output_offset;
7051 bfd_vma dt_tlsdesc_got = got_addr + htab->dt_tlsdesc_got;
7053 bfd_byte *plt_entry =
7054 htab->root.splt->contents + htab->tlsdesc_plt;
7056 /* adrp x2, DT_TLSDESC_GOT */
7057 elf_aarch64_update_plt_entry (output_bfd,
7058 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
7059 plt_entry + 4,
7060 (PG (dt_tlsdesc_got)
7061 - PG (adrp1_addr)));
7063 /* adrp x3, 0 */
7064 elf_aarch64_update_plt_entry (output_bfd,
7065 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
7066 plt_entry + 8,
7067 (PG (pltgot_addr)
7068 - PG (adrp2_addr)));
7070 /* ldr x2, [x2, #0] */
7071 elf_aarch64_update_plt_entry (output_bfd,
7072 BFD_RELOC_AARCH64_LDSTNN_LO12,
7073 plt_entry + 12,
7074 PG_OFFSET (dt_tlsdesc_got));
7076 /* add x3, x3, 0 */
7077 elf_aarch64_update_plt_entry (output_bfd,
7078 BFD_RELOC_AARCH64_ADD_LO12,
7079 plt_entry + 16,
7080 PG_OFFSET (pltgot_addr));
7085 if (htab->root.sgotplt)
7087 if (bfd_is_abs_section (htab->root.sgotplt->output_section))
7089 (*_bfd_error_handler)
7090 (_("discarded output section: `%A'"), htab->root.sgotplt);
7091 return FALSE;
7094 /* Fill in the first three entries in the global offset table. */
7095 if (htab->root.sgotplt->size > 0)
7097 bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
7099 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
7100 bfd_put_NN (output_bfd,
7101 (bfd_vma) 0,
7102 htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
7103 bfd_put_NN (output_bfd,
7104 (bfd_vma) 0,
7105 htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
7108 if (htab->root.sgot)
7110 if (htab->root.sgot->size > 0)
7112 bfd_vma addr =
7113 sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
7114 bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
7118 elf_section_data (htab->root.sgotplt->output_section)->
7119 this_hdr.sh_entsize = GOT_ENTRY_SIZE;
7122 if (htab->root.sgot && htab->root.sgot->size > 0)
7123 elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
7124 = GOT_ENTRY_SIZE;
7126 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
7127 htab_traverse (htab->loc_hash_table,
7128 elfNN_aarch64_finish_local_dynamic_symbol,
7129 info);
7131 return TRUE;
7134 /* Return address for Ith PLT stub in section PLT, for relocation REL
7135 or (bfd_vma) -1 if it should not be included. */
7137 static bfd_vma
7138 elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
7139 const arelent *rel ATTRIBUTE_UNUSED)
7141 return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
7145 /* We use this so we can override certain functions
7146 (though currently we don't). */
7148 const struct elf_size_info elfNN_aarch64_size_info =
7150 sizeof (ElfNN_External_Ehdr),
7151 sizeof (ElfNN_External_Phdr),
7152 sizeof (ElfNN_External_Shdr),
7153 sizeof (ElfNN_External_Rel),
7154 sizeof (ElfNN_External_Rela),
7155 sizeof (ElfNN_External_Sym),
7156 sizeof (ElfNN_External_Dyn),
7157 sizeof (Elf_External_Note),
7158 4, /* Hash table entry size. */
7159 1, /* Internal relocs per external relocs. */
7160 ARCH_SIZE, /* Arch size. */
7161 LOG_FILE_ALIGN, /* Log_file_align. */
7162 ELFCLASSNN, EV_CURRENT,
7163 bfd_elfNN_write_out_phdrs,
7164 bfd_elfNN_write_shdrs_and_ehdr,
7165 bfd_elfNN_checksum_contents,
7166 bfd_elfNN_write_relocs,
7167 bfd_elfNN_swap_symbol_in,
7168 bfd_elfNN_swap_symbol_out,
7169 bfd_elfNN_slurp_reloc_table,
7170 bfd_elfNN_slurp_symbol_table,
7171 bfd_elfNN_swap_dyn_in,
7172 bfd_elfNN_swap_dyn_out,
7173 bfd_elfNN_swap_reloc_in,
7174 bfd_elfNN_swap_reloc_out,
7175 bfd_elfNN_swap_reloca_in,
7176 bfd_elfNN_swap_reloca_out
7179 #define ELF_ARCH bfd_arch_aarch64
7180 #define ELF_MACHINE_CODE EM_AARCH64
7181 #define ELF_MAXPAGESIZE 0x10000
7182 #define ELF_MINPAGESIZE 0x1000
7183 #define ELF_COMMONPAGESIZE 0x1000
7185 #define bfd_elfNN_close_and_cleanup \
7186 elfNN_aarch64_close_and_cleanup
7188 #define bfd_elfNN_bfd_copy_private_bfd_data \
7189 elfNN_aarch64_copy_private_bfd_data
7191 #define bfd_elfNN_bfd_free_cached_info \
7192 elfNN_aarch64_bfd_free_cached_info
7194 #define bfd_elfNN_bfd_is_target_special_symbol \
7195 elfNN_aarch64_is_target_special_symbol
7197 #define bfd_elfNN_bfd_link_hash_table_create \
7198 elfNN_aarch64_link_hash_table_create
7200 #define bfd_elfNN_bfd_link_hash_table_free \
7201 elfNN_aarch64_hash_table_free
7203 #define bfd_elfNN_bfd_merge_private_bfd_data \
7204 elfNN_aarch64_merge_private_bfd_data
7206 #define bfd_elfNN_bfd_print_private_bfd_data \
7207 elfNN_aarch64_print_private_bfd_data
7209 #define bfd_elfNN_bfd_reloc_type_lookup \
7210 elfNN_aarch64_reloc_type_lookup
7212 #define bfd_elfNN_bfd_reloc_name_lookup \
7213 elfNN_aarch64_reloc_name_lookup
7215 #define bfd_elfNN_bfd_set_private_flags \
7216 elfNN_aarch64_set_private_flags
7218 #define bfd_elfNN_find_inliner_info \
7219 elfNN_aarch64_find_inliner_info
7221 #define bfd_elfNN_find_nearest_line \
7222 elfNN_aarch64_find_nearest_line
7224 #define bfd_elfNN_mkobject \
7225 elfNN_aarch64_mkobject
7227 #define bfd_elfNN_new_section_hook \
7228 elfNN_aarch64_new_section_hook
7230 #define elf_backend_adjust_dynamic_symbol \
7231 elfNN_aarch64_adjust_dynamic_symbol
7233 #define elf_backend_always_size_sections \
7234 elfNN_aarch64_always_size_sections
7236 #define elf_backend_check_relocs \
7237 elfNN_aarch64_check_relocs
7239 #define elf_backend_copy_indirect_symbol \
7240 elfNN_aarch64_copy_indirect_symbol
7242 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
7243 to them in our hash. */
7244 #define elf_backend_create_dynamic_sections \
7245 elfNN_aarch64_create_dynamic_sections
7247 #define elf_backend_init_index_section \
7248 _bfd_elf_init_2_index_sections
7250 #define elf_backend_finish_dynamic_sections \
7251 elfNN_aarch64_finish_dynamic_sections
7253 #define elf_backend_finish_dynamic_symbol \
7254 elfNN_aarch64_finish_dynamic_symbol
7256 #define elf_backend_gc_sweep_hook \
7257 elfNN_aarch64_gc_sweep_hook
7259 #define elf_backend_object_p \
7260 elfNN_aarch64_object_p
7262 #define elf_backend_output_arch_local_syms \
7263 elfNN_aarch64_output_arch_local_syms
7265 #define elf_backend_plt_sym_val \
7266 elfNN_aarch64_plt_sym_val
7268 #define elf_backend_post_process_headers \
7269 elfNN_aarch64_post_process_headers
7271 #define elf_backend_relocate_section \
7272 elfNN_aarch64_relocate_section
7274 #define elf_backend_reloc_type_class \
7275 elfNN_aarch64_reloc_type_class
7277 #define elf_backend_section_flags \
7278 elfNN_aarch64_section_flags
7280 #define elf_backend_section_from_shdr \
7281 elfNN_aarch64_section_from_shdr
7283 #define elf_backend_size_dynamic_sections \
7284 elfNN_aarch64_size_dynamic_sections
7286 #define elf_backend_size_info \
7287 elfNN_aarch64_size_info
7289 #define elf_backend_can_refcount 1
7290 #define elf_backend_can_gc_sections 1
7291 #define elf_backend_plt_readonly 1
7292 #define elf_backend_want_got_plt 1
7293 #define elf_backend_want_plt_sym 0
7294 #define elf_backend_may_use_rel_p 0
7295 #define elf_backend_may_use_rela_p 1
7296 #define elf_backend_default_use_rela_p 1
7297 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
7298 #define elf_backend_default_execstack 0
7300 #undef elf_backend_obj_attrs_section
7301 #define elf_backend_obj_attrs_section ".ARM.attributes"
7303 #include "elfNN-target.h"