1 /* AArch64-specific support for NN-bit ELF.
2 Copyright (C) 2009-2025 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* Notes on implementation:
23 Thread Local Store (TLS)
27 The implementation currently supports both traditional TLS and TLS
28 descriptors, but only general dynamic (GD).
30 For traditional TLS the assembler will present us with code
31 fragments of the form:
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
40 For TLS descriptors the assembler will present us with code
41 fragments of the form:
43 adrp x0, :tlsdesc:foo R_AARCH64_TLSDESC_ADR_PAGE21(foo)
44 ldr x1, [x0, #:tlsdesc_lo12:foo] R_AARCH64_TLSDESC_LD64_LO12(foo)
45 add x0, x0, #:tlsdesc_lo12:foo R_AARCH64_TLSDESC_ADD_LO12(foo)
47 blr x1 R_AARCH64_TLSDESC_CALL(foo)
49 The relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} against foo
50 indicate that foo is thread local and should be accessed via the
51 traditional TLS mechanims.
53 The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
54 against foo indicate that 'foo' is thread local and should be accessed
55 via a TLS descriptor mechanism.
57 The precise instruction sequence is only relevant from the
58 perspective of linker relaxation which is currently not implemented.
60 The static linker must detect that 'foo' is a TLS object and
61 allocate a double GOT entry. The GOT entry must be created for both
62 global and local TLS symbols. Note that this is different to none
63 TLS local objects which do not need a GOT entry.
65 In the traditional TLS mechanism, the double GOT entry is used to
66 provide the tls_index structure, containing module and offset
67 entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
68 on the module entry. The loader will subsequently fixup this
69 relocation with the module identity.
71 For global traditional TLS symbols the static linker places an
72 R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
73 will subsequently fixup the offset. For local TLS symbols the static
74 linker fixes up offset.
76 In the TLS descriptor mechanism the double GOT entry is used to
77 provide the descriptor. The static linker places the relocation
78 R_AARCH64_TLSDESC on the first GOT slot. The loader will
79 subsequently fix this up.
83 The handling of TLS symbols is implemented across a number of
84 different backend functions. The following is a top level view of
85 what processing is performed where.
87 The TLS implementation maintains state information for each TLS
88 symbol. The state information for local and global symbols is kept
89 in different places. Global symbols use generic BFD structures while
90 local symbols use backend specific structures that are allocated and
91 maintained entirely by the backend.
95 elfNN_aarch64_check_relocs()
97 This function is invoked for each relocation.
99 The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
100 R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
101 spotted. One time creation of local symbol data structures are
102 created when the first local symbol is seen.
104 The reference count for a symbol is incremented. The GOT type for
105 each symbol is marked as general dynamic.
107 elfNN_aarch64_allocate_dynrelocs ()
109 For each global with positive reference count we allocate a double
110 GOT slot. For a traditional TLS symbol we allocate space for two
111 relocation entries on the GOT, for a TLS descriptor symbol we
112 allocate space for one relocation on the slot. Record the GOT offset
115 elfNN_aarch64_late_size_sections ()
117 Iterate all input BFDS, look for in the local symbol data structure
118 constructed earlier for local TLS symbols and allocate them double
119 GOT slots along with space for a single GOT relocation. Update the
120 local symbol structure to record the GOT offset allocated.
122 elfNN_aarch64_relocate_section ()
124 Calls elfNN_aarch64_final_link_relocate ()
126 Emit the relevant TLS relocations against the GOT for each TLS
127 symbol. For local TLS symbols emit the GOT offset directly. The GOT
128 relocations are emitted once the first time a TLS symbol is
129 encountered. The implementation uses the LSB of the GOT offset to
130 flag that the relevant GOT relocations for a symbol have been
131 emitted. All of the TLS code that uses the GOT offset needs to take
132 care to mask out this flag bit before using the offset.
134 elfNN_aarch64_final_link_relocate ()
136 Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
140 #include "libiberty.h"
144 #include "objalloc.h"
145 #include "elf/aarch64.h"
146 #include "elfxx-aarch64.h"
147 #include "cpu-aarch64.h"
152 #define AARCH64_R(NAME) R_AARCH64_ ## NAME
153 #define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
154 #define HOWTO64(...) HOWTO (__VA_ARGS__)
155 #define HOWTO32(...) EMPTY_HOWTO (0)
156 #define LOG_FILE_ALIGN 3
157 #define BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
161 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
162 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
163 #define HOWTO64(...) EMPTY_HOWTO (0)
164 #define HOWTO32(...) HOWTO (__VA_ARGS__)
165 #define LOG_FILE_ALIGN 2
166 #define BFD_RELOC_AARCH64_TLSDESC_LD32_LO12 BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
167 #define R_AARCH64_P32_TLSDESC_ADD_LO12 R_AARCH64_P32_TLSDESC_ADD_LO12_NC
170 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
171 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12 \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12 \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12 \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12 \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12 \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12 \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0 \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1 \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2 \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12 \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC \
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12 \
207 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC \
208 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12 \
209 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC \
210 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12 \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC \
212 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
213 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
214 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
215 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
216 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
220 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
222 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
223 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
224 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
225 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
226 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
227 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
228 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
229 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
230 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
231 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
232 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
233 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
234 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
235 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
236 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
237 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
238 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
239 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
240 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
241 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
242 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
243 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
244 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
246 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
247 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
248 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
249 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
250 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
251 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
252 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
253 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
254 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12 \
255 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
256 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
257 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
258 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
260 #define ELIMINATE_COPY_RELOCS 1
262 /* Return size of a relocation entry. HTAB is the bfd's
263 elf_aarch64_link_hash_entry. */
264 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
266 /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
267 #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
268 #define PLT_ENTRY_SIZE (32)
269 #define PLT_SMALL_ENTRY_SIZE (16)
270 #define PLT_TLSDESC_ENTRY_SIZE (32)
271 /* PLT sizes with BTI insn. */
272 #define PLT_BTI_SMALL_ENTRY_SIZE (24)
273 /* PLT sizes with PAC insn. */
274 #define PLT_PAC_SMALL_ENTRY_SIZE (24)
275 /* PLT sizes with BTI and PAC insn. */
276 #define PLT_BTI_PAC_SMALL_ENTRY_SIZE (24)
278 /* Encoding of the nop instruction. */
279 #define INSN_NOP 0xd503201f
281 #define aarch64_compute_jump_table_size(htab) \
282 (((htab)->root.srelplt == NULL) ? 0 \
283 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
285 /* The first entry in a procedure linkage table looks like this
286 if the distance between the PLTGOT and the PLT is < 4GB use
287 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
288 in x16 and needs to work out PLTGOT[1] by using an address of
289 [x16,#-GOT_ENTRY_SIZE]. */
290 static const bfd_byte elfNN_aarch64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
292 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
293 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
295 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
296 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
298 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
299 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
301 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
302 0x1f, 0x20, 0x03, 0xd5, /* nop */
303 0x1f, 0x20, 0x03, 0xd5, /* nop */
304 0x1f, 0x20, 0x03, 0xd5, /* nop */
307 static const bfd_byte elfNN_aarch64_small_plt0_bti_entry
[PLT_ENTRY_SIZE
] =
309 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
310 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
311 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
313 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
314 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
316 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
317 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
319 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
320 0x1f, 0x20, 0x03, 0xd5, /* nop */
321 0x1f, 0x20, 0x03, 0xd5, /* nop */
324 /* Per function entry in a procedure linkage table looks like this
325 if the distance between the PLTGOT and the PLT is < 4GB use
326 these PLT entries. Use BTI versions of the PLTs when enabled. */
327 static const bfd_byte elfNN_aarch64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
329 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
331 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
332 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
334 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
335 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
337 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
340 static const bfd_byte
341 elfNN_aarch64_small_plt_bti_entry
[PLT_BTI_SMALL_ENTRY_SIZE
] =
343 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
344 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
346 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
347 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
349 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
350 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
352 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
353 0x1f, 0x20, 0x03, 0xd5, /* nop */
356 static const bfd_byte
357 elfNN_aarch64_small_plt_pac_entry
[PLT_PAC_SMALL_ENTRY_SIZE
] =
359 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
361 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
362 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
364 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
365 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
367 0x9f, 0x21, 0x03, 0xd5, /* autia1716 */
368 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
369 0x1f, 0x20, 0x03, 0xd5, /* nop */
372 static const bfd_byte
373 elfNN_aarch64_small_plt_bti_pac_entry
[PLT_BTI_PAC_SMALL_ENTRY_SIZE
] =
375 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
376 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
378 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
379 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
381 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
382 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
384 0x9f, 0x21, 0x03, 0xd5, /* autia1716 */
385 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
388 static const bfd_byte
389 elfNN_aarch64_tlsdesc_small_plt_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
391 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
392 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
393 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
395 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
396 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
398 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
399 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
401 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
402 0x1f, 0x20, 0x03, 0xd5, /* nop */
403 0x1f, 0x20, 0x03, 0xd5, /* nop */
406 static const bfd_byte
407 elfNN_aarch64_tlsdesc_small_plt_bti_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
409 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
410 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
411 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
412 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
414 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
415 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
417 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
418 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
420 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
421 0x1f, 0x20, 0x03, 0xd5, /* nop */
424 #define elf_info_to_howto elfNN_aarch64_info_to_howto
425 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
427 #define AARCH64_ELF_ABI_VERSION 0
429 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
430 #define ALL_ONES (~ (bfd_vma) 0)
432 /* Indexed by the bfd interal reloc enumerators.
433 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
436 static reloc_howto_type elfNN_aarch64_howto_table
[] =
440 /* Basic data relocations. */
442 /* Deprecated, but retained for backwards compatibility. */
443 HOWTO64 (R_AARCH64_NULL
, /* type */
447 false, /* pc_relative */
449 complain_overflow_dont
, /* complain_on_overflow */
450 bfd_elf_generic_reloc
, /* special_function */
451 "R_AARCH64_NULL", /* name */
452 false, /* partial_inplace */
455 false), /* pcrel_offset */
456 HOWTO (R_AARCH64_NONE
, /* type */
460 false, /* pc_relative */
462 complain_overflow_dont
, /* complain_on_overflow */
463 bfd_elf_generic_reloc
, /* special_function */
464 "R_AARCH64_NONE", /* name */
465 false, /* partial_inplace */
468 false), /* pcrel_offset */
471 HOWTO64 (AARCH64_R (ABS64
), /* type */
475 false, /* pc_relative */
477 complain_overflow_unsigned
, /* complain_on_overflow */
478 bfd_elf_generic_reloc
, /* special_function */
479 AARCH64_R_STR (ABS64
), /* name */
480 false, /* partial_inplace */
482 ALL_ONES
, /* dst_mask */
483 false), /* pcrel_offset */
486 HOWTO (AARCH64_R (ABS32
), /* type */
490 false, /* pc_relative */
492 complain_overflow_unsigned
, /* complain_on_overflow */
493 bfd_elf_generic_reloc
, /* special_function */
494 AARCH64_R_STR (ABS32
), /* name */
495 false, /* partial_inplace */
497 0xffffffff, /* dst_mask */
498 false), /* pcrel_offset */
501 HOWTO (AARCH64_R (ABS16
), /* type */
505 false, /* pc_relative */
507 complain_overflow_unsigned
, /* complain_on_overflow */
508 bfd_elf_generic_reloc
, /* special_function */
509 AARCH64_R_STR (ABS16
), /* name */
510 false, /* partial_inplace */
512 0xffff, /* dst_mask */
513 false), /* pcrel_offset */
515 /* .xword: (S+A-P) */
516 HOWTO64 (AARCH64_R (PREL64
), /* type */
520 true, /* pc_relative */
522 complain_overflow_signed
, /* complain_on_overflow */
523 bfd_elf_generic_reloc
, /* special_function */
524 AARCH64_R_STR (PREL64
), /* name */
525 false, /* partial_inplace */
527 ALL_ONES
, /* dst_mask */
528 true), /* pcrel_offset */
531 HOWTO (AARCH64_R (PREL32
), /* type */
535 true, /* pc_relative */
537 complain_overflow_signed
, /* complain_on_overflow */
538 bfd_elf_generic_reloc
, /* special_function */
539 AARCH64_R_STR (PREL32
), /* name */
540 false, /* partial_inplace */
542 0xffffffff, /* dst_mask */
543 true), /* pcrel_offset */
546 HOWTO (AARCH64_R (PREL16
), /* type */
550 true, /* pc_relative */
552 complain_overflow_signed
, /* complain_on_overflow */
553 bfd_elf_generic_reloc
, /* special_function */
554 AARCH64_R_STR (PREL16
), /* name */
555 false, /* partial_inplace */
557 0xffff, /* dst_mask */
558 true), /* pcrel_offset */
560 /* Group relocations to create a 16, 32, 48 or 64 bit
561 unsigned data or abs address inline. */
563 /* MOVZ: ((S+A) >> 0) & 0xffff */
564 HOWTO (AARCH64_R (MOVW_UABS_G0
), /* type */
568 false, /* pc_relative */
570 complain_overflow_unsigned
, /* complain_on_overflow */
571 bfd_elf_generic_reloc
, /* special_function */
572 AARCH64_R_STR (MOVW_UABS_G0
), /* name */
573 false, /* partial_inplace */
575 0xffff, /* dst_mask */
576 false), /* pcrel_offset */
578 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
579 HOWTO (AARCH64_R (MOVW_UABS_G0_NC
), /* type */
583 false, /* pc_relative */
585 complain_overflow_dont
, /* complain_on_overflow */
586 bfd_elf_generic_reloc
, /* special_function */
587 AARCH64_R_STR (MOVW_UABS_G0_NC
), /* name */
588 false, /* partial_inplace */
590 0xffff, /* dst_mask */
591 false), /* pcrel_offset */
593 /* MOVZ: ((S+A) >> 16) & 0xffff */
594 HOWTO (AARCH64_R (MOVW_UABS_G1
), /* type */
598 false, /* pc_relative */
600 complain_overflow_unsigned
, /* complain_on_overflow */
601 bfd_elf_generic_reloc
, /* special_function */
602 AARCH64_R_STR (MOVW_UABS_G1
), /* name */
603 false, /* partial_inplace */
605 0xffff, /* dst_mask */
606 false), /* pcrel_offset */
608 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
609 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC
), /* type */
613 false, /* pc_relative */
615 complain_overflow_dont
, /* complain_on_overflow */
616 bfd_elf_generic_reloc
, /* special_function */
617 AARCH64_R_STR (MOVW_UABS_G1_NC
), /* name */
618 false, /* partial_inplace */
620 0xffff, /* dst_mask */
621 false), /* pcrel_offset */
623 /* MOVZ: ((S+A) >> 32) & 0xffff */
624 HOWTO64 (AARCH64_R (MOVW_UABS_G2
), /* type */
628 false, /* pc_relative */
630 complain_overflow_unsigned
, /* complain_on_overflow */
631 bfd_elf_generic_reloc
, /* special_function */
632 AARCH64_R_STR (MOVW_UABS_G2
), /* name */
633 false, /* partial_inplace */
635 0xffff, /* dst_mask */
636 false), /* pcrel_offset */
638 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
639 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC
), /* type */
643 false, /* pc_relative */
645 complain_overflow_dont
, /* complain_on_overflow */
646 bfd_elf_generic_reloc
, /* special_function */
647 AARCH64_R_STR (MOVW_UABS_G2_NC
), /* name */
648 false, /* partial_inplace */
650 0xffff, /* dst_mask */
651 false), /* pcrel_offset */
653 /* MOVZ: ((S+A) >> 48) & 0xffff */
654 HOWTO64 (AARCH64_R (MOVW_UABS_G3
), /* type */
658 false, /* pc_relative */
660 complain_overflow_unsigned
, /* complain_on_overflow */
661 bfd_elf_generic_reloc
, /* special_function */
662 AARCH64_R_STR (MOVW_UABS_G3
), /* name */
663 false, /* partial_inplace */
665 0xffff, /* dst_mask */
666 false), /* pcrel_offset */
668 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
669 signed data or abs address inline. Will change instruction
670 to MOVN or MOVZ depending on sign of calculated value. */
672 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
673 HOWTO (AARCH64_R (MOVW_SABS_G0
), /* type */
677 false, /* pc_relative */
679 complain_overflow_signed
, /* complain_on_overflow */
680 bfd_elf_generic_reloc
, /* special_function */
681 AARCH64_R_STR (MOVW_SABS_G0
), /* name */
682 false, /* partial_inplace */
684 0xffff, /* dst_mask */
685 false), /* pcrel_offset */
687 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
688 HOWTO64 (AARCH64_R (MOVW_SABS_G1
), /* type */
692 false, /* pc_relative */
694 complain_overflow_signed
, /* complain_on_overflow */
695 bfd_elf_generic_reloc
, /* special_function */
696 AARCH64_R_STR (MOVW_SABS_G1
), /* name */
697 false, /* partial_inplace */
699 0xffff, /* dst_mask */
700 false), /* pcrel_offset */
702 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
703 HOWTO64 (AARCH64_R (MOVW_SABS_G2
), /* type */
707 false, /* pc_relative */
709 complain_overflow_signed
, /* complain_on_overflow */
710 bfd_elf_generic_reloc
, /* special_function */
711 AARCH64_R_STR (MOVW_SABS_G2
), /* name */
712 false, /* partial_inplace */
714 0xffff, /* dst_mask */
715 false), /* pcrel_offset */
717 /* Group relocations to create a 16, 32, 48 or 64 bit
718 PC relative address inline. */
720 /* MOV[NZ]: ((S+A-P) >> 0) & 0xffff */
721 HOWTO (AARCH64_R (MOVW_PREL_G0
), /* type */
725 true, /* pc_relative */
727 complain_overflow_signed
, /* complain_on_overflow */
728 bfd_elf_generic_reloc
, /* special_function */
729 AARCH64_R_STR (MOVW_PREL_G0
), /* name */
730 false, /* partial_inplace */
732 0xffff, /* dst_mask */
733 true), /* pcrel_offset */
735 /* MOVK: ((S+A-P) >> 0) & 0xffff [no overflow check] */
736 HOWTO (AARCH64_R (MOVW_PREL_G0_NC
), /* type */
740 true, /* pc_relative */
742 complain_overflow_dont
, /* complain_on_overflow */
743 bfd_elf_generic_reloc
, /* special_function */
744 AARCH64_R_STR (MOVW_PREL_G0_NC
), /* name */
745 false, /* partial_inplace */
747 0xffff, /* dst_mask */
748 true), /* pcrel_offset */
750 /* MOV[NZ]: ((S+A-P) >> 16) & 0xffff */
751 HOWTO (AARCH64_R (MOVW_PREL_G1
), /* type */
755 true, /* pc_relative */
757 complain_overflow_signed
, /* complain_on_overflow */
758 bfd_elf_generic_reloc
, /* special_function */
759 AARCH64_R_STR (MOVW_PREL_G1
), /* name */
760 false, /* partial_inplace */
762 0xffff, /* dst_mask */
763 true), /* pcrel_offset */
765 /* MOVK: ((S+A-P) >> 16) & 0xffff [no overflow check] */
766 HOWTO64 (AARCH64_R (MOVW_PREL_G1_NC
), /* type */
770 true, /* pc_relative */
772 complain_overflow_dont
, /* complain_on_overflow */
773 bfd_elf_generic_reloc
, /* special_function */
774 AARCH64_R_STR (MOVW_PREL_G1_NC
), /* name */
775 false, /* partial_inplace */
777 0xffff, /* dst_mask */
778 true), /* pcrel_offset */
780 /* MOV[NZ]: ((S+A-P) >> 32) & 0xffff */
781 HOWTO64 (AARCH64_R (MOVW_PREL_G2
), /* type */
785 true, /* pc_relative */
787 complain_overflow_signed
, /* complain_on_overflow */
788 bfd_elf_generic_reloc
, /* special_function */
789 AARCH64_R_STR (MOVW_PREL_G2
), /* name */
790 false, /* partial_inplace */
792 0xffff, /* dst_mask */
793 true), /* pcrel_offset */
795 /* MOVK: ((S+A-P) >> 32) & 0xffff [no overflow check] */
796 HOWTO64 (AARCH64_R (MOVW_PREL_G2_NC
), /* type */
800 true, /* pc_relative */
802 complain_overflow_dont
, /* complain_on_overflow */
803 bfd_elf_generic_reloc
, /* special_function */
804 AARCH64_R_STR (MOVW_PREL_G2_NC
), /* name */
805 false, /* partial_inplace */
807 0xffff, /* dst_mask */
808 true), /* pcrel_offset */
810 /* MOV[NZ]: ((S+A-P) >> 48) & 0xffff */
811 HOWTO64 (AARCH64_R (MOVW_PREL_G3
), /* type */
815 true, /* pc_relative */
817 complain_overflow_dont
, /* complain_on_overflow */
818 bfd_elf_generic_reloc
, /* special_function */
819 AARCH64_R_STR (MOVW_PREL_G3
), /* name */
820 false, /* partial_inplace */
822 0xffff, /* dst_mask */
823 true), /* pcrel_offset */
825 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
826 addresses: PG(x) is (x & ~0xfff). */
828 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
829 HOWTO (AARCH64_R (LD_PREL_LO19
), /* type */
833 true, /* pc_relative */
835 complain_overflow_signed
, /* complain_on_overflow */
836 bfd_elf_generic_reloc
, /* special_function */
837 AARCH64_R_STR (LD_PREL_LO19
), /* name */
838 false, /* partial_inplace */
840 0x7ffff, /* dst_mask */
841 true), /* pcrel_offset */
843 /* ADR: (S+A-P) & 0x1fffff */
844 HOWTO (AARCH64_R (ADR_PREL_LO21
), /* type */
848 true, /* pc_relative */
850 complain_overflow_signed
, /* complain_on_overflow */
851 bfd_elf_generic_reloc
, /* special_function */
852 AARCH64_R_STR (ADR_PREL_LO21
), /* name */
853 false, /* partial_inplace */
855 0x1fffff, /* dst_mask */
856 true), /* pcrel_offset */
858 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
859 HOWTO (AARCH64_R (ADR_PREL_PG_HI21
), /* type */
863 true, /* pc_relative */
865 complain_overflow_signed
, /* complain_on_overflow */
866 bfd_elf_generic_reloc
, /* special_function */
867 AARCH64_R_STR (ADR_PREL_PG_HI21
), /* name */
868 false, /* partial_inplace */
870 0x1fffff, /* dst_mask */
871 true), /* pcrel_offset */
873 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
874 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC
), /* type */
878 true, /* pc_relative */
880 complain_overflow_dont
, /* complain_on_overflow */
881 bfd_elf_generic_reloc
, /* special_function */
882 AARCH64_R_STR (ADR_PREL_PG_HI21_NC
), /* name */
883 false, /* partial_inplace */
885 0x1fffff, /* dst_mask */
886 true), /* pcrel_offset */
888 /* ADD: (S+A) & 0xfff [no overflow check] */
889 HOWTO (AARCH64_R (ADD_ABS_LO12_NC
), /* type */
893 false, /* pc_relative */
895 complain_overflow_dont
, /* complain_on_overflow */
896 bfd_elf_generic_reloc
, /* special_function */
897 AARCH64_R_STR (ADD_ABS_LO12_NC
), /* name */
898 false, /* partial_inplace */
900 0x3ffc00, /* dst_mask */
901 false), /* pcrel_offset */
903 /* LD/ST8: (S+A) & 0xfff */
904 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC
), /* type */
908 false, /* pc_relative */
910 complain_overflow_dont
, /* complain_on_overflow */
911 bfd_elf_generic_reloc
, /* special_function */
912 AARCH64_R_STR (LDST8_ABS_LO12_NC
), /* name */
913 false, /* partial_inplace */
915 0xfff, /* dst_mask */
916 false), /* pcrel_offset */
918 /* Relocations for control-flow instructions. */
920 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
921 HOWTO (AARCH64_R (TSTBR14
), /* type */
925 true, /* pc_relative */
927 complain_overflow_signed
, /* complain_on_overflow */
928 bfd_elf_generic_reloc
, /* special_function */
929 AARCH64_R_STR (TSTBR14
), /* name */
930 false, /* partial_inplace */
932 0x3fff, /* dst_mask */
933 true), /* pcrel_offset */
935 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
936 HOWTO (AARCH64_R (CONDBR19
), /* type */
940 true, /* pc_relative */
942 complain_overflow_signed
, /* complain_on_overflow */
943 bfd_elf_generic_reloc
, /* special_function */
944 AARCH64_R_STR (CONDBR19
), /* name */
945 false, /* partial_inplace */
947 0x7ffff, /* dst_mask */
948 true), /* pcrel_offset */
950 /* B: ((S+A-P) >> 2) & 0x3ffffff */
951 HOWTO (AARCH64_R (JUMP26
), /* type */
955 true, /* pc_relative */
957 complain_overflow_signed
, /* complain_on_overflow */
958 bfd_elf_generic_reloc
, /* special_function */
959 AARCH64_R_STR (JUMP26
), /* name */
960 false, /* partial_inplace */
962 0x3ffffff, /* dst_mask */
963 true), /* pcrel_offset */
965 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
966 HOWTO (AARCH64_R (CALL26
), /* type */
970 true, /* pc_relative */
972 complain_overflow_signed
, /* complain_on_overflow */
973 bfd_elf_generic_reloc
, /* special_function */
974 AARCH64_R_STR (CALL26
), /* name */
975 false, /* partial_inplace */
977 0x3ffffff, /* dst_mask */
978 true), /* pcrel_offset */
980 /* LD/ST16: (S+A) & 0xffe */
981 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC
), /* type */
985 false, /* pc_relative */
987 complain_overflow_dont
, /* complain_on_overflow */
988 bfd_elf_generic_reloc
, /* special_function */
989 AARCH64_R_STR (LDST16_ABS_LO12_NC
), /* name */
990 false, /* partial_inplace */
992 0xffe, /* dst_mask */
993 false), /* pcrel_offset */
995 /* LD/ST32: (S+A) & 0xffc */
996 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC
), /* type */
1000 false, /* pc_relative */
1002 complain_overflow_dont
, /* complain_on_overflow */
1003 bfd_elf_generic_reloc
, /* special_function */
1004 AARCH64_R_STR (LDST32_ABS_LO12_NC
), /* name */
1005 false, /* partial_inplace */
1007 0xffc, /* dst_mask */
1008 false), /* pcrel_offset */
1010 /* LD/ST64: (S+A) & 0xff8 */
1011 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC
), /* type */
1015 false, /* pc_relative */
1017 complain_overflow_dont
, /* complain_on_overflow */
1018 bfd_elf_generic_reloc
, /* special_function */
1019 AARCH64_R_STR (LDST64_ABS_LO12_NC
), /* name */
1020 false, /* partial_inplace */
1022 0xff8, /* dst_mask */
1023 false), /* pcrel_offset */
1025 /* LD/ST128: (S+A) & 0xff0 */
1026 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC
), /* type */
1030 false, /* pc_relative */
1032 complain_overflow_dont
, /* complain_on_overflow */
1033 bfd_elf_generic_reloc
, /* special_function */
1034 AARCH64_R_STR (LDST128_ABS_LO12_NC
), /* name */
1035 false, /* partial_inplace */
1037 0xff0, /* dst_mask */
1038 false), /* pcrel_offset */
1040 /* Set a load-literal immediate field to bits
1041 0x1FFFFC of G(S)-P */
1042 HOWTO (AARCH64_R (GOT_LD_PREL19
), /* type */
1046 true, /* pc_relative */
1048 complain_overflow_signed
, /* complain_on_overflow */
1049 bfd_elf_generic_reloc
, /* special_function */
1050 AARCH64_R_STR (GOT_LD_PREL19
), /* name */
1051 false, /* partial_inplace */
1053 0xffffe0, /* dst_mask */
1054 true), /* pcrel_offset */
1056 /* Get to the page for the GOT entry for the symbol
1057 (G(S) - P) using an ADRP instruction. */
1058 HOWTO (AARCH64_R (ADR_GOT_PAGE
), /* type */
1059 12, /* rightshift */
1062 true, /* pc_relative */
1064 complain_overflow_dont
, /* complain_on_overflow */
1065 bfd_elf_generic_reloc
, /* special_function */
1066 AARCH64_R_STR (ADR_GOT_PAGE
), /* name */
1067 false, /* partial_inplace */
1069 0x1fffff, /* dst_mask */
1070 true), /* pcrel_offset */
1072 /* LD64: GOT offset G(S) & 0xff8 */
1073 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC
), /* type */
1077 false, /* pc_relative */
1079 complain_overflow_dont
, /* complain_on_overflow */
1080 bfd_elf_generic_reloc
, /* special_function */
1081 AARCH64_R_STR (LD64_GOT_LO12_NC
), /* name */
1082 false, /* partial_inplace */
1084 0xff8, /* dst_mask */
1085 false), /* pcrel_offset */
1087 /* LD32: GOT offset G(S) & 0xffc */
1088 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC
), /* type */
1092 false, /* pc_relative */
1094 complain_overflow_dont
, /* complain_on_overflow */
1095 bfd_elf_generic_reloc
, /* special_function */
1096 AARCH64_R_STR (LD32_GOT_LO12_NC
), /* name */
1097 false, /* partial_inplace */
1099 0xffc, /* dst_mask */
1100 false), /* pcrel_offset */
1102 /* Lower 16 bits of GOT offset for the symbol. */
1103 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G0_NC
), /* type */
1107 false, /* pc_relative */
1109 complain_overflow_dont
, /* complain_on_overflow */
1110 bfd_elf_generic_reloc
, /* special_function */
1111 AARCH64_R_STR (MOVW_GOTOFF_G0_NC
), /* name */
1112 false, /* partial_inplace */
1114 0xffff, /* dst_mask */
1115 false), /* pcrel_offset */
1117 /* Higher 16 bits of GOT offset for the symbol. */
1118 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G1
), /* type */
1119 16, /* rightshift */
1122 false, /* pc_relative */
1124 complain_overflow_unsigned
, /* complain_on_overflow */
1125 bfd_elf_generic_reloc
, /* special_function */
1126 AARCH64_R_STR (MOVW_GOTOFF_G1
), /* name */
1127 false, /* partial_inplace */
1129 0xffff, /* dst_mask */
1130 false), /* pcrel_offset */
1132 /* LD64: GOT offset for the symbol. */
1133 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15
), /* type */
1137 false, /* pc_relative */
1139 complain_overflow_unsigned
, /* complain_on_overflow */
1140 bfd_elf_generic_reloc
, /* special_function */
1141 AARCH64_R_STR (LD64_GOTOFF_LO15
), /* name */
1142 false, /* partial_inplace */
1144 0x7ff8, /* dst_mask */
1145 false), /* pcrel_offset */
1147 /* LD32: GOT offset to the page address of GOT table.
1148 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
1149 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14
), /* type */
1153 false, /* pc_relative */
1155 complain_overflow_unsigned
, /* complain_on_overflow */
1156 bfd_elf_generic_reloc
, /* special_function */
1157 AARCH64_R_STR (LD32_GOTPAGE_LO14
), /* name */
1158 false, /* partial_inplace */
1160 0x5ffc, /* dst_mask */
1161 false), /* pcrel_offset */
1163 /* LD64: GOT offset to the page address of GOT table.
1164 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
1165 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15
), /* type */
1169 false, /* pc_relative */
1171 complain_overflow_unsigned
, /* complain_on_overflow */
1172 bfd_elf_generic_reloc
, /* special_function */
1173 AARCH64_R_STR (LD64_GOTPAGE_LO15
), /* name */
1174 false, /* partial_inplace */
1176 0x7ff8, /* dst_mask */
1177 false), /* pcrel_offset */
1179 /* Get to the page for the GOT entry for the symbol
1180 (G(S) - P) using an ADRP instruction. */
1181 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21
), /* type */
1182 12, /* rightshift */
1185 true, /* pc_relative */
1187 complain_overflow_dont
, /* complain_on_overflow */
1188 bfd_elf_generic_reloc
, /* special_function */
1189 AARCH64_R_STR (TLSGD_ADR_PAGE21
), /* name */
1190 false, /* partial_inplace */
1192 0x1fffff, /* dst_mask */
1193 true), /* pcrel_offset */
1195 HOWTO (AARCH64_R (TLSGD_ADR_PREL21
), /* type */
1199 true, /* pc_relative */
1201 complain_overflow_dont
, /* complain_on_overflow */
1202 bfd_elf_generic_reloc
, /* special_function */
1203 AARCH64_R_STR (TLSGD_ADR_PREL21
), /* name */
1204 false, /* partial_inplace */
1206 0x1fffff, /* dst_mask */
1207 true), /* pcrel_offset */
1209 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1210 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC
), /* type */
1214 false, /* pc_relative */
1216 complain_overflow_dont
, /* complain_on_overflow */
1217 bfd_elf_generic_reloc
, /* special_function */
1218 AARCH64_R_STR (TLSGD_ADD_LO12_NC
), /* name */
1219 false, /* partial_inplace */
1221 0xfff, /* dst_mask */
1222 false), /* pcrel_offset */
1224 /* Lower 16 bits of GOT offset to tls_index. */
1225 HOWTO64 (AARCH64_R (TLSGD_MOVW_G0_NC
), /* type */
1229 false, /* pc_relative */
1231 complain_overflow_dont
, /* complain_on_overflow */
1232 bfd_elf_generic_reloc
, /* special_function */
1233 AARCH64_R_STR (TLSGD_MOVW_G0_NC
), /* name */
1234 false, /* partial_inplace */
1236 0xffff, /* dst_mask */
1237 false), /* pcrel_offset */
1239 /* Higher 16 bits of GOT offset to tls_index. */
1240 HOWTO64 (AARCH64_R (TLSGD_MOVW_G1
), /* type */
1241 16, /* rightshift */
1244 false, /* pc_relative */
1246 complain_overflow_unsigned
, /* complain_on_overflow */
1247 bfd_elf_generic_reloc
, /* special_function */
1248 AARCH64_R_STR (TLSGD_MOVW_G1
), /* name */
1249 false, /* partial_inplace */
1251 0xffff, /* dst_mask */
1252 false), /* pcrel_offset */
1254 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21
), /* type */
1255 12, /* rightshift */
1258 false, /* pc_relative */
1260 complain_overflow_dont
, /* complain_on_overflow */
1261 bfd_elf_generic_reloc
, /* special_function */
1262 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21
), /* name */
1263 false, /* partial_inplace */
1265 0x1fffff, /* dst_mask */
1266 false), /* pcrel_offset */
1268 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC
), /* type */
1272 false, /* pc_relative */
1274 complain_overflow_dont
, /* complain_on_overflow */
1275 bfd_elf_generic_reloc
, /* special_function */
1276 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC
), /* name */
1277 false, /* partial_inplace */
1279 0xff8, /* dst_mask */
1280 false), /* pcrel_offset */
1282 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC
), /* type */
1286 false, /* pc_relative */
1288 complain_overflow_dont
, /* complain_on_overflow */
1289 bfd_elf_generic_reloc
, /* special_function */
1290 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC
), /* name */
1291 false, /* partial_inplace */
1293 0xffc, /* dst_mask */
1294 false), /* pcrel_offset */
1296 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19
), /* type */
1300 false, /* pc_relative */
1302 complain_overflow_dont
, /* complain_on_overflow */
1303 bfd_elf_generic_reloc
, /* special_function */
1304 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19
), /* name */
1305 false, /* partial_inplace */
1307 0x1ffffc, /* dst_mask */
1308 false), /* pcrel_offset */
1310 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC
), /* type */
1314 false, /* pc_relative */
1316 complain_overflow_dont
, /* complain_on_overflow */
1317 bfd_elf_generic_reloc
, /* special_function */
1318 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC
), /* name */
1319 false, /* partial_inplace */
1321 0xffff, /* dst_mask */
1322 false), /* pcrel_offset */
1324 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1
), /* type */
1325 16, /* rightshift */
1328 false, /* pc_relative */
1330 complain_overflow_unsigned
, /* complain_on_overflow */
1331 bfd_elf_generic_reloc
, /* special_function */
1332 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1
), /* name */
1333 false, /* partial_inplace */
1335 0xffff, /* dst_mask */
1336 false), /* pcrel_offset */
1338 /* ADD: bit[23:12] of byte offset to module TLS base address. */
1339 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12
), /* type */
1340 12, /* rightshift */
1343 false, /* pc_relative */
1345 complain_overflow_unsigned
, /* complain_on_overflow */
1346 bfd_elf_generic_reloc
, /* special_function */
1347 AARCH64_R_STR (TLSLD_ADD_DTPREL_HI12
), /* name */
1348 false, /* partial_inplace */
1350 0xfff, /* dst_mask */
1351 false), /* pcrel_offset */
1353 /* Unsigned 12 bit byte offset to module TLS base address. */
1354 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12
), /* type */
1358 false, /* pc_relative */
1360 complain_overflow_unsigned
, /* complain_on_overflow */
1361 bfd_elf_generic_reloc
, /* special_function */
1362 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12
), /* name */
1363 false, /* partial_inplace */
1365 0xfff, /* dst_mask */
1366 false), /* pcrel_offset */
1368 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1369 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC
), /* type */
1373 false, /* pc_relative */
1375 complain_overflow_dont
, /* complain_on_overflow */
1376 bfd_elf_generic_reloc
, /* special_function */
1377 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC
), /* name */
1378 false, /* partial_inplace */
1380 0xfff, /* dst_mask */
1381 false), /* pcrel_offset */
1383 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1384 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC
), /* type */
1388 false, /* pc_relative */
1390 complain_overflow_dont
, /* complain_on_overflow */
1391 bfd_elf_generic_reloc
, /* special_function */
1392 AARCH64_R_STR (TLSLD_ADD_LO12_NC
), /* name */
1393 false, /* partial_inplace */
1395 0xfff, /* dst_mask */
1396 false), /* pcrel_offset */
1398 /* Get to the page for the GOT entry for the symbol
1399 (G(S) - P) using an ADRP instruction. */
1400 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21
), /* type */
1401 12, /* rightshift */
1404 true, /* pc_relative */
1406 complain_overflow_signed
, /* complain_on_overflow */
1407 bfd_elf_generic_reloc
, /* special_function */
1408 AARCH64_R_STR (TLSLD_ADR_PAGE21
), /* name */
1409 false, /* partial_inplace */
1411 0x1fffff, /* dst_mask */
1412 true), /* pcrel_offset */
1414 HOWTO (AARCH64_R (TLSLD_ADR_PREL21
), /* type */
1418 true, /* pc_relative */
1420 complain_overflow_signed
, /* complain_on_overflow */
1421 bfd_elf_generic_reloc
, /* special_function */
1422 AARCH64_R_STR (TLSLD_ADR_PREL21
), /* name */
1423 false, /* partial_inplace */
1425 0x1fffff, /* dst_mask */
1426 true), /* pcrel_offset */
1428 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1429 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12
), /* type */
1433 false, /* pc_relative */
1435 complain_overflow_unsigned
, /* complain_on_overflow */
1436 bfd_elf_generic_reloc
, /* special_function */
1437 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12
), /* name */
1438 false, /* partial_inplace */
1440 0x1ffc00, /* dst_mask */
1441 false), /* pcrel_offset */
1443 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, but no overflow check. */
1444 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12_NC
), /* type */
1448 false, /* pc_relative */
1450 complain_overflow_dont
, /* complain_on_overflow */
1451 bfd_elf_generic_reloc
, /* special_function */
1452 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12_NC
), /* name */
1453 false, /* partial_inplace */
1455 0x1ffc00, /* dst_mask */
1456 false), /* pcrel_offset */
1458 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1459 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12
), /* type */
1463 false, /* pc_relative */
1465 complain_overflow_unsigned
, /* complain_on_overflow */
1466 bfd_elf_generic_reloc
, /* special_function */
1467 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12
), /* name */
1468 false, /* partial_inplace */
1470 0x3ffc00, /* dst_mask */
1471 false), /* pcrel_offset */
1473 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no overflow check. */
1474 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12_NC
), /* type */
1478 false, /* pc_relative */
1480 complain_overflow_dont
, /* complain_on_overflow */
1481 bfd_elf_generic_reloc
, /* special_function */
1482 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12_NC
), /* name */
1483 false, /* partial_inplace */
1485 0xffc00, /* dst_mask */
1486 false), /* pcrel_offset */
1488 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1489 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12
), /* type */
1493 false, /* pc_relative */
1495 complain_overflow_unsigned
, /* complain_on_overflow */
1496 bfd_elf_generic_reloc
, /* special_function */
1497 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12
), /* name */
1498 false, /* partial_inplace */
1500 0x3ffc00, /* dst_mask */
1501 false), /* pcrel_offset */
1503 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, but no overflow check. */
1504 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12_NC
), /* type */
1508 false, /* pc_relative */
1510 complain_overflow_dont
, /* complain_on_overflow */
1511 bfd_elf_generic_reloc
, /* special_function */
1512 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12_NC
), /* name */
1513 false, /* partial_inplace */
1515 0x7fc00, /* dst_mask */
1516 false), /* pcrel_offset */
1518 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1519 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12
), /* type */
1523 false, /* pc_relative */
1525 complain_overflow_unsigned
, /* complain_on_overflow */
1526 bfd_elf_generic_reloc
, /* special_function */
1527 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12
), /* name */
1528 false, /* partial_inplace */
1530 0x3ffc00, /* dst_mask */
1531 false), /* pcrel_offset */
1533 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, but no overflow check. */
1534 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12_NC
), /* type */
1538 false, /* pc_relative */
1540 complain_overflow_dont
, /* complain_on_overflow */
1541 bfd_elf_generic_reloc
, /* special_function */
1542 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12_NC
), /* name */
1543 false, /* partial_inplace */
1545 0x3ffc00, /* dst_mask */
1546 false), /* pcrel_offset */
1548 /* MOVZ: bit[15:0] of byte offset to module TLS base address. */
1549 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0
), /* type */
1553 false, /* pc_relative */
1555 complain_overflow_unsigned
, /* complain_on_overflow */
1556 bfd_elf_generic_reloc
, /* special_function */
1557 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0
), /* name */
1558 false, /* partial_inplace */
1560 0xffff, /* dst_mask */
1561 false), /* pcrel_offset */
1563 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */
1564 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0_NC
), /* type */
1568 false, /* pc_relative */
1570 complain_overflow_dont
, /* complain_on_overflow */
1571 bfd_elf_generic_reloc
, /* special_function */
1572 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0_NC
), /* name */
1573 false, /* partial_inplace */
1575 0xffff, /* dst_mask */
1576 false), /* pcrel_offset */
1578 /* MOVZ: bit[31:16] of byte offset to module TLS base address. */
1579 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G1
), /* type */
1580 16, /* rightshift */
1583 false, /* pc_relative */
1585 complain_overflow_unsigned
, /* complain_on_overflow */
1586 bfd_elf_generic_reloc
, /* special_function */
1587 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1
), /* name */
1588 false, /* partial_inplace */
1590 0xffff, /* dst_mask */
1591 false), /* pcrel_offset */
1593 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */
1594 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G1_NC
), /* type */
1595 16, /* rightshift */
1598 false, /* pc_relative */
1600 complain_overflow_dont
, /* complain_on_overflow */
1601 bfd_elf_generic_reloc
, /* special_function */
1602 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1_NC
), /* name */
1603 false, /* partial_inplace */
1605 0xffff, /* dst_mask */
1606 false), /* pcrel_offset */
1608 /* MOVZ: bit[47:32] of byte offset to module TLS base address. */
1609 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G2
), /* type */
1610 32, /* rightshift */
1613 false, /* pc_relative */
1615 complain_overflow_unsigned
, /* complain_on_overflow */
1616 bfd_elf_generic_reloc
, /* special_function */
1617 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G2
), /* name */
1618 false, /* partial_inplace */
1620 0xffff, /* dst_mask */
1621 false), /* pcrel_offset */
1623 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2
), /* type */
1624 32, /* rightshift */
1627 false, /* pc_relative */
1629 complain_overflow_unsigned
, /* complain_on_overflow */
1630 bfd_elf_generic_reloc
, /* special_function */
1631 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2
), /* name */
1632 false, /* partial_inplace */
1634 0xffff, /* dst_mask */
1635 false), /* pcrel_offset */
1637 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1
), /* type */
1638 16, /* rightshift */
1641 false, /* pc_relative */
1643 complain_overflow_dont
, /* complain_on_overflow */
1644 bfd_elf_generic_reloc
, /* special_function */
1645 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1
), /* name */
1646 false, /* partial_inplace */
1648 0xffff, /* dst_mask */
1649 false), /* pcrel_offset */
1651 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC
), /* type */
1652 16, /* rightshift */
1655 false, /* pc_relative */
1657 complain_overflow_dont
, /* complain_on_overflow */
1658 bfd_elf_generic_reloc
, /* special_function */
1659 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC
), /* name */
1660 false, /* partial_inplace */
1662 0xffff, /* dst_mask */
1663 false), /* pcrel_offset */
1665 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0
), /* type */
1669 false, /* pc_relative */
1671 complain_overflow_dont
, /* complain_on_overflow */
1672 bfd_elf_generic_reloc
, /* special_function */
1673 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0
), /* name */
1674 false, /* partial_inplace */
1676 0xffff, /* dst_mask */
1677 false), /* pcrel_offset */
1679 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
), /* type */
1683 false, /* pc_relative */
1685 complain_overflow_dont
, /* complain_on_overflow */
1686 bfd_elf_generic_reloc
, /* special_function */
1687 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC
), /* name */
1688 false, /* partial_inplace */
1690 0xffff, /* dst_mask */
1691 false), /* pcrel_offset */
1693 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12
), /* type */
1694 12, /* rightshift */
1697 false, /* pc_relative */
1699 complain_overflow_unsigned
, /* complain_on_overflow */
1700 bfd_elf_generic_reloc
, /* special_function */
1701 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12
), /* name */
1702 false, /* partial_inplace */
1704 0xfff, /* dst_mask */
1705 false), /* pcrel_offset */
1707 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12
), /* type */
1711 false, /* pc_relative */
1713 complain_overflow_unsigned
, /* complain_on_overflow */
1714 bfd_elf_generic_reloc
, /* special_function */
1715 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12
), /* name */
1716 false, /* partial_inplace */
1718 0xfff, /* dst_mask */
1719 false), /* pcrel_offset */
1721 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
), /* type */
1725 false, /* pc_relative */
1727 complain_overflow_dont
, /* complain_on_overflow */
1728 bfd_elf_generic_reloc
, /* special_function */
1729 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC
), /* name */
1730 false, /* partial_inplace */
1732 0xfff, /* dst_mask */
1733 false), /* pcrel_offset */
1735 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1736 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12
), /* type */
1740 false, /* pc_relative */
1742 complain_overflow_unsigned
, /* complain_on_overflow */
1743 bfd_elf_generic_reloc
, /* special_function */
1744 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12
), /* name */
1745 false, /* partial_inplace */
1747 0x1ffc00, /* dst_mask */
1748 false), /* pcrel_offset */
1750 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check. */
1751 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12_NC
), /* type */
1755 false, /* pc_relative */
1757 complain_overflow_dont
, /* complain_on_overflow */
1758 bfd_elf_generic_reloc
, /* special_function */
1759 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12_NC
), /* name */
1760 false, /* partial_inplace */
1762 0x1ffc00, /* dst_mask */
1763 false), /* pcrel_offset */
1765 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1766 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12
), /* type */
1770 false, /* pc_relative */
1772 complain_overflow_unsigned
, /* complain_on_overflow */
1773 bfd_elf_generic_reloc
, /* special_function */
1774 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12
), /* name */
1775 false, /* partial_inplace */
1777 0xffc00, /* dst_mask */
1778 false), /* pcrel_offset */
1780 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check. */
1781 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12_NC
), /* type */
1785 false, /* pc_relative */
1787 complain_overflow_dont
, /* complain_on_overflow */
1788 bfd_elf_generic_reloc
, /* special_function */
1789 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12_NC
), /* name */
1790 false, /* partial_inplace */
1792 0xffc00, /* dst_mask */
1793 false), /* pcrel_offset */
1795 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1796 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12
), /* type */
1800 false, /* pc_relative */
1802 complain_overflow_unsigned
, /* complain_on_overflow */
1803 bfd_elf_generic_reloc
, /* special_function */
1804 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12
), /* name */
1805 false, /* partial_inplace */
1807 0x7fc00, /* dst_mask */
1808 false), /* pcrel_offset */
1810 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check. */
1811 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12_NC
), /* type */
1815 false, /* pc_relative */
1817 complain_overflow_dont
, /* complain_on_overflow */
1818 bfd_elf_generic_reloc
, /* special_function */
1819 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12_NC
), /* name */
1820 false, /* partial_inplace */
1822 0x7fc00, /* dst_mask */
1823 false), /* pcrel_offset */
1825 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1826 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12
), /* type */
1830 false, /* pc_relative */
1832 complain_overflow_unsigned
, /* complain_on_overflow */
1833 bfd_elf_generic_reloc
, /* special_function */
1834 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12
), /* name */
1835 false, /* partial_inplace */
1837 0x3ffc00, /* dst_mask */
1838 false), /* pcrel_offset */
1840 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check. */
1841 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12_NC
), /* type */
1845 false, /* pc_relative */
1847 complain_overflow_dont
, /* complain_on_overflow */
1848 bfd_elf_generic_reloc
, /* special_function */
1849 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12_NC
), /* name */
1850 false, /* partial_inplace */
1852 0x3ffc00, /* dst_mask */
1853 false), /* pcrel_offset */
1855 HOWTO (AARCH64_R (TLSDESC_LD_PREL19
), /* type */
1859 true, /* pc_relative */
1861 complain_overflow_dont
, /* complain_on_overflow */
1862 bfd_elf_generic_reloc
, /* special_function */
1863 AARCH64_R_STR (TLSDESC_LD_PREL19
), /* name */
1864 false, /* partial_inplace */
1866 0x0ffffe0, /* dst_mask */
1867 true), /* pcrel_offset */
1869 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21
), /* type */
1873 true, /* pc_relative */
1875 complain_overflow_dont
, /* complain_on_overflow */
1876 bfd_elf_generic_reloc
, /* special_function */
1877 AARCH64_R_STR (TLSDESC_ADR_PREL21
), /* name */
1878 false, /* partial_inplace */
1880 0x1fffff, /* dst_mask */
1881 true), /* pcrel_offset */
1883 /* Get to the page for the GOT entry for the symbol
1884 (G(S) - P) using an ADRP instruction. */
1885 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21
), /* type */
1886 12, /* rightshift */
1889 true, /* pc_relative */
1891 complain_overflow_dont
, /* complain_on_overflow */
1892 bfd_elf_generic_reloc
, /* special_function */
1893 AARCH64_R_STR (TLSDESC_ADR_PAGE21
), /* name */
1894 false, /* partial_inplace */
1896 0x1fffff, /* dst_mask */
1897 true), /* pcrel_offset */
1899 /* LD64: GOT offset G(S) & 0xff8. */
1900 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12
), /* type */
1904 false, /* pc_relative */
1906 complain_overflow_dont
, /* complain_on_overflow */
1907 bfd_elf_generic_reloc
, /* special_function */
1908 AARCH64_R_STR (TLSDESC_LD64_LO12
), /* name */
1909 false, /* partial_inplace */
1911 0xff8, /* dst_mask */
1912 false), /* pcrel_offset */
1914 /* LD32: GOT offset G(S) & 0xffc. */
1915 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC
), /* type */
1919 false, /* pc_relative */
1921 complain_overflow_dont
, /* complain_on_overflow */
1922 bfd_elf_generic_reloc
, /* special_function */
1923 AARCH64_R_STR (TLSDESC_LD32_LO12_NC
), /* name */
1924 false, /* partial_inplace */
1926 0xffc, /* dst_mask */
1927 false), /* pcrel_offset */
1929 /* ADD: GOT offset G(S) & 0xfff. */
1930 HOWTO (AARCH64_R (TLSDESC_ADD_LO12
), /* type */
1934 false, /* pc_relative */
1936 complain_overflow_dont
,/* complain_on_overflow */
1937 bfd_elf_generic_reloc
, /* special_function */
1938 AARCH64_R_STR (TLSDESC_ADD_LO12
), /* name */
1939 false, /* partial_inplace */
1941 0xfff, /* dst_mask */
1942 false), /* pcrel_offset */
1944 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1
), /* type */
1945 16, /* rightshift */
1948 false, /* pc_relative */
1950 complain_overflow_unsigned
, /* complain_on_overflow */
1951 bfd_elf_generic_reloc
, /* special_function */
1952 AARCH64_R_STR (TLSDESC_OFF_G1
), /* name */
1953 false, /* partial_inplace */
1955 0xffff, /* dst_mask */
1956 false), /* pcrel_offset */
1958 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC
), /* type */
1962 false, /* pc_relative */
1964 complain_overflow_dont
, /* complain_on_overflow */
1965 bfd_elf_generic_reloc
, /* special_function */
1966 AARCH64_R_STR (TLSDESC_OFF_G0_NC
), /* name */
1967 false, /* partial_inplace */
1969 0xffff, /* dst_mask */
1970 false), /* pcrel_offset */
1972 HOWTO64 (AARCH64_R (TLSDESC_LDR
), /* type */
1976 false, /* pc_relative */
1978 complain_overflow_dont
, /* complain_on_overflow */
1979 bfd_elf_generic_reloc
, /* special_function */
1980 AARCH64_R_STR (TLSDESC_LDR
), /* name */
1981 false, /* partial_inplace */
1984 false), /* pcrel_offset */
1986 HOWTO64 (AARCH64_R (TLSDESC_ADD
), /* type */
1990 false, /* pc_relative */
1992 complain_overflow_dont
, /* complain_on_overflow */
1993 bfd_elf_generic_reloc
, /* special_function */
1994 AARCH64_R_STR (TLSDESC_ADD
), /* name */
1995 false, /* partial_inplace */
1998 false), /* pcrel_offset */
2000 HOWTO (AARCH64_R (TLSDESC_CALL
), /* type */
2004 false, /* pc_relative */
2006 complain_overflow_dont
, /* complain_on_overflow */
2007 bfd_elf_generic_reloc
, /* special_function */
2008 AARCH64_R_STR (TLSDESC_CALL
), /* name */
2009 false, /* partial_inplace */
2012 false), /* pcrel_offset */
2014 HOWTO (AARCH64_R (COPY
), /* type */
2018 false, /* pc_relative */
2020 complain_overflow_bitfield
, /* complain_on_overflow */
2021 bfd_elf_generic_reloc
, /* special_function */
2022 AARCH64_R_STR (COPY
), /* name */
2023 true, /* partial_inplace */
2025 0xffffffff, /* dst_mask */
2026 false), /* pcrel_offset */
2028 HOWTO (AARCH64_R (GLOB_DAT
), /* type */
2032 false, /* pc_relative */
2034 complain_overflow_bitfield
, /* complain_on_overflow */
2035 bfd_elf_generic_reloc
, /* special_function */
2036 AARCH64_R_STR (GLOB_DAT
), /* name */
2037 true, /* partial_inplace */
2039 0xffffffff, /* dst_mask */
2040 false), /* pcrel_offset */
2042 HOWTO (AARCH64_R (JUMP_SLOT
), /* type */
2046 false, /* pc_relative */
2048 complain_overflow_bitfield
, /* complain_on_overflow */
2049 bfd_elf_generic_reloc
, /* special_function */
2050 AARCH64_R_STR (JUMP_SLOT
), /* name */
2051 true, /* partial_inplace */
2053 0xffffffff, /* dst_mask */
2054 false), /* pcrel_offset */
2056 HOWTO (AARCH64_R (RELATIVE
), /* type */
2060 false, /* pc_relative */
2062 complain_overflow_bitfield
, /* complain_on_overflow */
2063 bfd_elf_generic_reloc
, /* special_function */
2064 AARCH64_R_STR (RELATIVE
), /* name */
2065 true, /* partial_inplace */
2067 ALL_ONES
, /* dst_mask */
2068 false), /* pcrel_offset */
2070 HOWTO (AARCH64_R (TLS_DTPMOD
), /* type */
2074 false, /* pc_relative */
2076 complain_overflow_dont
, /* complain_on_overflow */
2077 bfd_elf_generic_reloc
, /* special_function */
2079 AARCH64_R_STR (TLS_DTPMOD64
), /* name */
2081 AARCH64_R_STR (TLS_DTPMOD
), /* name */
2083 false, /* partial_inplace */
2085 ALL_ONES
, /* dst_mask */
2086 false), /* pc_reloffset */
2088 HOWTO (AARCH64_R (TLS_DTPREL
), /* type */
2092 false, /* pc_relative */
2094 complain_overflow_dont
, /* complain_on_overflow */
2095 bfd_elf_generic_reloc
, /* special_function */
2097 AARCH64_R_STR (TLS_DTPREL64
), /* name */
2099 AARCH64_R_STR (TLS_DTPREL
), /* name */
2101 false, /* partial_inplace */
2103 ALL_ONES
, /* dst_mask */
2104 false), /* pcrel_offset */
2106 HOWTO (AARCH64_R (TLS_TPREL
), /* type */
2110 false, /* pc_relative */
2112 complain_overflow_dont
, /* complain_on_overflow */
2113 bfd_elf_generic_reloc
, /* special_function */
2115 AARCH64_R_STR (TLS_TPREL64
), /* name */
2117 AARCH64_R_STR (TLS_TPREL
), /* name */
2119 false, /* partial_inplace */
2121 ALL_ONES
, /* dst_mask */
2122 false), /* pcrel_offset */
2124 HOWTO (AARCH64_R (TLSDESC
), /* type */
2128 false, /* pc_relative */
2130 complain_overflow_dont
, /* complain_on_overflow */
2131 bfd_elf_generic_reloc
, /* special_function */
2132 AARCH64_R_STR (TLSDESC
), /* name */
2133 false, /* partial_inplace */
2135 ALL_ONES
, /* dst_mask */
2136 false), /* pcrel_offset */
2138 HOWTO (AARCH64_R (IRELATIVE
), /* type */
2142 false, /* pc_relative */
2144 complain_overflow_bitfield
, /* complain_on_overflow */
2145 bfd_elf_generic_reloc
, /* special_function */
2146 AARCH64_R_STR (IRELATIVE
), /* name */
2147 false, /* partial_inplace */
2149 ALL_ONES
, /* dst_mask */
2150 false), /* pcrel_offset */
2155 static reloc_howto_type elfNN_aarch64_howto_none
=
2156 HOWTO (R_AARCH64_NONE
, /* type */
2160 false, /* pc_relative */
2162 complain_overflow_dont
,/* complain_on_overflow */
2163 bfd_elf_generic_reloc
, /* special_function */
2164 "R_AARCH64_NONE", /* name */
2165 false, /* partial_inplace */
2168 false); /* pcrel_offset */
2170 /* Given HOWTO, return the bfd internal relocation enumerator. */
2172 static bfd_reloc_code_real_type
2173 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type
*howto
)
2176 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table
);
2177 const ptrdiff_t offset
2178 = howto
- elfNN_aarch64_howto_table
;
2180 if (offset
> 0 && offset
< size
- 1)
2181 return BFD_RELOC_AARCH64_RELOC_START
+ offset
;
2183 if (howto
== &elfNN_aarch64_howto_none
)
2184 return BFD_RELOC_AARCH64_NONE
;
2186 return BFD_RELOC_AARCH64_RELOC_START
;
2189 /* Given R_TYPE, return the bfd internal relocation enumerator. */
2191 static bfd_reloc_code_real_type
2192 elfNN_aarch64_bfd_reloc_from_type (bfd
*abfd
, unsigned int r_type
)
2194 static bool initialized_p
= false;
2195 /* Indexed by R_TYPE, values are offsets in the howto_table. */
2196 static unsigned int offsets
[R_AARCH64_end
];
2202 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
2203 if (elfNN_aarch64_howto_table
[i
].type
!= 0)
2204 offsets
[elfNN_aarch64_howto_table
[i
].type
] = i
;
2206 initialized_p
= true;
2209 if (r_type
== R_AARCH64_NONE
|| r_type
== R_AARCH64_NULL
)
2210 return BFD_RELOC_AARCH64_NONE
;
2212 /* PR 17512: file: b371e70a. */
2213 if (r_type
>= R_AARCH64_end
)
2215 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
2217 bfd_set_error (bfd_error_bad_value
);
2218 return BFD_RELOC_AARCH64_NONE
;
2221 return BFD_RELOC_AARCH64_RELOC_START
+ offsets
[r_type
];
2224 struct elf_aarch64_reloc_map
2226 bfd_reloc_code_real_type from
;
2227 bfd_reloc_code_real_type to
;
2230 /* Map bfd generic reloc to AArch64-specific reloc. */
2231 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map
[] =
2233 {BFD_RELOC_NONE
, BFD_RELOC_AARCH64_NONE
},
2235 /* Basic data relocations. */
2236 {BFD_RELOC_CTOR
, BFD_RELOC_AARCH64_NN
},
2237 {BFD_RELOC_64
, BFD_RELOC_AARCH64_64
},
2238 {BFD_RELOC_32
, BFD_RELOC_AARCH64_32
},
2239 {BFD_RELOC_16
, BFD_RELOC_AARCH64_16
},
2240 {BFD_RELOC_64_PCREL
, BFD_RELOC_AARCH64_64_PCREL
},
2241 {BFD_RELOC_32_PCREL
, BFD_RELOC_AARCH64_32_PCREL
},
2242 {BFD_RELOC_16_PCREL
, BFD_RELOC_AARCH64_16_PCREL
},
2245 /* Given the bfd internal relocation enumerator in CODE, return the
2246 corresponding howto entry. */
2248 static reloc_howto_type
*
2249 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code
)
2253 /* Convert bfd generic reloc to AArch64-specific reloc. */
2254 if (code
< BFD_RELOC_AARCH64_RELOC_START
2255 || code
> BFD_RELOC_AARCH64_RELOC_END
)
2256 for (i
= 0; i
< ARRAY_SIZE (elf_aarch64_reloc_map
); i
++)
2257 if (elf_aarch64_reloc_map
[i
].from
== code
)
2259 code
= elf_aarch64_reloc_map
[i
].to
;
2263 if (code
> BFD_RELOC_AARCH64_RELOC_START
2264 && code
< BFD_RELOC_AARCH64_RELOC_END
)
2265 if (elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
].type
)
2266 return &elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
];
2268 if (code
== BFD_RELOC_AARCH64_NONE
)
2269 return &elfNN_aarch64_howto_none
;
2274 static reloc_howto_type
*
2275 elfNN_aarch64_howto_from_type (bfd
*abfd
, unsigned int r_type
)
2277 bfd_reloc_code_real_type val
;
2278 reloc_howto_type
*howto
;
2283 bfd_set_error (bfd_error_bad_value
);
2288 if (r_type
== R_AARCH64_NONE
)
2289 return &elfNN_aarch64_howto_none
;
2291 val
= elfNN_aarch64_bfd_reloc_from_type (abfd
, r_type
);
2292 howto
= elfNN_aarch64_howto_from_bfd_reloc (val
);
2297 bfd_set_error (bfd_error_bad_value
);
2302 elfNN_aarch64_info_to_howto (bfd
*abfd
, arelent
*bfd_reloc
,
2303 Elf_Internal_Rela
*elf_reloc
)
2305 unsigned int r_type
;
2307 r_type
= ELFNN_R_TYPE (elf_reloc
->r_info
);
2308 bfd_reloc
->howto
= elfNN_aarch64_howto_from_type (abfd
, r_type
);
2310 if (bfd_reloc
->howto
== NULL
)
2312 /* xgettext:c-format */
2313 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd
, r_type
);
2319 static reloc_howto_type
*
2320 elfNN_aarch64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2321 bfd_reloc_code_real_type code
)
2323 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (code
);
2328 bfd_set_error (bfd_error_bad_value
);
2332 static reloc_howto_type
*
2333 elfNN_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2338 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
2339 if (elfNN_aarch64_howto_table
[i
].name
!= NULL
2340 && strcasecmp (elfNN_aarch64_howto_table
[i
].name
, r_name
) == 0)
2341 return &elfNN_aarch64_howto_table
[i
];
2346 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
2347 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
2348 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
2349 #define TARGET_BIG_NAME "elfNN-bigaarch64"
2351 /* The linker script knows the section names for placement.
2352 The entry_names are used to do simple name mangling on the stubs.
2353 Given a function name, and its type, the stub can be found. The
2354 name can be changed. The only requirement is the %s be present. */
2355 #define STUB_ENTRY_NAME "__%s_veneer"
2357 /* Stub name for a BTI landing stub. */
2358 #define BTI_STUB_ENTRY_NAME "__%s_bti_veneer"
2360 /* The name of the dynamic interpreter. This is put in the .interp
2362 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
2364 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
2365 (((1 << 25) - 1) << 2)
2366 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
2369 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
2370 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
2373 aarch64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
2375 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
2376 return offset
<= AARCH64_MAX_ADRP_IMM
&& offset
>= AARCH64_MIN_ADRP_IMM
;
2380 aarch64_valid_branch_p (bfd_vma value
, bfd_vma place
)
2382 bfd_signed_vma offset
= (bfd_signed_vma
) (value
- place
);
2383 return (offset
<= AARCH64_MAX_FWD_BRANCH_OFFSET
2384 && offset
>= AARCH64_MAX_BWD_BRANCH_OFFSET
);
2387 static const uint32_t aarch64_adrp_branch_stub
[] =
2389 0x90000010, /* adrp ip0, X */
2390 /* R_AARCH64_ADR_HI21_PCREL(X) */
2391 0x91000210, /* add ip0, ip0, :lo12:X */
2392 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2393 0xd61f0200, /* br ip0 */
2396 static const uint32_t aarch64_long_branch_stub
[] =
2399 0x58000090, /* ldr ip0, 1f */
2401 0x18000090, /* ldr wip0, 1f */
2403 0x10000011, /* adr ip1, #0 */
2404 0x8b110210, /* add ip0, ip0, ip1 */
2405 0xd61f0200, /* br ip0 */
2406 0x00000000, /* 1: .xword or .word
2407 R_AARCH64_PRELNN(X) + 12
2412 static const uint32_t aarch64_bti_direct_branch_stub
[] =
2414 0xd503245f, /* bti c */
2415 0x14000000, /* b <label> */
2418 static const uint32_t aarch64_erratum_835769_stub
[] =
2420 0x00000000, /* Placeholder for multiply accumulate. */
2421 0x14000000, /* b <label> */
2424 static const uint32_t aarch64_erratum_843419_stub
[] =
2426 0x00000000, /* Placeholder for LDR instruction. */
2427 0x14000000, /* b <label> */
2430 /* Section name for stubs is the associated section name plus this
2432 #define STUB_SUFFIX ".stub"
2434 enum elf_aarch64_stub_type
2437 aarch64_stub_adrp_branch
,
2438 aarch64_stub_long_branch
,
2439 aarch64_stub_bti_direct_branch
,
2440 aarch64_stub_erratum_835769_veneer
,
2441 aarch64_stub_erratum_843419_veneer
,
2444 struct elf_aarch64_stub_hash_entry
2446 /* Base hash table entry structure. */
2447 struct bfd_hash_entry root
;
2449 /* The stub section. */
2452 /* Offset within stub_sec of the beginning of this stub. */
2453 bfd_vma stub_offset
;
2455 /* Given the symbol's value and its section we can determine its final
2456 value when building the stubs (so the stub knows where to jump). */
2457 bfd_vma target_value
;
2458 asection
*target_section
;
2460 enum elf_aarch64_stub_type stub_type
;
2462 /* The symbol table entry, if any, that this was derived from. */
2463 struct elf_aarch64_link_hash_entry
*h
;
2465 /* Destination symbol type */
2466 unsigned char st_type
;
2468 /* The target is also a stub. */
2471 /* Where this stub is being called from, or, in the case of combined
2472 stub sections, the first input section in the group. */
2475 /* The name for the local symbol at the start of this stub. The
2476 stub name in the hash table has to be unique; this does not, so
2477 it can be friendlier. */
2480 /* The instruction which caused this stub to be generated (only valid for
2481 erratum 835769 workaround stubs at present). */
2482 uint32_t veneered_insn
;
2484 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
2485 bfd_vma adrp_offset
;
2488 /* Used to build a map of a section. This is required for mixed-endian
2491 typedef struct elf_elf_section_map
2496 elf_aarch64_section_map
;
2499 typedef struct _aarch64_elf_section_data
2501 struct bfd_elf_section_data elf
;
2502 unsigned int mapcount
;
2503 unsigned int mapsize
;
2504 elf_aarch64_section_map
*map
;
2506 _aarch64_elf_section_data
;
2508 #define elf_aarch64_section_data(sec) \
2509 ((_aarch64_elf_section_data *) elf_section_data (sec))
2511 /* The size of the thread control block which is defined to be two pointers. */
2512 #define TCB_SIZE (ARCH_SIZE/8)*2
2514 struct elf_aarch64_local_symbol
2516 unsigned int got_type
;
2517 bfd_signed_vma got_refcount
;
2520 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2521 offset is from the end of the jump table and reserved entries
2524 The magic value (bfd_vma) -1 indicates that an offset has not be
2526 bfd_vma tlsdesc_got_jump_table_offset
;
2529 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
2531 #define is_aarch64_elf(bfd) \
2532 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2533 && elf_tdata (bfd) != NULL \
2534 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2537 elfNN_aarch64_mkobject (bfd
*abfd
)
2539 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
));
2542 #define elf_aarch64_hash_entry(ent) \
2543 ((struct elf_aarch64_link_hash_entry *)(ent))
2545 #define GOT_UNKNOWN 0
2546 #define GOT_NORMAL 1
2547 #define GOT_TLS_GD 2
2548 #define GOT_TLS_IE 4
2549 #define GOT_TLSDESC_GD 8
2551 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
2553 /* AArch64 ELF linker hash entry. */
2554 struct elf_aarch64_link_hash_entry
2556 struct elf_link_hash_entry root
;
2558 /* Since PLT entries have variable size, we need to record the
2559 index into .got.plt instead of recomputing it from the PLT
2561 bfd_signed_vma plt_got_offset
;
2563 /* Bit mask representing the type of GOT entry(s) if any required by
2565 unsigned int got_type
;
2567 /* TRUE if symbol is defined as a protected symbol. */
2568 unsigned int def_protected
: 1;
2570 /* A pointer to the most recently used stub hash entry against this
2572 struct elf_aarch64_stub_hash_entry
*stub_cache
;
2574 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
2575 is from the end of the jump table and reserved entries within the PLTGOT.
2577 The magic value (bfd_vma) -1 indicates that an offset has not
2579 bfd_vma tlsdesc_got_jump_table_offset
;
2583 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
2585 unsigned long r_symndx
)
2588 return elf_aarch64_hash_entry (h
)->got_type
;
2590 if (! elf_aarch64_locals (abfd
))
2593 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
2596 /* Get the AArch64 elf linker hash table from a link_info structure. */
2597 #define elf_aarch64_hash_table(info) \
2598 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
2600 #define aarch64_stub_hash_lookup(table, string, create, copy) \
2601 ((struct elf_aarch64_stub_hash_entry *) \
2602 bfd_hash_lookup ((table), (string), (create), (copy)))
2604 /* AArch64 ELF linker hash table. */
2605 struct elf_aarch64_link_hash_table
2607 /* The main hash table. */
2608 struct elf_link_hash_table root
;
2610 /* Nonzero to force PIC branch veneers. */
2613 /* Fix erratum 835769. */
2614 int fix_erratum_835769
;
2616 /* Fix erratum 843419. */
2617 erratum_84319_opts fix_erratum_843419
;
2619 /* Don't apply link-time values for dynamic relocations. */
2620 int no_apply_dynamic_relocs
;
2622 /* The number of bytes in the initial entry in the PLT. */
2623 bfd_size_type plt_header_size
;
2625 /* The bytes of the initial PLT entry. */
2626 const bfd_byte
*plt0_entry
;
2628 /* The number of bytes in the subsequent PLT entries. */
2629 bfd_size_type plt_entry_size
;
2631 /* The bytes of the subsequent PLT entry. */
2632 const bfd_byte
*plt_entry
;
2634 /* PLT entries have a common shape, but may have some pre-amble
2635 instructions (such as BTI). This delta is used to factor this
2636 out of the common code. */
2637 int plt_entry_delta
;
2639 /* For convenience in allocate_dynrelocs. */
2642 /* The amount of space used by the reserved portion of the sgotplt
2643 section, plus whatever space is used by the jump slots. */
2644 bfd_vma sgotplt_jump_table_size
;
2646 /* The stub hash table. */
2647 struct bfd_hash_table stub_hash_table
;
2649 /* Linker stub bfd. */
2652 /* Linker call-backs. */
2653 asection
*(*add_stub_section
) (const char *, asection
*);
2654 void (*layout_sections_again
) (void);
2656 /* Array to keep track of which stub sections have been created, and
2657 information on stub grouping. */
2660 /* This is the section to which stubs in the group will be
2663 /* The stub section. */
2667 /* Assorted information used by elfNN_aarch64_size_stubs. */
2668 unsigned int bfd_count
;
2669 unsigned int top_index
;
2670 asection
**input_list
;
2672 /* True when two stubs are added where one targets the other, happens
2673 when BTI stubs are inserted and then the stub layout must not change
2674 during elfNN_aarch64_build_stubs. */
2675 bool has_double_stub
;
2677 /* JUMP_SLOT relocs for variant PCS symbols may be present. */
2680 /* The number of bytes in the PLT enty for the TLS descriptor. */
2681 bfd_size_type tlsdesc_plt_entry_size
;
2683 /* Used by local STT_GNU_IFUNC symbols. */
2684 htab_t loc_hash_table
;
2685 void * loc_hash_memory
;
2687 /* Array of relative relocs to be emitted in DT_RELR format. */
2688 bfd_size_type relr_alloc
;
2689 bfd_size_type relr_count
;
2695 /* Sorted output addresses of above relative relocs. */
2696 bfd_vma
*relr_sorted
;
2697 /* Layout recomputation count. */
2698 bfd_size_type relr_layout_iter
;
2701 /* Create an entry in an AArch64 ELF linker hash table. */
2703 static struct bfd_hash_entry
*
2704 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
2705 struct bfd_hash_table
*table
,
2708 struct elf_aarch64_link_hash_entry
*ret
=
2709 (struct elf_aarch64_link_hash_entry
*) entry
;
2711 /* Allocate the structure if it has not already been allocated by a
2714 ret
= bfd_hash_allocate (table
,
2715 sizeof (struct elf_aarch64_link_hash_entry
));
2717 return (struct bfd_hash_entry
*) ret
;
2719 /* Call the allocation method of the superclass. */
2720 ret
= ((struct elf_aarch64_link_hash_entry
*)
2721 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
2725 ret
->got_type
= GOT_UNKNOWN
;
2726 ret
->def_protected
= 0;
2727 ret
->plt_got_offset
= (bfd_vma
) - 1;
2728 ret
->stub_cache
= NULL
;
2729 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
2732 return (struct bfd_hash_entry
*) ret
;
2735 /* Initialize an entry in the stub hash table. */
2737 static struct bfd_hash_entry
*
2738 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
2739 struct bfd_hash_table
*table
, const char *string
)
2741 /* Allocate the structure if it has not already been allocated by a
2745 entry
= bfd_hash_allocate (table
,
2747 elf_aarch64_stub_hash_entry
));
2752 /* Call the allocation method of the superclass. */
2753 entry
= bfd_hash_newfunc (entry
, table
, string
);
2756 struct elf_aarch64_stub_hash_entry
*eh
;
2758 /* Initialize the local fields. */
2759 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
2760 memset (&eh
->stub_sec
, 0,
2761 (sizeof (struct elf_aarch64_stub_hash_entry
)
2762 - offsetof (struct elf_aarch64_stub_hash_entry
, stub_sec
)));
2768 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
2769 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2770 as global symbol. We reuse indx and dynstr_index for local symbol
2771 hash since they aren't used by global symbols in this backend. */
2774 elfNN_aarch64_local_htab_hash (const void *ptr
)
2776 struct elf_link_hash_entry
*h
2777 = (struct elf_link_hash_entry
*) ptr
;
2778 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
2781 /* Compare local hash entries. */
2784 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
2786 struct elf_link_hash_entry
*h1
2787 = (struct elf_link_hash_entry
*) ptr1
;
2788 struct elf_link_hash_entry
*h2
2789 = (struct elf_link_hash_entry
*) ptr2
;
2791 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
2794 /* Find and/or create a hash entry for local symbol. */
2796 static struct elf_link_hash_entry
*
2797 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
2798 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
2801 struct elf_aarch64_link_hash_entry e
, *ret
;
2802 asection
*sec
= abfd
->sections
;
2803 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
2804 ELFNN_R_SYM (rel
->r_info
));
2807 e
.root
.indx
= sec
->id
;
2808 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2809 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
2810 create
? INSERT
: NO_INSERT
);
2817 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
2821 ret
= (struct elf_aarch64_link_hash_entry
*)
2822 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
2823 sizeof (struct elf_aarch64_link_hash_entry
));
2826 memset (ret
, 0, sizeof (*ret
));
2827 ret
->root
.indx
= sec
->id
;
2828 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
2829 ret
->root
.dynindx
= -1;
2835 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2838 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
2839 struct elf_link_hash_entry
*dir
,
2840 struct elf_link_hash_entry
*ind
)
2842 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
2844 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
2845 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
2847 if (ind
->root
.type
== bfd_link_hash_indirect
)
2849 /* Copy over PLT info. */
2850 if (dir
->got
.refcount
<= 0)
2852 edir
->got_type
= eind
->got_type
;
2853 eind
->got_type
= GOT_UNKNOWN
;
2857 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2860 /* Merge non-visibility st_other attributes. */
2863 elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry
*h
,
2864 unsigned int st_other
,
2866 bool dynamic ATTRIBUTE_UNUSED
)
2870 struct elf_aarch64_link_hash_entry
*eh
2871 = (struct elf_aarch64_link_hash_entry
*)h
;
2872 eh
->def_protected
= ELF_ST_VISIBILITY (st_other
) == STV_PROTECTED
;
2875 unsigned int isym_sto
= st_other
& ~ELF_ST_VISIBILITY (-1);
2876 unsigned int h_sto
= h
->other
& ~ELF_ST_VISIBILITY (-1);
2878 if (isym_sto
== h_sto
)
2881 if (isym_sto
& ~STO_AARCH64_VARIANT_PCS
)
2882 /* Not fatal, this callback cannot fail. */
2883 _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"),
2884 h
->root
.root
.string
, isym_sto
);
2886 /* Note: Ideally we would warn about any attribute mismatch, but
2887 this api does not allow that without substantial changes. */
2888 if (isym_sto
& STO_AARCH64_VARIANT_PCS
)
2889 h
->other
|= STO_AARCH64_VARIANT_PCS
;
2892 /* Destroy an AArch64 elf linker hash table. */
2895 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
2897 struct elf_aarch64_link_hash_table
*ret
2898 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
2900 if (ret
->loc_hash_table
)
2901 htab_delete (ret
->loc_hash_table
);
2902 if (ret
->loc_hash_memory
)
2903 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
2905 bfd_hash_table_free (&ret
->stub_hash_table
);
2906 _bfd_elf_link_hash_table_free (obfd
);
2909 /* Create an AArch64 elf linker hash table. */
2911 static struct bfd_link_hash_table
*
2912 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
2914 struct elf_aarch64_link_hash_table
*ret
;
2915 size_t amt
= sizeof (struct elf_aarch64_link_hash_table
);
2917 ret
= bfd_zmalloc (amt
);
2921 if (!_bfd_elf_link_hash_table_init
2922 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
2923 sizeof (struct elf_aarch64_link_hash_entry
)))
2929 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
2930 ret
->plt0_entry
= elfNN_aarch64_small_plt0_entry
;
2931 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
2932 ret
->plt_entry_delta
= 0;
2933 ret
->plt_entry
= elfNN_aarch64_small_plt_entry
;
2934 ret
->tlsdesc_plt_entry_size
= PLT_TLSDESC_ENTRY_SIZE
;
2936 ret
->root
.tlsdesc_got
= (bfd_vma
) - 1;
2938 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
2939 sizeof (struct elf_aarch64_stub_hash_entry
)))
2941 _bfd_elf_link_hash_table_free (abfd
);
2945 ret
->loc_hash_table
= htab_try_create (1024,
2946 elfNN_aarch64_local_htab_hash
,
2947 elfNN_aarch64_local_htab_eq
,
2949 ret
->loc_hash_memory
= objalloc_create ();
2950 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
2952 elfNN_aarch64_link_hash_table_free (abfd
);
2955 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
2957 return &ret
->root
.root
;
2960 /* Perform relocation R_TYPE. Returns TRUE upon success, FALSE otherwise. */
2963 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
2964 bfd_vma offset
, bfd_vma value
)
2966 reloc_howto_type
*howto
;
2969 howto
= elfNN_aarch64_howto_from_type (input_bfd
, r_type
);
2970 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
2973 r_type
= elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
2974 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, r_type
, place
,
2976 return _bfd_aarch64_elf_put_addend (input_bfd
,
2977 input_section
->contents
+ offset
, r_type
,
2978 howto
, value
) == bfd_reloc_ok
;
2981 /* Determine the type of stub needed, if any, for a call. */
2983 static enum elf_aarch64_stub_type
2984 aarch64_type_of_stub (asection
*input_sec
,
2985 const Elf_Internal_Rela
*rel
,
2987 unsigned char st_type
,
2988 bfd_vma destination
)
2991 bfd_signed_vma branch_offset
;
2992 unsigned int r_type
;
2993 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
2995 if (st_type
!= STT_FUNC
2996 && (sym_sec
== input_sec
))
2999 /* Determine where the call point is. */
3000 location
= (input_sec
->output_offset
3001 + input_sec
->output_section
->vma
+ rel
->r_offset
);
3003 branch_offset
= (bfd_signed_vma
) (destination
- location
);
3005 r_type
= ELFNN_R_TYPE (rel
->r_info
);
3007 /* We don't want to redirect any old unconditional jump in this way,
3008 only one which is being used for a sibcall, where it is
3009 acceptable for the IP0 and IP1 registers to be clobbered. */
3010 if ((r_type
== AARCH64_R (CALL26
) || r_type
== AARCH64_R (JUMP26
))
3011 && (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
3012 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
))
3014 stub_type
= aarch64_stub_long_branch
;
3020 /* Build a name for an entry in the stub hash table. */
3023 elfNN_aarch64_stub_name (const asection
*input_section
,
3024 const asection
*sym_sec
,
3025 const struct elf_aarch64_link_hash_entry
*hash
,
3026 const Elf_Internal_Rela
*rel
)
3033 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
3034 stub_name
= bfd_malloc (len
);
3035 if (stub_name
!= NULL
)
3036 snprintf (stub_name
, len
, "%08x_%s+%" PRIx64
,
3037 (unsigned int) input_section
->id
,
3038 hash
->root
.root
.root
.string
,
3039 (uint64_t) rel
->r_addend
);
3043 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
3044 stub_name
= bfd_malloc (len
);
3045 if (stub_name
!= NULL
)
3046 snprintf (stub_name
, len
, "%08x_%x:%x+%" PRIx64
,
3047 (unsigned int) input_section
->id
,
3048 (unsigned int) sym_sec
->id
,
3049 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
3050 (uint64_t) rel
->r_addend
);
3056 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
3057 executable PLT slots where the executable never takes the address of those
3058 functions, the function symbols are not added to the hash table. */
3061 elf_aarch64_hash_symbol (struct elf_link_hash_entry
*h
)
3063 if (h
->plt
.offset
!= (bfd_vma
) -1
3065 && !h
->pointer_equality_needed
)
3068 return _bfd_elf_hash_symbol (h
);
3072 /* Look up an entry in the stub hash. Stub entries are cached because
3073 creating the stub name takes a bit of time. */
3075 static struct elf_aarch64_stub_hash_entry
*
3076 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
3077 const asection
*sym_sec
,
3078 struct elf_link_hash_entry
*hash
,
3079 const Elf_Internal_Rela
*rel
,
3080 struct elf_aarch64_link_hash_table
*htab
)
3082 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3083 struct elf_aarch64_link_hash_entry
*h
=
3084 (struct elf_aarch64_link_hash_entry
*) hash
;
3085 const asection
*id_sec
;
3087 if ((input_section
->flags
& SEC_CODE
) == 0)
3090 /* If this input section is part of a group of sections sharing one
3091 stub section, then use the id of the first section in the group.
3092 Stub names need to include a section id, as there may well be
3093 more than one stub used to reach say, printf, and we need to
3094 distinguish between them. */
3095 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
3097 if (h
!= NULL
&& h
->stub_cache
!= NULL
3098 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
3100 stub_entry
= h
->stub_cache
;
3106 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
);
3107 if (stub_name
== NULL
)
3110 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
3111 stub_name
, false, false);
3113 h
->stub_cache
= stub_entry
;
3122 /* Create a stub section. */
3125 _bfd_aarch64_create_stub_section (asection
*section
,
3126 struct elf_aarch64_link_hash_table
*htab
)
3132 namelen
= strlen (section
->name
);
3133 len
= namelen
+ sizeof (STUB_SUFFIX
);
3134 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
3138 memcpy (s_name
, section
->name
, namelen
);
3139 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
3140 return (*htab
->add_stub_section
) (s_name
, section
);
3144 /* Find or create a stub section for a link section.
3146 Fix or create the stub section used to collect stubs attached to
3147 the specified link section. */
3150 _bfd_aarch64_get_stub_for_link_section (asection
*link_section
,
3151 struct elf_aarch64_link_hash_table
*htab
)
3153 if (htab
->stub_group
[link_section
->id
].stub_sec
== NULL
)
3154 htab
->stub_group
[link_section
->id
].stub_sec
3155 = _bfd_aarch64_create_stub_section (link_section
, htab
);
3156 return htab
->stub_group
[link_section
->id
].stub_sec
;
3160 /* Find or create a stub section in the stub group for an input
3164 _bfd_aarch64_create_or_find_stub_sec (asection
*section
,
3165 struct elf_aarch64_link_hash_table
*htab
)
3167 asection
*link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3168 return _bfd_aarch64_get_stub_for_link_section (link_sec
, htab
);
3172 /* Add a new stub entry in the stub group associated with an input
3173 section to the stub hash. Not all fields of the new stub entry are
3176 static struct elf_aarch64_stub_hash_entry
*
3177 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name
,
3179 struct elf_aarch64_link_hash_table
*htab
)
3183 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3185 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3186 stub_sec
= _bfd_aarch64_create_or_find_stub_sec (section
, htab
);
3188 /* Enter this entry into the linker stub hash table. */
3189 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3191 if (stub_entry
== NULL
)
3193 /* xgettext:c-format */
3194 _bfd_error_handler (_("%pB: cannot create stub entry %s"),
3195 section
->owner
, stub_name
);
3199 stub_entry
->stub_sec
= stub_sec
;
3200 stub_entry
->stub_offset
= 0;
3201 stub_entry
->id_sec
= link_sec
;
3206 /* Add a new stub entry in the final stub section to the stub hash.
3207 Not all fields of the new stub entry are initialised. */
3209 static struct elf_aarch64_stub_hash_entry
*
3210 _bfd_aarch64_add_stub_entry_after (const char *stub_name
,
3211 asection
*link_section
,
3212 struct elf_aarch64_link_hash_table
*htab
)
3215 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3218 /* Only create the actual stub if we will end up needing it. */
3219 if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
3220 stub_sec
= _bfd_aarch64_get_stub_for_link_section (link_section
, htab
);
3221 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3223 if (stub_entry
== NULL
)
3225 _bfd_error_handler (_("cannot create stub entry %s"), stub_name
);
3229 stub_entry
->stub_sec
= stub_sec
;
3230 stub_entry
->stub_offset
= 0;
3231 stub_entry
->id_sec
= link_section
;
3238 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
3241 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3246 bfd_vma veneered_insn_loc
;
3247 bfd_vma veneer_entry_loc
;
3248 bfd_signed_vma branch_offset
= 0;
3249 unsigned int template_size
;
3250 unsigned int pad_size
= 0;
3251 const uint32_t *template;
3253 struct bfd_link_info
*info
;
3254 struct elf_aarch64_link_hash_table
*htab
;
3256 /* Massage our args to the form they really have. */
3257 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
3259 info
= (struct bfd_link_info
*) in_arg
;
3260 htab
= elf_aarch64_hash_table (info
);
3262 /* Fail if the target section could not be assigned to an output
3263 section. The user should fix his linker script. */
3264 if (stub_entry
->target_section
->output_section
== NULL
3265 && info
->non_contiguous_regions
)
3266 info
->callbacks
->einfo (_("%F%P: Could not assign `%pA' to an output section. "
3268 "--enable-non-contiguous-regions.\n"),
3269 stub_entry
->target_section
);
3271 stub_sec
= stub_entry
->stub_sec
;
3273 /* The layout must not change when a stub may be the target of another. */
3274 if (htab
->has_double_stub
)
3275 BFD_ASSERT (stub_entry
->stub_offset
== stub_sec
->size
);
3277 /* Make a note of the offset within the stubs for this entry. */
3278 stub_entry
->stub_offset
= stub_sec
->size
;
3279 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
3281 stub_bfd
= stub_sec
->owner
;
3283 /* This is the address of the stub destination. */
3284 sym_value
= (stub_entry
->target_value
3285 + stub_entry
->target_section
->output_offset
3286 + stub_entry
->target_section
->output_section
->vma
);
3288 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
3290 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
3291 + stub_sec
->output_offset
);
3293 /* See if we can relax the stub. */
3294 if (aarch64_valid_for_adrp_p (sym_value
, place
))
3296 stub_entry
->stub_type
= aarch64_stub_adrp_branch
;
3298 /* Avoid the relaxation changing the layout. */
3299 if (htab
->has_double_stub
)
3300 pad_size
= sizeof (aarch64_long_branch_stub
)
3301 - sizeof (aarch64_adrp_branch_stub
);
3305 switch (stub_entry
->stub_type
)
3307 case aarch64_stub_adrp_branch
:
3308 template = aarch64_adrp_branch_stub
;
3309 template_size
= sizeof (aarch64_adrp_branch_stub
);
3311 case aarch64_stub_long_branch
:
3312 template = aarch64_long_branch_stub
;
3313 template_size
= sizeof (aarch64_long_branch_stub
);
3315 case aarch64_stub_bti_direct_branch
:
3316 template = aarch64_bti_direct_branch_stub
;
3317 template_size
= sizeof (aarch64_bti_direct_branch_stub
);
3319 case aarch64_stub_erratum_835769_veneer
:
3320 template = aarch64_erratum_835769_stub
;
3321 template_size
= sizeof (aarch64_erratum_835769_stub
);
3323 case aarch64_stub_erratum_843419_veneer
:
3324 template = aarch64_erratum_843419_stub
;
3325 template_size
= sizeof (aarch64_erratum_843419_stub
);
3331 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
3333 bfd_putl32 (template[i
], loc
);
3337 template_size
+= pad_size
;
3338 template_size
= (template_size
+ 7) & ~7;
3339 stub_sec
->size
+= template_size
;
3341 switch (stub_entry
->stub_type
)
3343 case aarch64_stub_adrp_branch
:
3344 if (!aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
3345 stub_entry
->stub_offset
, sym_value
))
3346 /* The stub would not have been relaxed if the offset was out
3350 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
3351 stub_entry
->stub_offset
+ 4, sym_value
))
3355 case aarch64_stub_long_branch
:
3356 /* We want the value relative to the address 12 bytes back from the
3358 if (!aarch64_relocate (AARCH64_R (PRELNN
), stub_bfd
, stub_sec
,
3359 stub_entry
->stub_offset
+ 16, sym_value
+ 12))
3363 case aarch64_stub_bti_direct_branch
:
3364 if (!aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
3365 stub_entry
->stub_offset
+ 4, sym_value
))
3369 case aarch64_stub_erratum_835769_veneer
:
3370 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
3371 + stub_entry
->target_section
->output_offset
3372 + stub_entry
->target_value
;
3373 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
3374 + stub_entry
->stub_sec
->output_offset
3375 + stub_entry
->stub_offset
;
3376 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
3377 branch_offset
>>= 2;
3378 branch_offset
&= 0x3ffffff;
3379 bfd_putl32 (stub_entry
->veneered_insn
,
3380 stub_sec
->contents
+ stub_entry
->stub_offset
);
3381 bfd_putl32 (template[1] | branch_offset
,
3382 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
3385 case aarch64_stub_erratum_843419_veneer
:
3386 if (!aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
3387 stub_entry
->stub_offset
+ 4, sym_value
+ 4))
3398 /* As above, but don't actually build the stub. Just bump offset so
3399 we know stub section sizes and record the offset for each stub so
3400 a stub can target another stub (needed for BTI direct branch stub). */
3403 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
3405 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3406 struct elf_aarch64_link_hash_table
*htab
;
3409 /* Massage our args to the form they really have. */
3410 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
3411 htab
= (struct elf_aarch64_link_hash_table
*) in_arg
;
3413 switch (stub_entry
->stub_type
)
3415 case aarch64_stub_adrp_branch
:
3416 size
= sizeof (aarch64_adrp_branch_stub
);
3418 case aarch64_stub_long_branch
:
3419 size
= sizeof (aarch64_long_branch_stub
);
3421 case aarch64_stub_bti_direct_branch
:
3422 size
= sizeof (aarch64_bti_direct_branch_stub
);
3424 case aarch64_stub_erratum_835769_veneer
:
3425 size
= sizeof (aarch64_erratum_835769_stub
);
3427 case aarch64_stub_erratum_843419_veneer
:
3429 if (htab
->fix_erratum_843419
== ERRAT_ADR
)
3431 size
= sizeof (aarch64_erratum_843419_stub
);
3438 size
= (size
+ 7) & ~7;
3439 stub_entry
->stub_offset
= stub_entry
->stub_sec
->size
;
3440 stub_entry
->stub_sec
->size
+= size
;
3444 /* Output is BTI compatible. */
3447 elf_aarch64_bti_p (bfd
*output_bfd
)
3449 return elf_aarch64_tdata (output_bfd
)->gnu_property_aarch64_feature_1_and
3450 & GNU_PROPERTY_AARCH64_FEATURE_1_BTI
;
3453 /* External entry points for sizing and building linker stubs. */
3455 /* Set up various things so that we can make a list of input sections
3456 for each output section included in the link. Returns -1 on error,
3457 0 when no stubs will be needed, and 1 on success. */
3460 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
3461 struct bfd_link_info
*info
)
3464 unsigned int bfd_count
;
3465 unsigned int top_id
, top_index
;
3467 asection
**input_list
, **list
;
3469 struct elf_aarch64_link_hash_table
*htab
=
3470 elf_aarch64_hash_table (info
);
3472 if (!is_elf_hash_table (&htab
->root
.root
))
3475 /* Count the number of input BFDs and find the top input section id. */
3476 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
3477 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3480 for (section
= input_bfd
->sections
;
3481 section
!= NULL
; section
= section
->next
)
3483 if (top_id
< section
->id
)
3484 top_id
= section
->id
;
3487 htab
->bfd_count
= bfd_count
;
3489 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
3490 htab
->stub_group
= bfd_zmalloc (amt
);
3491 if (htab
->stub_group
== NULL
)
3494 /* We can't use output_bfd->section_count here to find the top output
3495 section index as some sections may have been removed, and
3496 _bfd_strip_section_from_output doesn't renumber the indices. */
3497 for (section
= output_bfd
->sections
, top_index
= 0;
3498 section
!= NULL
; section
= section
->next
)
3500 if (top_index
< section
->index
)
3501 top_index
= section
->index
;
3504 htab
->top_index
= top_index
;
3505 amt
= sizeof (asection
*) * (top_index
+ 1);
3506 input_list
= bfd_malloc (amt
);
3507 htab
->input_list
= input_list
;
3508 if (input_list
== NULL
)
3511 /* For sections we aren't interested in, mark their entries with a
3512 value we can check later. */
3513 list
= input_list
+ top_index
;
3515 *list
= bfd_abs_section_ptr
;
3516 while (list
-- != input_list
);
3518 for (section
= output_bfd
->sections
;
3519 section
!= NULL
; section
= section
->next
)
3521 if ((section
->flags
& SEC_CODE
) != 0)
3522 input_list
[section
->index
] = NULL
;
3528 /* Used by elfNN_aarch64_next_input_section and group_sections. */
3529 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
3531 /* The linker repeatedly calls this function for each input section,
3532 in the order that input sections are linked into output sections.
3533 Build lists of input sections to determine groupings between which
3534 we may insert linker stubs. */
3537 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
3539 struct elf_aarch64_link_hash_table
*htab
=
3540 elf_aarch64_hash_table (info
);
3542 if (isec
->output_section
->index
<= htab
->top_index
)
3544 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
3546 if (*list
!= bfd_abs_section_ptr
&& (isec
->flags
& SEC_CODE
) != 0)
3548 /* Steal the link_sec pointer for our list. */
3549 /* This happens to make the list in reverse order,
3550 which is what we want. */
3551 PREV_SEC (isec
) = *list
;
3557 /* See whether we can group stub sections together. Grouping stub
3558 sections may result in fewer stubs. More importantly, we need to
3559 put all .init* and .fini* stubs at the beginning of the .init or
3560 .fini output sections respectively, because glibc splits the
3561 _init and _fini functions into multiple parts. Putting a stub in
3562 the middle of a function is not a good idea. */
3565 group_sections (struct elf_aarch64_link_hash_table
*htab
,
3566 bfd_size_type stub_group_size
,
3567 bool stubs_always_after_branch
)
3569 asection
**list
= htab
->input_list
;
3573 asection
*tail
= *list
;
3576 if (tail
== bfd_abs_section_ptr
)
3579 /* Reverse the list: we must avoid placing stubs at the
3580 beginning of the section because the beginning of the text
3581 section may be required for an interrupt vector in bare metal
3583 #define NEXT_SEC PREV_SEC
3585 while (tail
!= NULL
)
3587 /* Pop from tail. */
3588 asection
*item
= tail
;
3589 tail
= PREV_SEC (item
);
3592 NEXT_SEC (item
) = head
;
3596 while (head
!= NULL
)
3600 bfd_vma stub_group_start
= head
->output_offset
;
3601 bfd_vma end_of_next
;
3604 while (NEXT_SEC (curr
) != NULL
)
3606 next
= NEXT_SEC (curr
);
3607 end_of_next
= next
->output_offset
+ next
->size
;
3608 if (end_of_next
- stub_group_start
>= stub_group_size
)
3609 /* End of NEXT is too far from start, so stop. */
3611 /* Add NEXT to the group. */
3615 /* OK, the size from the start to the start of CURR is less
3616 than stub_group_size and thus can be handled by one stub
3617 section. (Or the head section is itself larger than
3618 stub_group_size, in which case we may be toast.)
3619 We should really be keeping track of the total size of
3620 stubs added here, as stubs contribute to the final output
3624 next
= NEXT_SEC (head
);
3625 /* Set up this stub group. */
3626 htab
->stub_group
[head
->id
].link_sec
= curr
;
3628 while (head
!= curr
&& (head
= next
) != NULL
);
3630 /* But wait, there's more! Input sections up to stub_group_size
3631 bytes after the stub section can be handled by it too. */
3632 if (!stubs_always_after_branch
)
3634 stub_group_start
= curr
->output_offset
+ curr
->size
;
3636 while (next
!= NULL
)
3638 end_of_next
= next
->output_offset
+ next
->size
;
3639 if (end_of_next
- stub_group_start
>= stub_group_size
)
3640 /* End of NEXT is too far from stubs, so stop. */
3642 /* Add NEXT to the stub group. */
3644 next
= NEXT_SEC (head
);
3645 htab
->stub_group
[head
->id
].link_sec
= curr
;
3651 while (list
++ != htab
->input_list
+ htab
->top_index
);
3653 free (htab
->input_list
);
3659 #define AARCH64_HINT(insn) (((insn) & 0xfffff01f) == 0xd503201f)
3660 #define AARCH64_PACIASP 0xd503233f
3661 #define AARCH64_PACIBSP 0xd503237f
3662 #define AARCH64_BTI_C 0xd503245f
3663 #define AARCH64_BTI_J 0xd503249f
3664 #define AARCH64_BTI_JC 0xd50324df
3666 /* True if the inserted stub does not break BTI compatibility. */
3669 aarch64_bti_stub_p (struct bfd_link_info
*info
,
3670 struct elf_aarch64_stub_hash_entry
*stub_entry
)
3672 /* Stubs without indirect branch are BTI compatible. */
3673 if (stub_entry
->stub_type
!= aarch64_stub_adrp_branch
3674 && stub_entry
->stub_type
!= aarch64_stub_long_branch
)
3677 /* Return true if the target instruction is compatible with BR x16. */
3679 struct elf_aarch64_link_hash_table
*globals
= elf_aarch64_hash_table (info
);
3680 asection
*section
= stub_entry
->target_section
;
3682 file_ptr off
= stub_entry
->target_value
;
3683 bfd_size_type count
= sizeof (loc
);
3685 /* PLT code is not generated yet, so treat it specially.
3686 Note: Checking elf_aarch64_obj_tdata.plt_type & PLT_BTI is not
3687 enough because it only implies BTI in the PLT0 and tlsdesc PLT
3688 entries. Normal PLT entries don't have BTI in a shared library
3689 (because such PLT is normally not called indirectly and adding
3690 the BTI when a stub targets a PLT would change the PLT layout
3691 and it's too late for that here). */
3692 if (section
== globals
->root
.splt
)
3693 memcpy (loc
, globals
->plt_entry
, count
);
3694 else if (!bfd_get_section_contents (section
->owner
, section
, loc
, off
, count
))
3697 uint32_t insn
= bfd_getl32 (loc
);
3698 if (!AARCH64_HINT (insn
))
3700 return insn
== AARCH64_BTI_C
3701 || insn
== AARCH64_PACIASP
3702 || insn
== AARCH64_BTI_JC
3703 || insn
== AARCH64_BTI_J
3704 || insn
== AARCH64_PACIBSP
;
3707 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
3709 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
3710 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
3711 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
3712 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
3713 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
3714 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
3716 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
3717 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
3718 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
3719 #define AARCH64_ZR 0x1f
3721 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
3722 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
3724 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
3725 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
3726 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
3727 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
3728 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
3729 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
3730 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
3731 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
3732 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
3733 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
3734 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
3735 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
3736 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
3737 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
3738 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
3739 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
3740 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
3741 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
3743 /* Classify an INSN if it is indeed a load/store.
3745 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
3747 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
3750 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned. */
3753 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rt2
,
3754 bool *pair
, bool *load
)
3762 /* Bail out quickly if INSN doesn't fall into the load-store
3764 if (!AARCH64_LDST (insn
))
3769 if (AARCH64_LDST_EX (insn
))
3771 *rt
= AARCH64_RT (insn
);
3773 if (AARCH64_BIT (insn
, 21) == 1)
3776 *rt2
= AARCH64_RT2 (insn
);
3778 *load
= AARCH64_LD (insn
);
3781 else if (AARCH64_LDST_NAP (insn
)
3782 || AARCH64_LDSTP_PI (insn
)
3783 || AARCH64_LDSTP_O (insn
)
3784 || AARCH64_LDSTP_PRE (insn
))
3787 *rt
= AARCH64_RT (insn
);
3788 *rt2
= AARCH64_RT2 (insn
);
3789 *load
= AARCH64_LD (insn
);
3792 else if (AARCH64_LDST_PCREL (insn
)
3793 || AARCH64_LDST_UI (insn
)
3794 || AARCH64_LDST_PIIMM (insn
)
3795 || AARCH64_LDST_U (insn
)
3796 || AARCH64_LDST_PREIMM (insn
)
3797 || AARCH64_LDST_RO (insn
)
3798 || AARCH64_LDST_UIMM (insn
))
3800 *rt
= AARCH64_RT (insn
);
3802 if (AARCH64_LDST_PCREL (insn
))
3804 opc
= AARCH64_BITS (insn
, 22, 2);
3805 v
= AARCH64_BIT (insn
, 26);
3806 opc_v
= opc
| (v
<< 2);
3807 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
3808 || opc_v
== 5 || opc_v
== 7);
3811 else if (AARCH64_LDST_SIMD_M (insn
)
3812 || AARCH64_LDST_SIMD_M_PI (insn
))
3814 *rt
= AARCH64_RT (insn
);
3815 *load
= AARCH64_BIT (insn
, 22);
3816 opcode
= (insn
>> 12) & 0xf;
3843 else if (AARCH64_LDST_SIMD_S (insn
)
3844 || AARCH64_LDST_SIMD_S_PI (insn
))
3846 *rt
= AARCH64_RT (insn
);
3847 r
= (insn
>> 21) & 1;
3848 *load
= AARCH64_BIT (insn
, 22);
3849 opcode
= (insn
>> 13) & 0x7;
3861 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3869 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
3881 /* Return TRUE if INSN is multiply-accumulate. */
3884 aarch64_mlxl_p (uint32_t insn
)
3886 uint32_t op31
= AARCH64_OP31 (insn
);
3888 if (AARCH64_MAC (insn
)
3889 && (op31
== 0 || op31
== 1 || op31
== 5)
3890 /* Exclude MUL instructions which are encoded as a multiple accumulate
3892 && AARCH64_RA (insn
) != AARCH64_ZR
)
3898 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3899 it is possible for a 64-bit multiply-accumulate instruction to generate an
3900 incorrect result. The details are quite complex and hard to
3901 determine statically, since branches in the code may exist in some
3902 circumstances, but all cases end with a memory (load, store, or
3903 prefetch) instruction followed immediately by the multiply-accumulate
3904 operation. We employ a linker patching technique, by moving the potentially
3905 affected multiply-accumulate instruction into a patch region and replacing
3906 the original instruction with a branch to the patch. This function checks
3907 if INSN_1 is the memory operation followed by a multiply-accumulate
3908 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3909 if INSN_1 and INSN_2 are safe. */
3912 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
3922 if (aarch64_mlxl_p (insn_2
)
3923 && aarch64_mem_op_p (insn_1
, &rt
, &rt2
, &pair
, &load
))
3925 /* Any SIMD memory op is independent of the subsequent MLA
3926 by definition of the erratum. */
3927 if (AARCH64_BIT (insn_1
, 26))
3930 /* If not SIMD, check for integer memory ops and MLA relationship. */
3931 rn
= AARCH64_RN (insn_2
);
3932 ra
= AARCH64_RA (insn_2
);
3933 rm
= AARCH64_RM (insn_2
);
3935 /* If this is a load and there's a true(RAW) dependency, we are safe
3936 and this is not an erratum sequence. */
3938 (rt
== rn
|| rt
== rm
|| rt
== ra
3939 || (pair
&& (rt2
== rn
|| rt2
== rm
|| rt2
== ra
))))
3942 /* We conservatively put out stubs for all other cases (including
3950 /* Used to order a list of mapping symbols by address. */
3953 elf_aarch64_compare_mapping (const void *a
, const void *b
)
3955 const elf_aarch64_section_map
*amap
= (const elf_aarch64_section_map
*) a
;
3956 const elf_aarch64_section_map
*bmap
= (const elf_aarch64_section_map
*) b
;
3958 if (amap
->vma
> bmap
->vma
)
3960 else if (amap
->vma
< bmap
->vma
)
3962 else if (amap
->type
> bmap
->type
)
3963 /* Ensure results do not depend on the host qsort for objects with
3964 multiple mapping symbols at the same address by sorting on type
3967 else if (amap
->type
< bmap
->type
)
3975 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes
)
3977 char *stub_name
= (char *) bfd_malloc
3978 (strlen ("__erratum_835769_veneer_") + 16);
3979 if (stub_name
!= NULL
)
3980 sprintf (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
3984 /* Scan for Cortex-A53 erratum 835769 sequence.
3986 Return TRUE else FALSE on abnormal termination. */
3989 _bfd_aarch64_erratum_835769_scan (bfd
*input_bfd
,
3990 struct bfd_link_info
*info
,
3991 unsigned int *num_fixes_p
)
3994 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
3995 unsigned int num_fixes
= *num_fixes_p
;
4000 for (section
= input_bfd
->sections
;
4002 section
= section
->next
)
4004 bfd_byte
*contents
= NULL
;
4005 struct _aarch64_elf_section_data
*sec_data
;
4008 if (elf_section_type (section
) != SHT_PROGBITS
4009 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
4010 || (section
->flags
& SEC_EXCLUDE
) != 0
4011 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
4012 || (section
->output_section
== bfd_abs_section_ptr
))
4015 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
4016 contents
= elf_section_data (section
)->this_hdr
.contents
;
4017 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
4020 sec_data
= elf_aarch64_section_data (section
);
4022 if (sec_data
->mapcount
)
4023 qsort (sec_data
->map
, sec_data
->mapcount
,
4024 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
4026 for (span
= 0; span
< sec_data
->mapcount
; span
++)
4028 unsigned int span_start
= sec_data
->map
[span
].vma
;
4029 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
4030 ? sec_data
->map
[0].vma
+ section
->size
4031 : sec_data
->map
[span
+ 1].vma
);
4033 char span_type
= sec_data
->map
[span
].type
;
4035 if (span_type
== 'd')
4038 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
4040 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
4041 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
4043 if (aarch64_erratum_sequence (insn_1
, insn_2
))
4045 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4046 char *stub_name
= _bfd_aarch64_erratum_835769_stub_name (num_fixes
);
4050 stub_entry
= _bfd_aarch64_add_stub_entry_in_group (stub_name
,
4056 stub_entry
->stub_type
= aarch64_stub_erratum_835769_veneer
;
4057 stub_entry
->target_section
= section
;
4058 stub_entry
->target_value
= i
+ 4;
4059 stub_entry
->veneered_insn
= insn_2
;
4060 stub_entry
->output_name
= stub_name
;
4065 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
4069 *num_fixes_p
= num_fixes
;
4075 /* Test if instruction INSN is ADRP. */
4078 _bfd_aarch64_adrp_p (uint32_t insn
)
4080 return ((insn
& AARCH64_ADRP_OP_MASK
) == AARCH64_ADRP_OP
);
4084 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
4087 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1
, uint32_t insn_2
,
4095 return (aarch64_mem_op_p (insn_2
, &rt
, &rt2
, &pair
, &load
)
4098 && AARCH64_LDST_UIMM (insn_3
)
4099 && AARCH64_RN (insn_3
) == AARCH64_RD (insn_1
));
4103 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
4105 Return TRUE if section CONTENTS at offset I contains one of the
4106 erratum 843419 sequences, otherwise return FALSE. If a sequence is
4107 seen set P_VENEER_I to the offset of the final LOAD/STORE
4108 instruction in the sequence.
4112 _bfd_aarch64_erratum_843419_p (bfd_byte
*contents
, bfd_vma vma
,
4113 bfd_vma i
, bfd_vma span_end
,
4114 bfd_vma
*p_veneer_i
)
4116 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
4118 if (!_bfd_aarch64_adrp_p (insn_1
))
4121 if (span_end
< i
+ 12)
4124 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
4125 uint32_t insn_3
= bfd_getl32 (contents
+ i
+ 8);
4127 if ((vma
& 0xfff) != 0xff8 && (vma
& 0xfff) != 0xffc)
4130 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_3
))
4132 *p_veneer_i
= i
+ 8;
4136 if (span_end
< i
+ 16)
4139 uint32_t insn_4
= bfd_getl32 (contents
+ i
+ 12);
4141 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_4
))
4143 *p_veneer_i
= i
+ 12;
4151 /* Resize all stub sections. */
4154 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table
*htab
)
4158 /* OK, we've added some stubs. Find out the new size of the
4160 for (section
= htab
->stub_bfd
->sections
;
4161 section
!= NULL
; section
= section
->next
)
4163 /* Ignore non-stub sections. */
4164 if (!strstr (section
->name
, STUB_SUFFIX
))
4167 /* Add space for a branch. Add 8 bytes to keep section 8 byte aligned,
4168 as long branch stubs contain a 64-bit address. */
4172 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
4174 for (section
= htab
->stub_bfd
->sections
;
4175 section
!= NULL
; section
= section
->next
)
4177 if (!strstr (section
->name
, STUB_SUFFIX
))
4180 /* Empty stub section. */
4181 if (section
->size
== 8)
4184 /* Ensure all stub sections have a size which is a multiple of
4185 4096. This is important in order to ensure that the insertion
4186 of stub sections does not in itself move existing code around
4187 in such a way that new errata sequences are created. We only do this
4188 when the ADRP workaround is enabled. If only the ADR workaround is
4189 enabled then the stubs workaround won't ever be used. */
4190 if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
4192 section
->size
= BFD_ALIGN (section
->size
, 0x1000);
4196 /* Construct an erratum 843419 workaround stub name. */
4199 _bfd_aarch64_erratum_843419_stub_name (asection
*input_section
,
4202 const bfd_size_type len
= 8 + 4 + 1 + 8 + 1 + 16 + 1;
4203 char *stub_name
= bfd_malloc (len
);
4205 if (stub_name
!= NULL
)
4206 snprintf (stub_name
, len
, "e843419@%04x_%08x_%" PRIx64
,
4207 input_section
->owner
->id
,
4213 /* Build a stub_entry structure describing an 843419 fixup.
4215 The stub_entry constructed is populated with the bit pattern INSN
4216 of the instruction located at OFFSET within input SECTION.
4218 Returns TRUE on success. */
4221 _bfd_aarch64_erratum_843419_fixup (uint32_t insn
,
4222 bfd_vma adrp_offset
,
4223 bfd_vma ldst_offset
,
4225 struct bfd_link_info
*info
)
4227 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4229 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4231 stub_name
= _bfd_aarch64_erratum_843419_stub_name (section
, ldst_offset
);
4232 if (stub_name
== NULL
)
4234 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
4242 /* We always place an 843419 workaround veneer in the stub section
4243 attached to the input section in which an erratum sequence has
4244 been found. This ensures that later in the link process (in
4245 elfNN_aarch64_write_section) when we copy the veneered
4246 instruction from the input section into the stub section the
4247 copied instruction will have had any relocations applied to it.
4248 If we placed workaround veneers in any other stub section then we
4249 could not assume that all relocations have been processed on the
4250 corresponding input section at the point we output the stub
4253 stub_entry
= _bfd_aarch64_add_stub_entry_after (stub_name
, section
, htab
);
4254 if (stub_entry
== NULL
)
4260 stub_entry
->adrp_offset
= adrp_offset
;
4261 stub_entry
->target_value
= ldst_offset
;
4262 stub_entry
->target_section
= section
;
4263 stub_entry
->stub_type
= aarch64_stub_erratum_843419_veneer
;
4264 stub_entry
->veneered_insn
= insn
;
4265 stub_entry
->output_name
= stub_name
;
4271 /* Scan an input section looking for the signature of erratum 843419.
4273 Scans input SECTION in INPUT_BFD looking for erratum 843419
4274 signatures, for each signature found a stub_entry is created
4275 describing the location of the erratum for subsequent fixup.
4277 Return TRUE on successful scan, FALSE on failure to scan.
4281 _bfd_aarch64_erratum_843419_scan (bfd
*input_bfd
, asection
*section
,
4282 struct bfd_link_info
*info
)
4284 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4289 if (elf_section_type (section
) != SHT_PROGBITS
4290 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
4291 || (section
->flags
& SEC_EXCLUDE
) != 0
4292 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
4293 || (section
->output_section
== bfd_abs_section_ptr
))
4298 bfd_byte
*contents
= NULL
;
4299 struct _aarch64_elf_section_data
*sec_data
;
4302 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
4303 contents
= elf_section_data (section
)->this_hdr
.contents
;
4304 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
4307 sec_data
= elf_aarch64_section_data (section
);
4309 if (sec_data
->mapcount
)
4310 qsort (sec_data
->map
, sec_data
->mapcount
,
4311 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
4313 for (span
= 0; span
< sec_data
->mapcount
; span
++)
4315 unsigned int span_start
= sec_data
->map
[span
].vma
;
4316 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
4317 ? sec_data
->map
[0].vma
+ section
->size
4318 : sec_data
->map
[span
+ 1].vma
);
4320 char span_type
= sec_data
->map
[span
].type
;
4322 if (span_type
== 'd')
4325 for (i
= span_start
; i
+ 8 < span_end
; i
+= 4)
4327 bfd_vma vma
= (section
->output_section
->vma
4328 + section
->output_offset
4332 if (_bfd_aarch64_erratum_843419_p
4333 (contents
, vma
, i
, span_end
, &veneer_i
))
4335 uint32_t insn
= bfd_getl32 (contents
+ veneer_i
);
4337 if (!_bfd_aarch64_erratum_843419_fixup (insn
, i
, veneer_i
,
4344 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
4353 /* Add stub entries for calls.
4355 The basic idea here is to examine all the relocations looking for
4356 PC-relative calls to a target that is unreachable with a "bl"
4360 _bfd_aarch64_add_call_stub_entries (bool *stub_changed
, bfd
*output_bfd
,
4361 struct bfd_link_info
*info
)
4363 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4364 bool need_bti
= elf_aarch64_bti_p (output_bfd
);
4367 for (input_bfd
= info
->input_bfds
; input_bfd
!= NULL
;
4368 input_bfd
= input_bfd
->link
.next
)
4370 Elf_Internal_Shdr
*symtab_hdr
;
4372 Elf_Internal_Sym
*local_syms
= NULL
;
4374 if (!is_aarch64_elf (input_bfd
)
4375 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
4378 /* We'll need the symbol table in a second. */
4379 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4380 if (symtab_hdr
->sh_info
== 0)
4383 /* Walk over each section attached to the input bfd. */
4384 for (section
= input_bfd
->sections
;
4385 section
!= NULL
; section
= section
->next
)
4387 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
4389 /* If there aren't any relocs, then there's nothing more to do. */
4390 if ((section
->flags
& SEC_RELOC
) == 0
4391 || section
->reloc_count
== 0
4392 || (section
->flags
& SEC_CODE
) == 0)
4395 /* If this section is a link-once section that will be
4396 discarded, then don't create any stubs. */
4397 if (section
->output_section
== NULL
4398 || section
->output_section
->owner
!= output_bfd
)
4401 /* Get the relocs. */
4403 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
4404 NULL
, info
->keep_memory
);
4405 if (internal_relocs
== NULL
)
4406 goto error_ret_free_local
;
4408 /* Now examine each relocation. */
4409 irela
= internal_relocs
;
4410 irelaend
= irela
+ section
->reloc_count
;
4411 for (; irela
< irelaend
; irela
++)
4413 unsigned int r_type
, r_indx
;
4414 enum elf_aarch64_stub_type stub_type
;
4415 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4416 struct elf_aarch64_stub_hash_entry
*stub_entry_bti
;
4419 bfd_vma destination
;
4420 struct elf_aarch64_link_hash_entry
*hash
;
4421 const char *sym_name
;
4423 char *stub_name_bti
;
4424 const asection
*id_sec
;
4425 const asection
*id_sec_bti
;
4426 unsigned char st_type
;
4429 r_type
= ELFNN_R_TYPE (irela
->r_info
);
4430 r_indx
= ELFNN_R_SYM (irela
->r_info
);
4432 if (r_type
>= (unsigned int) R_AARCH64_end
)
4434 bfd_set_error (bfd_error_bad_value
);
4435 error_ret_free_internal
:
4436 if (elf_section_data (section
)->relocs
== NULL
)
4437 free (internal_relocs
);
4438 goto error_ret_free_local
;
4441 /* Only look for stubs on unconditional branch and
4442 branch and link instructions. */
4443 if (r_type
!= (unsigned int) AARCH64_R (CALL26
)
4444 && r_type
!= (unsigned int) AARCH64_R (JUMP26
))
4447 /* Now determine the call target, its name, value,
4454 if (r_indx
< symtab_hdr
->sh_info
)
4456 /* It's a local symbol. */
4457 Elf_Internal_Sym
*sym
;
4458 Elf_Internal_Shdr
*hdr
;
4460 if (local_syms
== NULL
)
4463 = (Elf_Internal_Sym
*) symtab_hdr
->contents
;
4464 if (local_syms
== NULL
)
4466 = bfd_elf_get_elf_syms (input_bfd
, symtab_hdr
,
4467 symtab_hdr
->sh_info
, 0,
4469 if (local_syms
== NULL
)
4470 goto error_ret_free_internal
;
4473 sym
= local_syms
+ r_indx
;
4474 hdr
= elf_elfsections (input_bfd
)[sym
->st_shndx
];
4475 sym_sec
= hdr
->bfd_section
;
4477 /* This is an undefined symbol. It can never
4481 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
4482 sym_value
= sym
->st_value
;
4483 destination
= (sym_value
+ irela
->r_addend
4484 + sym_sec
->output_offset
4485 + sym_sec
->output_section
->vma
);
4486 st_type
= ELF_ST_TYPE (sym
->st_info
);
4488 = bfd_elf_string_from_elf_section (input_bfd
,
4489 symtab_hdr
->sh_link
,
4496 e_indx
= r_indx
- symtab_hdr
->sh_info
;
4497 hash
= ((struct elf_aarch64_link_hash_entry
*)
4498 elf_sym_hashes (input_bfd
)[e_indx
]);
4500 while (hash
->root
.root
.type
== bfd_link_hash_indirect
4501 || hash
->root
.root
.type
== bfd_link_hash_warning
)
4502 hash
= ((struct elf_aarch64_link_hash_entry
*)
4503 hash
->root
.root
.u
.i
.link
);
4505 if (hash
->root
.root
.type
== bfd_link_hash_defined
4506 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
4508 struct elf_aarch64_link_hash_table
*globals
=
4509 elf_aarch64_hash_table (info
);
4510 sym_sec
= hash
->root
.root
.u
.def
.section
;
4511 sym_value
= hash
->root
.root
.u
.def
.value
;
4512 /* For a destination in a shared library,
4513 use the PLT stub as target address to
4514 decide whether a branch stub is
4516 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
4517 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
4519 sym_sec
= globals
->root
.splt
;
4520 sym_value
= hash
->root
.plt
.offset
;
4521 if (sym_sec
->output_section
!= NULL
)
4522 destination
= (sym_value
4523 + sym_sec
->output_offset
4524 + sym_sec
->output_section
->vma
);
4526 else if (sym_sec
->output_section
!= NULL
)
4527 destination
= (sym_value
+ irela
->r_addend
4528 + sym_sec
->output_offset
4529 + sym_sec
->output_section
->vma
);
4531 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
4532 || (hash
->root
.root
.type
4533 == bfd_link_hash_undefweak
))
4535 /* For a shared library, use the PLT stub as
4536 target address to decide whether a long
4537 branch stub is needed.
4538 For absolute code, they cannot be handled. */
4539 struct elf_aarch64_link_hash_table
*globals
=
4540 elf_aarch64_hash_table (info
);
4542 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
4543 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
4545 sym_sec
= globals
->root
.splt
;
4546 sym_value
= hash
->root
.plt
.offset
;
4547 if (sym_sec
->output_section
!= NULL
)
4548 destination
= (sym_value
4549 + sym_sec
->output_offset
4550 + sym_sec
->output_section
->vma
);
4557 bfd_set_error (bfd_error_bad_value
);
4558 goto error_ret_free_internal
;
4560 st_type
= ELF_ST_TYPE (hash
->root
.type
);
4561 sym_name
= hash
->root
.root
.root
.string
;
4564 /* Determine what (if any) linker stub is needed. */
4565 stub_type
= aarch64_type_of_stub (section
, irela
, sym_sec
,
4566 st_type
, destination
);
4567 if (stub_type
== aarch64_stub_none
)
4570 /* Support for grouping stub sections. */
4571 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
4573 /* Get the name of this stub. */
4574 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
4577 goto error_ret_free_internal
;
4580 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
4581 stub_name
, false, false);
4582 if (stub_entry
!= NULL
)
4584 /* The proper stub has already been created. */
4587 /* Always update this stub's target since it may have
4588 changed after layout. */
4589 stub_entry
->target_value
= sym_value
+ irela
->r_addend
;
4591 if (stub_entry
->double_stub
)
4593 /* Update the target of both stubs. */
4595 id_sec_bti
= htab
->stub_group
[sym_sec
->id
].link_sec
;
4597 elfNN_aarch64_stub_name (id_sec_bti
, sym_sec
, hash
,
4600 goto error_ret_free_internal
;
4602 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
4603 stub_name_bti
, false, false);
4604 BFD_ASSERT (stub_entry_bti
!= NULL
);
4605 free (stub_name_bti
);
4606 stub_entry_bti
->target_value
= stub_entry
->target_value
;
4607 stub_entry
->target_value
= stub_entry_bti
->stub_offset
;
4612 stub_entry
= _bfd_aarch64_add_stub_entry_in_group
4613 (stub_name
, section
, htab
);
4614 if (stub_entry
== NULL
)
4617 goto error_ret_free_internal
;
4620 stub_entry
->target_value
= sym_value
+ irela
->r_addend
;
4621 stub_entry
->target_section
= sym_sec
;
4622 stub_entry
->stub_type
= stub_type
;
4623 stub_entry
->h
= hash
;
4624 stub_entry
->st_type
= st_type
;
4626 if (sym_name
== NULL
)
4627 sym_name
= "unnamed";
4628 len
= sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
);
4629 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
4630 if (stub_entry
->output_name
== NULL
)
4633 goto error_ret_free_internal
;
4636 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
4639 /* A stub with indirect jump may break BTI compatibility, so
4640 insert another stub with direct jump near the target then. */
4641 if (need_bti
&& !aarch64_bti_stub_p (info
, stub_entry
))
4643 id_sec_bti
= htab
->stub_group
[sym_sec
->id
].link_sec
;
4645 /* If the stub with indirect jump and the BTI stub are in
4646 the same stub group: change the indirect jump stub into
4647 a BTI stub since a direct branch can reach the target.
4648 The BTI landing pad is still needed in case another
4649 stub indirectly jumps to it. */
4650 if (id_sec_bti
== id_sec
)
4652 stub_entry
->stub_type
= aarch64_stub_bti_direct_branch
;
4653 goto skip_double_stub
;
4656 stub_entry
->double_stub
= true;
4657 htab
->has_double_stub
= true;
4660 elfNN_aarch64_stub_name (id_sec_bti
, sym_sec
, hash
, irela
);
4664 goto error_ret_free_internal
;
4668 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
4669 stub_name_bti
, false, false);
4670 if (stub_entry_bti
!= NULL
)
4671 BFD_ASSERT (stub_entry_bti
->stub_type
4672 == aarch64_stub_bti_direct_branch
);
4676 _bfd_aarch64_add_stub_entry_in_group (stub_name_bti
,
4678 if (stub_entry_bti
== NULL
)
4681 free (stub_name_bti
);
4682 goto error_ret_free_internal
;
4685 stub_entry_bti
->target_value
=
4686 sym_value
+ irela
->r_addend
;
4687 stub_entry_bti
->target_section
= sym_sec
;
4688 stub_entry_bti
->stub_type
=
4689 aarch64_stub_bti_direct_branch
;
4690 stub_entry_bti
->h
= hash
;
4691 stub_entry_bti
->st_type
= st_type
;
4693 len
= sizeof (BTI_STUB_ENTRY_NAME
) + strlen (sym_name
);
4694 stub_entry_bti
->output_name
= bfd_alloc (htab
->stub_bfd
,
4696 if (stub_entry_bti
->output_name
== NULL
)
4699 free (stub_name_bti
);
4700 goto error_ret_free_internal
;
4702 snprintf (stub_entry_bti
->output_name
, len
,
4703 BTI_STUB_ENTRY_NAME
, sym_name
);
4706 /* Update the indirect call stub to target the BTI stub. */
4707 stub_entry
->target_value
= 0;
4708 stub_entry
->target_section
= stub_entry_bti
->stub_sec
;
4709 stub_entry
->stub_type
= stub_type
;
4710 stub_entry
->h
= NULL
;
4711 stub_entry
->st_type
= STT_FUNC
;
4714 *stub_changed
= true;
4717 /* We're done with the internal relocs, free them. */
4718 if (elf_section_data (section
)->relocs
== NULL
)
4719 free (internal_relocs
);
4723 error_ret_free_local
:
4728 /* Determine and set the size of the stub section for a final link. */
4731 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
4733 struct bfd_link_info
*info
,
4734 bfd_signed_vma group_size
,
4735 asection
* (*add_stub_section
) (const char *,
4737 void (*layout_sections_again
) (void))
4739 bfd_size_type stub_group_size
;
4740 bool stubs_always_before_branch
;
4741 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4742 unsigned int num_erratum_835769_fixes
= 0;
4744 /* Propagate mach to stub bfd, because it may not have been
4745 finalized when we created stub_bfd. */
4746 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
4747 bfd_get_mach (output_bfd
));
4749 /* Stash our params away. */
4750 htab
->stub_bfd
= stub_bfd
;
4751 htab
->add_stub_section
= add_stub_section
;
4752 htab
->layout_sections_again
= layout_sections_again
;
4753 stubs_always_before_branch
= group_size
< 0;
4755 stub_group_size
= -group_size
;
4757 stub_group_size
= group_size
;
4759 if (stub_group_size
== 1)
4761 /* Default values. */
4762 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
4763 stub_group_size
= 127 * 1024 * 1024;
4766 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
4768 (*htab
->layout_sections_again
) ();
4770 if (htab
->fix_erratum_835769
)
4774 for (input_bfd
= info
->input_bfds
;
4775 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
4777 if (!is_aarch64_elf (input_bfd
)
4778 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
4781 if (!_bfd_aarch64_erratum_835769_scan (input_bfd
, info
,
4782 &num_erratum_835769_fixes
))
4786 _bfd_aarch64_resize_stubs (htab
);
4787 (*htab
->layout_sections_again
) ();
4790 if (htab
->fix_erratum_843419
!= ERRAT_NONE
)
4794 for (input_bfd
= info
->input_bfds
;
4796 input_bfd
= input_bfd
->link
.next
)
4800 if (!is_aarch64_elf (input_bfd
)
4801 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
4804 for (section
= input_bfd
->sections
;
4806 section
= section
->next
)
4807 if (!_bfd_aarch64_erratum_843419_scan (input_bfd
, section
, info
))
4811 _bfd_aarch64_resize_stubs (htab
);
4812 (*htab
->layout_sections_again
) ();
4817 bool stub_changed
= false;
4819 if (!_bfd_aarch64_add_call_stub_entries (&stub_changed
, output_bfd
, info
))
4825 _bfd_aarch64_resize_stubs (htab
);
4826 (*htab
->layout_sections_again
) ();
4830 /* Build all the stubs associated with the current output file. The
4831 stubs are kept in a hash table attached to the main linker hash
4832 table. We also set up the .plt entries for statically linked PIC
4833 functions here. This function is called via aarch64_elf_finish in the
4837 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
4840 struct bfd_hash_table
*table
;
4841 struct elf_aarch64_link_hash_table
*htab
;
4843 htab
= elf_aarch64_hash_table (info
);
4845 for (stub_sec
= htab
->stub_bfd
->sections
;
4846 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
4850 /* Ignore non-stub sections. */
4851 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
4854 /* Allocate memory to hold the linker stubs. */
4855 size
= stub_sec
->size
;
4856 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
4857 if (stub_sec
->contents
== NULL
&& size
!= 0)
4859 stub_sec
->alloced
= 1;
4862 /* Add a branch around the stub section, and a nop, to keep it 8 byte
4863 aligned, as long branch stubs contain a 64-bit address. */
4864 bfd_putl32 (0x14000000 | (size
>> 2), stub_sec
->contents
);
4865 bfd_putl32 (INSN_NOP
, stub_sec
->contents
+ 4);
4866 stub_sec
->size
+= 8;
4869 /* Build the stubs as directed by the stub hash table. */
4870 table
= &htab
->stub_hash_table
;
4871 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
4877 /* Add an entry to the code/data map for section SEC. */
4880 elfNN_aarch64_section_map_add (asection
*sec
, char type
, bfd_vma vma
)
4882 struct _aarch64_elf_section_data
*sec_data
=
4883 elf_aarch64_section_data (sec
);
4884 unsigned int newidx
;
4886 if (sec_data
->map
== NULL
)
4888 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
4889 sec_data
->mapcount
= 0;
4890 sec_data
->mapsize
= 1;
4893 newidx
= sec_data
->mapcount
++;
4895 if (sec_data
->mapcount
> sec_data
->mapsize
)
4897 sec_data
->mapsize
*= 2;
4898 sec_data
->map
= bfd_realloc_or_free
4899 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
4904 sec_data
->map
[newidx
].vma
= vma
;
4905 sec_data
->map
[newidx
].type
= type
;
4910 /* Initialise maps of insn/data for input BFDs. */
4912 bfd_elfNN_aarch64_init_maps (bfd
*abfd
)
4914 Elf_Internal_Sym
*isymbuf
;
4915 Elf_Internal_Shdr
*hdr
;
4916 unsigned int i
, localsyms
;
4918 /* Make sure that we are dealing with an AArch64 elf binary. */
4919 if (!is_aarch64_elf (abfd
))
4922 if ((abfd
->flags
& DYNAMIC
) != 0)
4925 hdr
= &elf_symtab_hdr (abfd
);
4926 localsyms
= hdr
->sh_info
;
4928 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
4929 should contain the number of local symbols, which should come before any
4930 global symbols. Mapping symbols are always local. */
4931 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
4933 /* No internal symbols read? Skip this BFD. */
4934 if (isymbuf
== NULL
)
4937 for (i
= 0; i
< localsyms
; i
++)
4939 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
4940 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
4943 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
4945 name
= bfd_elf_string_from_elf_section (abfd
,
4949 if (bfd_is_aarch64_special_symbol_name
4950 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
4951 elfNN_aarch64_section_map_add (sec
, name
[1], isym
->st_value
);
4957 setup_plt_values (struct bfd_link_info
*link_info
,
4958 aarch64_plt_type plt_type
)
4960 struct elf_aarch64_link_hash_table
*globals
;
4961 globals
= elf_aarch64_hash_table (link_info
);
4963 if (plt_type
== PLT_BTI_PAC
)
4965 globals
->plt0_entry
= elfNN_aarch64_small_plt0_bti_entry
;
4967 /* Only in ET_EXEC we need PLTn with BTI. */
4968 if (bfd_link_executable (link_info
))
4970 globals
->plt_entry_size
= PLT_BTI_PAC_SMALL_ENTRY_SIZE
;
4971 globals
->plt_entry
= elfNN_aarch64_small_plt_bti_pac_entry
;
4972 globals
->plt_entry_delta
= 4;
4976 globals
->plt_entry_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
4977 globals
->plt_entry
= elfNN_aarch64_small_plt_pac_entry
;
4978 globals
->plt_entry_delta
= 0;
4981 else if (plt_type
== PLT_BTI
)
4983 globals
->plt0_entry
= elfNN_aarch64_small_plt0_bti_entry
;
4985 /* Only in ET_EXEC we need PLTn with BTI. */
4986 if (bfd_link_executable (link_info
))
4988 globals
->plt_entry_size
= PLT_BTI_SMALL_ENTRY_SIZE
;
4989 globals
->plt_entry
= elfNN_aarch64_small_plt_bti_entry
;
4990 globals
->plt_entry_delta
= 4;
4993 else if (plt_type
== PLT_PAC
)
4995 globals
->plt_entry_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
4996 globals
->plt_entry
= elfNN_aarch64_small_plt_pac_entry
;
5000 /* Set option values needed during linking. */
5002 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
5003 struct bfd_link_info
*link_info
,
5005 int no_wchar_warn
, int pic_veneer
,
5006 int fix_erratum_835769
,
5007 erratum_84319_opts fix_erratum_843419
,
5008 int no_apply_dynamic_relocs
,
5009 const aarch64_protection_opts
*sw_protections
)
5011 struct elf_aarch64_link_hash_table
*globals
;
5013 globals
= elf_aarch64_hash_table (link_info
);
5014 globals
->pic_veneer
= pic_veneer
;
5015 globals
->fix_erratum_835769
= fix_erratum_835769
;
5016 /* If the default options are used, then ERRAT_ADR will be set by default
5017 which will enable the ADRP->ADR workaround for the erratum 843419
5019 globals
->fix_erratum_843419
= fix_erratum_843419
;
5020 globals
->no_apply_dynamic_relocs
= no_apply_dynamic_relocs
;
5022 BFD_ASSERT (is_aarch64_elf (output_bfd
));
5023 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
5024 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
5026 /* Note: gnu_property_aarch64_feature_1_and was initialized to 0 by
5028 if (sw_protections
->plt_type
& PLT_BTI
)
5029 elf_aarch64_tdata (output_bfd
)->gnu_property_aarch64_feature_1_and
5030 |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI
;
5032 switch (sw_protections
->gcs_type
)
5035 elf_aarch64_tdata (output_bfd
)->gnu_property_aarch64_feature_1_and
5036 |= GNU_PROPERTY_AARCH64_FEATURE_1_GCS
;
5039 elf_aarch64_tdata (output_bfd
)->gnu_property_aarch64_feature_1_and
5040 &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS
;
5043 /* GCS feature on the output bfd will be deduced from input objects. */
5047 elf_aarch64_tdata (output_bfd
)->sw_protections
= *sw_protections
;
5048 /* Inherit the value from '-z gcs-report' if the option '-z gcs-report-dynamic'
5049 was not set on the command line. However, the inheritance mechanism is
5050 capped to avoid inheriting the error level from -g gcs-report as the user
5051 might want to continue to build a module without rebuilding all the shared
5052 libraries. If a user also wants to error GCS issues in the shared
5053 libraries, '-z gcs-report-dynamic=error' will have to be specified
5055 if (sw_protections
->gcs_report_dynamic
== MARKING_UNSET
)
5056 elf_aarch64_tdata (output_bfd
)->sw_protections
.gcs_report_dynamic
5057 = (sw_protections
->gcs_report
== MARKING_ERROR
)
5059 : sw_protections
->gcs_report
;
5061 elf_aarch64_tdata (output_bfd
)->n_bti_issues
= 0;
5062 elf_aarch64_tdata (output_bfd
)->n_gcs_issues
= 0;
5063 elf_aarch64_tdata (output_bfd
)->n_gcs_dynamic_issues
= 0;
5065 setup_plt_values (link_info
, sw_protections
->plt_type
);
5069 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
5070 struct elf_aarch64_link_hash_table
5071 *globals
, struct bfd_link_info
*info
,
5072 bfd_vma value
, bfd
*output_bfd
,
5073 bool *unresolved_reloc_p
)
5075 bfd_vma off
= (bfd_vma
) - 1;
5076 asection
*basegot
= globals
->root
.sgot
;
5077 bool dyn
= globals
->root
.dynamic_sections_created
;
5081 BFD_ASSERT (basegot
!= NULL
);
5082 off
= h
->got
.offset
;
5083 BFD_ASSERT (off
!= (bfd_vma
) - 1);
5084 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
5085 || (bfd_link_pic (info
)
5086 && SYMBOL_REFERENCES_LOCAL (info
, h
))
5087 || (ELF_ST_VISIBILITY (h
->other
)
5088 && h
->root
.type
== bfd_link_hash_undefweak
))
5090 /* This is actually a static link, or it is a -Bsymbolic link
5091 and the symbol is defined locally. We must initialize this
5092 entry in the global offset table. Since the offset must
5093 always be a multiple of 8 (4 in the case of ILP32), we use
5094 the least significant bit to record whether we have
5095 initialized it already.
5096 When doing a dynamic link, we create a .rel(a).got relocation
5097 entry to initialize the value. This is done in the
5098 finish_dynamic_symbol routine. */
5103 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
5108 *unresolved_reloc_p
= false;
5110 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
5116 /* Change R_TYPE to a more efficient access model where possible,
5117 return the new reloc type. */
5119 static bfd_reloc_code_real_type
5120 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
5121 struct elf_link_hash_entry
*h
,
5122 struct bfd_link_info
*info
)
5124 bool local_exec
= bfd_link_executable (info
)
5125 && SYMBOL_REFERENCES_LOCAL (info
, h
);
5129 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5130 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5132 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5133 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
5135 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5137 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5140 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5142 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5143 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
5145 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5147 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5148 : BFD_RELOC_AARCH64_NONE
);
5150 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
5152 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5153 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
);
5155 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
5157 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5158 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
);
5160 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5161 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5163 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5164 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
5166 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5167 return local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
5169 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5170 return local_exec
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
5172 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5175 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5177 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
5178 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
5180 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5181 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
5182 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5183 /* Instructions with these relocations will become NOPs. */
5184 return BFD_RELOC_AARCH64_NONE
;
5186 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5187 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5188 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5189 return local_exec
? BFD_RELOC_AARCH64_NONE
: r_type
;
5192 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
5194 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5195 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
;
5197 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
5199 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5200 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
;
5211 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
5215 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5216 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5217 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5218 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5219 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
5220 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5221 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5222 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
5223 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
5226 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5227 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5228 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5229 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
5230 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
5231 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5232 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5233 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5236 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5237 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
5238 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5239 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5240 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5241 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5242 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
5243 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5244 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5245 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
5246 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
5247 return GOT_TLSDESC_GD
;
5249 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5250 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5251 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5252 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5253 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
5254 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
5264 aarch64_can_relax_tls (bfd
*input_bfd
,
5265 struct bfd_link_info
*info
,
5266 bfd_reloc_code_real_type r_type
,
5267 struct elf_link_hash_entry
*h
,
5268 unsigned long r_symndx
)
5270 unsigned int symbol_got_type
;
5271 unsigned int reloc_got_type
;
5273 if (! IS_AARCH64_TLS_RELAX_RELOC (r_type
))
5276 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
5277 reloc_got_type
= aarch64_reloc_got_type (r_type
);
5279 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
5282 if (!bfd_link_executable (info
))
5285 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
5291 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
5294 static bfd_reloc_code_real_type
5295 aarch64_tls_transition (bfd
*input_bfd
,
5296 struct bfd_link_info
*info
,
5297 unsigned int r_type
,
5298 struct elf_link_hash_entry
*h
,
5299 unsigned long r_symndx
)
5301 bfd_reloc_code_real_type bfd_r_type
5302 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
5304 if (! aarch64_can_relax_tls (input_bfd
, info
, bfd_r_type
, h
, r_symndx
))
5307 return aarch64_tls_transition_without_check (bfd_r_type
, h
, info
);
5310 /* Return the base VMA address which should be subtracted from real addresses
5311 when resolving R_AARCH64_TLS_DTPREL relocation. */
5314 dtpoff_base (struct bfd_link_info
*info
)
5316 /* If tls_sec is NULL, we should have signalled an error already. */
5317 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
5318 return elf_hash_table (info
)->tls_sec
->vma
;
5321 /* Return the base VMA address which should be subtracted from real addresses
5322 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
5325 tpoff_base (struct bfd_link_info
*info
)
5327 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
5329 /* If tls_sec is NULL, we should have signalled an error already. */
5330 BFD_ASSERT (htab
->tls_sec
!= NULL
);
5332 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE
,
5333 htab
->tls_sec
->alignment_power
);
5334 return htab
->tls_sec
->vma
- base
;
5338 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5339 unsigned long r_symndx
)
5341 /* Calculate the address of the GOT entry for symbol
5342 referred to in h. */
5344 return &h
->got
.offset
;
5348 struct elf_aarch64_local_symbol
*l
;
5350 l
= elf_aarch64_locals (input_bfd
);
5351 return &l
[r_symndx
].got_offset
;
5356 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5357 unsigned long r_symndx
)
5360 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
5365 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5366 unsigned long r_symndx
)
5369 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
5374 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5375 unsigned long r_symndx
)
5378 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
5384 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5385 unsigned long r_symndx
)
5387 /* Calculate the address of the GOT entry for symbol
5388 referred to in h. */
5391 struct elf_aarch64_link_hash_entry
*eh
;
5392 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
5393 return &eh
->tlsdesc_got_jump_table_offset
;
5398 struct elf_aarch64_local_symbol
*l
;
5400 l
= elf_aarch64_locals (input_bfd
);
5401 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
5406 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5407 unsigned long r_symndx
)
5410 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
5415 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
5416 struct elf_link_hash_entry
*h
,
5417 unsigned long r_symndx
)
5420 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
5425 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
5426 unsigned long r_symndx
)
5429 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
5434 /* Data for make_branch_to_erratum_835769_stub(). */
5436 struct erratum_835769_branch_to_stub_data
5438 struct bfd_link_info
*info
;
5439 asection
*output_section
;
5443 /* Helper to insert branches to erratum 835769 stubs in the right
5444 places for a particular section. */
5447 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
5450 struct elf_aarch64_stub_hash_entry
*stub_entry
;
5451 struct erratum_835769_branch_to_stub_data
*data
;
5453 unsigned long branch_insn
= 0;
5454 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
5455 bfd_signed_vma branch_offset
;
5456 unsigned int target
;
5459 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
5460 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
5462 if (stub_entry
->target_section
!= data
->output_section
5463 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
5466 contents
= data
->contents
;
5467 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
5468 + stub_entry
->target_section
->output_offset
5469 + stub_entry
->target_value
;
5470 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
5471 + stub_entry
->stub_sec
->output_offset
5472 + stub_entry
->stub_offset
;
5473 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
5475 abfd
= stub_entry
->target_section
->owner
;
5476 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
5478 (_("%pB: error: erratum 835769 stub out "
5479 "of range (input file too large)"), abfd
);
5481 target
= stub_entry
->target_value
;
5482 branch_insn
= 0x14000000;
5483 branch_offset
>>= 2;
5484 branch_offset
&= 0x3ffffff;
5485 branch_insn
|= branch_offset
;
5486 bfd_putl32 (branch_insn
, &contents
[target
]);
5493 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry
*gen_entry
,
5496 struct elf_aarch64_stub_hash_entry
*stub_entry
5497 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
5498 struct erratum_835769_branch_to_stub_data
*data
5499 = (struct erratum_835769_branch_to_stub_data
*) in_arg
;
5500 struct bfd_link_info
*info
;
5501 struct elf_aarch64_link_hash_table
*htab
;
5509 contents
= data
->contents
;
5510 section
= data
->output_section
;
5512 htab
= elf_aarch64_hash_table (info
);
5514 if (stub_entry
->target_section
!= section
5515 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
)
5518 BFD_ASSERT (((htab
->fix_erratum_843419
& ERRAT_ADRP
) && stub_entry
->stub_sec
)
5519 || (htab
->fix_erratum_843419
& ERRAT_ADR
));
5521 /* Only update the stub section if we have one. We should always have one if
5522 we're allowed to use the ADRP errata workaround, otherwise it is not
5524 if (stub_entry
->stub_sec
)
5526 insn
= bfd_getl32 (contents
+ stub_entry
->target_value
);
5528 stub_entry
->stub_sec
->contents
+ stub_entry
->stub_offset
);
5531 place
= (section
->output_section
->vma
+ section
->output_offset
5532 + stub_entry
->adrp_offset
);
5533 insn
= bfd_getl32 (contents
+ stub_entry
->adrp_offset
);
5535 if (!_bfd_aarch64_adrp_p (insn
))
5538 bfd_signed_vma imm
=
5539 (_bfd_aarch64_sign_extend
5540 ((bfd_vma
) _bfd_aarch64_decode_adrp_imm (insn
) << 12, 33)
5543 if ((htab
->fix_erratum_843419
& ERRAT_ADR
)
5544 && (imm
>= AARCH64_MIN_ADRP_IMM
&& imm
<= AARCH64_MAX_ADRP_IMM
))
5546 insn
= (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP
, imm
)
5547 | AARCH64_RT (insn
));
5548 bfd_putl32 (insn
, contents
+ stub_entry
->adrp_offset
);
5549 /* Stub is not needed, don't map it out. */
5550 stub_entry
->stub_type
= aarch64_stub_none
;
5552 else if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
5554 bfd_vma veneered_insn_loc
;
5555 bfd_vma veneer_entry_loc
;
5556 bfd_signed_vma branch_offset
;
5557 uint32_t branch_insn
;
5559 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
5560 + stub_entry
->target_section
->output_offset
5561 + stub_entry
->target_value
;
5562 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
5563 + stub_entry
->stub_sec
->output_offset
5564 + stub_entry
->stub_offset
;
5565 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
5567 abfd
= stub_entry
->target_section
->owner
;
5568 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
5570 (_("%pB: error: erratum 843419 stub out "
5571 "of range (input file too large)"), abfd
);
5573 branch_insn
= 0x14000000;
5574 branch_offset
>>= 2;
5575 branch_offset
&= 0x3ffffff;
5576 branch_insn
|= branch_offset
;
5577 bfd_putl32 (branch_insn
, contents
+ stub_entry
->target_value
);
5581 abfd
= stub_entry
->target_section
->owner
;
5583 (_("%pB: error: erratum 843419 immediate 0x%" PRIx64
5584 " out of range for ADR (input file too large) and "
5585 "--fix-cortex-a53-843419=adr used. Run the linker with "
5586 "--fix-cortex-a53-843419=full instead"),
5587 abfd
, (uint64_t) (bfd_vma
) imm
);
5588 bfd_set_error (bfd_error_bad_value
);
5589 /* This function is called inside a hashtable traversal and the error
5590 handlers called above turn into non-fatal errors. Which means this
5591 case ld returns an exit code 0 and also produces a broken object file.
5592 To prevent this, issue a hard abort. */
5600 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
5601 struct bfd_link_info
*link_info
,
5606 struct elf_aarch64_link_hash_table
*globals
=
5607 elf_aarch64_hash_table (link_info
);
5609 if (globals
== NULL
)
5612 /* Fix code to point to erratum 835769 stubs. */
5613 if (globals
->fix_erratum_835769
)
5615 struct erratum_835769_branch_to_stub_data data
;
5617 data
.info
= link_info
;
5618 data
.output_section
= sec
;
5619 data
.contents
= contents
;
5620 bfd_hash_traverse (&globals
->stub_hash_table
,
5621 make_branch_to_erratum_835769_stub
, &data
);
5624 if (globals
->fix_erratum_843419
)
5626 struct erratum_835769_branch_to_stub_data data
;
5628 data
.info
= link_info
;
5629 data
.output_section
= sec
;
5630 data
.contents
= contents
;
5631 bfd_hash_traverse (&globals
->stub_hash_table
,
5632 _bfd_aarch64_erratum_843419_branch_to_stub
, &data
);
5638 /* Return TRUE if RELOC is a relocation against the base of GOT table. */
5641 aarch64_relocation_aginst_gp_p (bfd_reloc_code_real_type reloc
)
5643 return (reloc
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
5644 || reloc
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5645 || reloc
== BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
5646 || reloc
== BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
5647 || reloc
== BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
);
5650 /* Perform a relocation as part of a final link. The input relocation type
5651 should be TLS relaxed. */
5653 static bfd_reloc_status_type
5654 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
5657 asection
*input_section
,
5659 Elf_Internal_Rela
*rel
,
5661 struct bfd_link_info
*info
,
5663 struct elf_link_hash_entry
*h
,
5664 bool *unresolved_reloc_p
,
5666 bfd_vma
*saved_addend
,
5667 Elf_Internal_Sym
*sym
)
5669 Elf_Internal_Shdr
*symtab_hdr
;
5670 unsigned int r_type
= howto
->type
;
5671 bfd_reloc_code_real_type bfd_r_type
5672 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
5673 unsigned long r_symndx
;
5674 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
5675 bfd_vma place
, off
, got_entry_addr
= 0;
5676 bfd_signed_vma signed_addend
;
5677 struct elf_aarch64_link_hash_table
*globals
;
5679 bool relative_reloc
;
5681 bfd_vma orig_value
= value
;
5682 bool resolved_to_zero
;
5685 globals
= elf_aarch64_hash_table (info
);
5687 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
5689 BFD_ASSERT (is_aarch64_elf (input_bfd
));
5691 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
5693 place
= input_section
->output_section
->vma
5694 + input_section
->output_offset
+ rel
->r_offset
;
5696 /* Get addend, accumulating the addend for consecutive relocs
5697 which refer to the same offset. */
5698 signed_addend
= saved_addend
? *saved_addend
: 0;
5699 signed_addend
+= rel
->r_addend
;
5701 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
5702 : bfd_is_und_section (sym_sec
));
5703 abs_symbol_p
= h
!= NULL
&& bfd_is_abs_symbol (&h
->root
);
5706 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
5707 it here if it is defined in a non-shared object. */
5709 && h
->type
== STT_GNU_IFUNC
5716 if ((input_section
->flags
& SEC_ALLOC
) == 0)
5718 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
5719 STT_GNU_IFUNC symbol as STT_FUNC. */
5720 if (elf_section_type (input_section
) == SHT_NOTE
)
5723 /* Dynamic relocs are not propagated for SEC_DEBUGGING
5724 sections because such sections are not SEC_ALLOC and
5725 thus ld.so will not process them. */
5726 if ((input_section
->flags
& SEC_DEBUGGING
) != 0)
5727 return bfd_reloc_ok
;
5729 if (h
->root
.root
.string
)
5730 name
= h
->root
.root
.string
;
5732 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
, NULL
);
5734 /* xgettext:c-format */
5735 (_("%pB(%pA+%#" PRIx64
"): "
5736 "unresolvable %s relocation against symbol `%s'"),
5737 input_bfd
, input_section
, (uint64_t) rel
->r_offset
,
5739 bfd_set_error (bfd_error_bad_value
);
5740 return bfd_reloc_notsupported
;
5742 else if (h
->plt
.offset
== (bfd_vma
) -1)
5743 goto bad_ifunc_reloc
;
5745 /* STT_GNU_IFUNC symbol must go through PLT. */
5746 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
5747 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
5753 if (h
->root
.root
.string
)
5754 name
= h
->root
.root
.string
;
5756 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
5759 /* xgettext:c-format */
5760 (_("%pB: relocation %s against STT_GNU_IFUNC "
5761 "symbol `%s' isn't handled by %s"), input_bfd
,
5762 howto
->name
, name
, __func__
);
5763 bfd_set_error (bfd_error_bad_value
);
5764 return bfd_reloc_notsupported
;
5766 case BFD_RELOC_AARCH64_NN
:
5767 if (rel
->r_addend
!= 0)
5769 if (h
->root
.root
.string
)
5770 name
= h
->root
.root
.string
;
5772 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
5775 /* xgettext:c-format */
5776 (_("%pB: relocation %s against STT_GNU_IFUNC "
5777 "symbol `%s' has non-zero addend: %" PRId64
),
5778 input_bfd
, howto
->name
, name
, (int64_t) rel
->r_addend
);
5779 bfd_set_error (bfd_error_bad_value
);
5780 return bfd_reloc_notsupported
;
5783 /* Generate dynamic relocation only when there is a
5784 non-GOT reference in a shared object. */
5785 if (bfd_link_pic (info
) && h
->non_got_ref
)
5787 Elf_Internal_Rela outrel
;
5790 /* Need a dynamic relocation to get the real function
5792 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
5796 if (outrel
.r_offset
== (bfd_vma
) -1
5797 || outrel
.r_offset
== (bfd_vma
) -2)
5800 outrel
.r_offset
+= (input_section
->output_section
->vma
5801 + input_section
->output_offset
);
5803 if (h
->dynindx
== -1
5805 || bfd_link_executable (info
))
5807 /* This symbol is resolved locally. */
5808 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
5809 outrel
.r_addend
= (h
->root
.u
.def
.value
5810 + h
->root
.u
.def
.section
->output_section
->vma
5811 + h
->root
.u
.def
.section
->output_offset
);
5815 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
5816 outrel
.r_addend
= 0;
5819 sreloc
= globals
->root
.irelifunc
;
5820 elf_append_rela (output_bfd
, sreloc
, &outrel
);
5822 /* If this reloc is against an external symbol, we
5823 do not want to fiddle with the addend. Otherwise,
5824 we need to include the symbol value so that it
5825 becomes an addend for the dynamic reloc. For an
5826 internal symbol, we have updated addend. */
5827 return bfd_reloc_ok
;
5830 case BFD_RELOC_AARCH64_CALL26
:
5831 case BFD_RELOC_AARCH64_JUMP26
:
5832 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
5836 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
5838 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5839 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5840 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5841 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5842 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5843 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
5844 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
5845 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
5846 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5847 base_got
= globals
->root
.sgot
;
5848 off
= h
->got
.offset
;
5850 if (base_got
== NULL
)
5853 if (off
== (bfd_vma
) -1)
5857 /* We can't use h->got.offset here to save state, or
5858 even just remember the offset, as finish_dynamic_symbol
5859 would use that as offset into .got. */
5861 if (globals
->root
.splt
!= NULL
)
5863 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
5864 globals
->plt_entry_size
);
5865 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
5866 base_got
= globals
->root
.sgotplt
;
5870 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
5871 off
= plt_index
* GOT_ENTRY_SIZE
;
5872 base_got
= globals
->root
.igotplt
;
5875 if (h
->dynindx
== -1
5879 /* This references the local definition. We must
5880 initialize this entry in the global offset table.
5881 Since the offset must always be a multiple of 8,
5882 we use the least significant bit to record
5883 whether we have initialized it already.
5885 When doing a dynamic link, we create a .rela.got
5886 relocation entry to initialize the value. This
5887 is done in the finish_dynamic_symbol routine. */
5892 bfd_put_NN (output_bfd
, value
,
5893 base_got
->contents
+ off
);
5894 /* Note that this is harmless as -1 | 1 still is -1. */
5898 value
= (base_got
->output_section
->vma
5899 + base_got
->output_offset
+ off
);
5902 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
5904 unresolved_reloc_p
);
5906 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
5907 addend
= (globals
->root
.sgot
->output_section
->vma
5908 + globals
->root
.sgot
->output_offset
);
5910 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
5912 addend
, weak_undef_p
);
5913 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
5914 case BFD_RELOC_AARCH64_ADD_LO12
:
5915 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
5921 resolved_to_zero
= (h
!= NULL
5922 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
5926 case BFD_RELOC_AARCH64_NONE
:
5927 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5928 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5929 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5930 *unresolved_reloc_p
= false;
5931 return bfd_reloc_ok
;
5933 case BFD_RELOC_AARCH64_NN
:
5935 /* When generating a shared library or PIE, these relocations
5936 are copied into the output file to be resolved at run time. */
5937 if ((bfd_link_pic (info
)
5938 && (input_section
->flags
& SEC_ALLOC
)
5940 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
5941 && !resolved_to_zero
)
5942 || h
->root
.type
!= bfd_link_hash_undefweak
))
5943 /* Or we are creating an executable, we may need to keep relocations
5944 for symbols satisfied by a dynamic library if we manage to avoid
5945 copy relocs for the symbol. */
5946 || (ELIMINATE_COPY_RELOCS
5947 && !bfd_link_pic (info
)
5949 && (input_section
->flags
& SEC_ALLOC
)
5954 || h
->root
.type
== bfd_link_hash_undefweak
5955 || h
->root
.type
== bfd_link_hash_undefined
)))
5957 Elf_Internal_Rela outrel
;
5959 bool skip
, relocate
;
5962 *unresolved_reloc_p
= false;
5967 outrel
.r_addend
= signed_addend
;
5969 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
5971 if (outrel
.r_offset
== (bfd_vma
) - 1)
5973 else if (outrel
.r_offset
== (bfd_vma
) - 2)
5978 else if (abs_symbol_p
)
5980 /* Local absolute symbol. */
5981 skip
= (h
->forced_local
|| (h
->dynindx
== -1));
5985 outrel
.r_offset
+= (input_section
->output_section
->vma
5986 + input_section
->output_offset
);
5989 memset (&outrel
, 0, sizeof outrel
);
5992 && (!bfd_link_pic (info
)
5993 || !(bfd_link_pie (info
) || SYMBOLIC_BIND (info
, h
))
5994 || !h
->def_regular
))
5995 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
5996 else if (info
->enable_dt_relr
5997 && input_section
->alignment_power
!= 0
5998 && rel
->r_offset
% 2 == 0)
6000 /* Don't emit a relative relocation that is packed, only
6001 apply the addend. */
6002 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
6003 contents
, rel
->r_offset
, value
,
6010 /* On SVR4-ish systems, the dynamic loader cannot
6011 relocate the text and data segments independently,
6012 so the symbol does not matter. */
6014 relocate
= !globals
->no_apply_dynamic_relocs
;
6015 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
6016 outrel
.r_addend
+= value
;
6019 sreloc
= elf_section_data (input_section
)->sreloc
;
6020 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
6021 return bfd_reloc_notsupported
;
6023 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
6024 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
6026 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
6028 /* Sanity to check that we have previously allocated
6029 sufficient space in the relocation section for the
6030 number of relocations we actually want to emit. */
6034 /* If this reloc is against an external symbol, we do not want to
6035 fiddle with the addend. Otherwise, we need to include the symbol
6036 value so that it becomes an addend for the dynamic reloc. */
6038 return bfd_reloc_ok
;
6040 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
6041 contents
, rel
->r_offset
, value
,
6045 value
+= signed_addend
;
6048 case BFD_RELOC_AARCH64_CALL26
:
6049 case BFD_RELOC_AARCH64_JUMP26
:
6051 asection
*splt
= globals
->root
.splt
;
6053 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
6055 /* A call to an undefined weak symbol is converted to a jump to
6056 the next instruction unless a PLT entry will be created.
6057 The jump to the next instruction is optimized as a NOP.
6058 Do the same for local undefined symbols. */
6059 if (weak_undef_p
&& ! via_plt_p
)
6061 bfd_putl32 (INSN_NOP
, hit_data
);
6062 return bfd_reloc_ok
;
6065 /* If the call goes through a PLT entry, make sure to
6066 check distance to the right destination address. */
6068 value
= (splt
->output_section
->vma
6069 + splt
->output_offset
+ h
->plt
.offset
);
6071 /* Check if a stub has to be inserted because the destination
6073 struct elf_aarch64_stub_hash_entry
*stub_entry
= NULL
;
6075 /* If the branch destination is directed to plt stub, "value" will be
6076 the final destination, otherwise we should plus signed_addend, it may
6077 contain non-zero value, for example call to local function symbol
6078 which are turned into "sec_sym + sec_off", and sec_off is kept in
6080 if (! aarch64_valid_branch_p (via_plt_p
? value
: value
+ signed_addend
,
6082 /* The target is out of reach, so redirect the branch to
6083 the local stub for this function. */
6084 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
, sym_sec
, h
,
6086 if (stub_entry
!= NULL
)
6088 value
= (stub_entry
->stub_offset
6089 + stub_entry
->stub_sec
->output_offset
6090 + stub_entry
->stub_sec
->output_section
->vma
);
6092 /* We have redirected the destination to stub entry address,
6093 so ignore any addend record in the original rela entry. */
6097 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6099 signed_addend
, weak_undef_p
);
6100 *unresolved_reloc_p
= false;
6103 case BFD_RELOC_AARCH64_16_PCREL
:
6104 case BFD_RELOC_AARCH64_32_PCREL
:
6105 case BFD_RELOC_AARCH64_64_PCREL
:
6106 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
6107 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6108 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
6109 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
6110 case BFD_RELOC_AARCH64_MOVW_PREL_G0
:
6111 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC
:
6112 case BFD_RELOC_AARCH64_MOVW_PREL_G1
:
6113 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC
:
6114 case BFD_RELOC_AARCH64_MOVW_PREL_G2
:
6115 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC
:
6116 case BFD_RELOC_AARCH64_MOVW_PREL_G3
:
6117 if (bfd_link_pic (info
)
6118 && (input_section
->flags
& SEC_ALLOC
) != 0
6119 && (input_section
->flags
& SEC_READONLY
) != 0
6120 && !_bfd_elf_symbol_refs_local_p (h
, info
, 1))
6122 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6125 /* xgettext:c-format */
6126 (_("%pB: relocation %s against symbol `%s' which may bind "
6127 "externally can not be used when making a shared object; "
6128 "recompile with -fPIC"),
6129 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
6130 h
->root
.root
.string
);
6131 bfd_set_error (bfd_error_bad_value
);
6132 return bfd_reloc_notsupported
;
6134 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6140 case BFD_RELOC_AARCH64_BRANCH19
:
6141 case BFD_RELOC_AARCH64_TSTBR14
:
6142 if (h
&& h
->root
.type
== bfd_link_hash_undefined
)
6145 /* xgettext:c-format */
6146 (_("%pB: conditional branch to undefined symbol `%s' "
6147 "not allowed"), input_bfd
, h
->root
.root
.string
);
6148 bfd_set_error (bfd_error_bad_value
);
6149 return bfd_reloc_notsupported
;
6153 case BFD_RELOC_AARCH64_16
:
6155 case BFD_RELOC_AARCH64_32
:
6157 case BFD_RELOC_AARCH64_ADD_LO12
:
6158 case BFD_RELOC_AARCH64_LDST128_LO12
:
6159 case BFD_RELOC_AARCH64_LDST16_LO12
:
6160 case BFD_RELOC_AARCH64_LDST32_LO12
:
6161 case BFD_RELOC_AARCH64_LDST64_LO12
:
6162 case BFD_RELOC_AARCH64_LDST8_LO12
:
6163 case BFD_RELOC_AARCH64_MOVW_G0
:
6164 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
6165 case BFD_RELOC_AARCH64_MOVW_G0_S
:
6166 case BFD_RELOC_AARCH64_MOVW_G1
:
6167 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
6168 case BFD_RELOC_AARCH64_MOVW_G1_S
:
6169 case BFD_RELOC_AARCH64_MOVW_G2
:
6170 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
6171 case BFD_RELOC_AARCH64_MOVW_G2_S
:
6172 case BFD_RELOC_AARCH64_MOVW_G3
:
6173 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6175 signed_addend
, weak_undef_p
);
6178 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6179 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6180 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6181 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6182 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6183 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6184 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
6185 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
6186 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
6187 if (globals
->root
.sgot
== NULL
)
6188 BFD_ASSERT (h
!= NULL
);
6190 relative_reloc
= false;
6195 /* If a symbol is not dynamic and is not undefined weak, bind it
6196 locally and generate a RELATIVE relocation under PIC mode.
6198 NOTE: one symbol may be referenced by several relocations, we
6199 should only generate one RELATIVE relocation for that symbol.
6200 Therefore, check GOT offset mark first. */
6201 if (h
->dynindx
== -1
6203 && h
->root
.type
!= bfd_link_hash_undefweak
6204 && bfd_link_pic (info
)
6205 && !symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
6206 relative_reloc
= true;
6208 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
, value
,
6210 unresolved_reloc_p
);
6211 /* Record the GOT entry address which will be used when generating
6212 RELATIVE relocation. */
6214 got_entry_addr
= value
;
6216 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
6217 addend
= (globals
->root
.sgot
->output_section
->vma
6218 + globals
->root
.sgot
->output_offset
);
6219 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6221 addend
, weak_undef_p
);
6226 struct elf_aarch64_local_symbol
*locals
6227 = elf_aarch64_locals (input_bfd
);
6231 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6233 /* xgettext:c-format */
6234 (_("%pB: local symbol descriptor table be NULL when applying "
6235 "relocation %s against local symbol"),
6236 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
6240 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
6241 base_got
= globals
->root
.sgot
;
6242 got_entry_addr
= (base_got
->output_section
->vma
6243 + base_got
->output_offset
+ off
);
6245 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
6247 bfd_put_64 (output_bfd
, value
, base_got
->contents
+ off
);
6249 /* For local symbol, we have done absolute relocation in static
6250 linking stage. While for shared library, we need to update the
6251 content of GOT entry according to the shared object's runtime
6252 base address. So, we need to generate a R_AARCH64_RELATIVE reloc
6253 for dynamic linker. */
6254 if (bfd_link_pic (info
))
6255 relative_reloc
= true;
6257 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
6260 /* Update the relocation value to GOT entry addr as we have transformed
6261 the direct data access into indirect data access through GOT. */
6262 value
= got_entry_addr
;
6264 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
6265 addend
= base_got
->output_section
->vma
+ base_got
->output_offset
;
6267 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6269 addend
, weak_undef_p
);
6272 /* Emit relative relocations, but not if they are packed (DT_RELR). */
6273 if (relative_reloc
&& !info
->enable_dt_relr
)
6276 Elf_Internal_Rela outrel
;
6278 s
= globals
->root
.srelgot
;
6282 outrel
.r_offset
= got_entry_addr
;
6283 outrel
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
6284 outrel
.r_addend
= orig_value
;
6285 elf_append_rela (output_bfd
, s
, &outrel
);
6289 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6290 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6291 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6292 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6293 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
6294 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
6295 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6296 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6297 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6298 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6299 if (globals
->root
.sgot
== NULL
)
6300 return bfd_reloc_notsupported
;
6302 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
6303 + globals
->root
.sgot
->output_section
->vma
6304 + globals
->root
.sgot
->output_offset
);
6306 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6309 *unresolved_reloc_p
= false;
6312 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
6313 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
6314 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
6315 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
6316 if (globals
->root
.sgot
== NULL
)
6317 return bfd_reloc_notsupported
;
6319 value
= symbol_got_offset (input_bfd
, h
, r_symndx
);
6320 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6323 *unresolved_reloc_p
= false;
6326 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
6327 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
6328 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
6329 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
6330 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
6331 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
6332 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
6333 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
6334 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
6335 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
6336 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
6337 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
6338 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
6339 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
6340 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
6341 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
6343 if (!(weak_undef_p
|| elf_hash_table (info
)->tls_sec
))
6345 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6347 /* xgettext:c-format */
6348 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
6349 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
6350 h
->root
.root
.string
);
6351 bfd_set_error (bfd_error_bad_value
);
6352 return bfd_reloc_notsupported
;
6356 = weak_undef_p
? 0 : signed_addend
- dtpoff_base (info
);
6357 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6359 def_value
, weak_undef_p
);
6363 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
6364 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
6365 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
6366 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
:
6367 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
:
6368 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
:
6369 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
:
6370 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
:
6371 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
:
6372 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
:
6373 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
:
6374 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
6375 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
6376 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
6377 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
6378 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
6380 if (!(weak_undef_p
|| elf_hash_table (info
)->tls_sec
))
6382 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6384 /* xgettext:c-format */
6385 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
6386 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
6387 h
->root
.root
.string
);
6388 bfd_set_error (bfd_error_bad_value
);
6389 return bfd_reloc_notsupported
;
6393 = weak_undef_p
? 0 : signed_addend
- tpoff_base (info
);
6394 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6396 def_value
, weak_undef_p
);
6397 *unresolved_reloc_p
= false;
6401 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
6402 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6403 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6404 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
6405 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
6406 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6407 if (globals
->root
.sgot
== NULL
)
6408 return bfd_reloc_notsupported
;
6409 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
6410 + globals
->root
.sgotplt
->output_section
->vma
6411 + globals
->root
.sgotplt
->output_offset
6412 + globals
->sgotplt_jump_table_size
);
6414 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6417 *unresolved_reloc_p
= false;
6420 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
6421 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
6422 if (globals
->root
.sgot
== NULL
)
6423 return bfd_reloc_notsupported
;
6425 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
6426 + globals
->root
.sgotplt
->output_section
->vma
6427 + globals
->root
.sgotplt
->output_offset
6428 + globals
->sgotplt_jump_table_size
);
6430 value
-= (globals
->root
.sgot
->output_section
->vma
6431 + globals
->root
.sgot
->output_offset
);
6433 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6436 *unresolved_reloc_p
= false;
6440 return bfd_reloc_notsupported
;
6444 *saved_addend
= value
;
6446 /* Only apply the final relocation in a sequence. */
6448 return bfd_reloc_continue
;
6450 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
6454 /* LP64 and ILP32 operates on x- and w-registers respectively.
6455 Next definitions take into account the difference between
6456 corresponding machine codes. R means x-register if the target
6457 arch is LP64, and w-register if the target is ILP32. */
6460 # define add_R0_R0 (0x91000000)
6461 # define add_R0_R0_R1 (0x8b000020)
6462 # define add_R0_R1 (0x91400020)
6463 # define ldr_R0 (0x58000000)
6464 # define ldr_R0_mask(i) (i & 0xffffffe0)
6465 # define ldr_R0_x0 (0xf9400000)
6466 # define ldr_hw_R0 (0xf2a00000)
6467 # define movk_R0 (0xf2800000)
6468 # define movz_R0 (0xd2a00000)
6469 # define movz_hw_R0 (0xd2c00000)
6470 #else /*ARCH_SIZE == 32 */
6471 # define add_R0_R0 (0x11000000)
6472 # define add_R0_R0_R1 (0x0b000020)
6473 # define add_R0_R1 (0x11400020)
6474 # define ldr_R0 (0x18000000)
6475 # define ldr_R0_mask(i) (i & 0xbfffffe0)
6476 # define ldr_R0_x0 (0xb9400000)
6477 # define ldr_hw_R0 (0x72a00000)
6478 # define movk_R0 (0x72800000)
6479 # define movz_R0 (0x52a00000)
6480 # define movz_hw_R0 (0x52c00000)
6483 /* Structure to hold payload for _bfd_aarch64_erratum_843419_clear_stub,
6484 it is used to identify the stub information to reset. */
6486 struct erratum_843419_branch_to_stub_clear_data
6488 bfd_vma adrp_offset
;
6489 asection
*output_section
;
6492 /* Clear the erratum information for GEN_ENTRY if the ADRP_OFFSET and
6493 section inside IN_ARG matches. The clearing is done by setting the
6494 stub_type to none. */
6497 _bfd_aarch64_erratum_843419_clear_stub (struct bfd_hash_entry
*gen_entry
,
6500 struct elf_aarch64_stub_hash_entry
*stub_entry
6501 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
6502 struct erratum_843419_branch_to_stub_clear_data
*data
6503 = (struct erratum_843419_branch_to_stub_clear_data
*) in_arg
;
6505 if (stub_entry
->target_section
!= data
->output_section
6506 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
6507 || stub_entry
->adrp_offset
!= data
->adrp_offset
)
6510 /* Change the stub type instead of removing the entry, removing from the hash
6511 table would be slower and we have already reserved the memory for the entry
6512 so there wouldn't be much gain. Changing the stub also keeps around a
6513 record of what was there before. */
6514 stub_entry
->stub_type
= aarch64_stub_none
;
6516 /* We're done and there could have been only one matching stub at that
6517 particular offset, so abort further traversal. */
6521 /* TLS Relaxations may relax an adrp sequence that matches the erratum 843419
6522 sequence. In this case the erratum no longer applies and we need to remove
6523 the entry from the pending stub generation. This clears matching adrp insn
6524 at ADRP_OFFSET in INPUT_SECTION in the stub table defined in GLOBALS. */
6527 clear_erratum_843419_entry (struct elf_aarch64_link_hash_table
*globals
,
6528 bfd_vma adrp_offset
, asection
*input_section
)
6530 if (globals
->fix_erratum_843419
& ERRAT_ADRP
)
6532 struct erratum_843419_branch_to_stub_clear_data data
;
6533 data
.adrp_offset
= adrp_offset
;
6534 data
.output_section
= input_section
;
6536 bfd_hash_traverse (&globals
->stub_hash_table
,
6537 _bfd_aarch64_erratum_843419_clear_stub
, &data
);
6541 /* Handle TLS relaxations. Relaxing is possible for symbols that use
6542 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
6545 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
6546 is to then call final_link_relocate. Return other values in the
6549 static bfd_reloc_status_type
6550 elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table
*globals
,
6551 bfd
*input_bfd
, asection
*input_section
,
6552 bfd_byte
*contents
, Elf_Internal_Rela
*rel
,
6553 struct elf_link_hash_entry
*h
,
6554 struct bfd_link_info
*info
)
6556 bool local_exec
= bfd_link_executable (info
)
6557 && SYMBOL_REFERENCES_LOCAL (info
, h
);
6558 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
6561 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
6563 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
))
6565 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
6566 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
6569 /* GD->LE relaxation:
6570 adrp x0, :tlsgd:var => movz R0, :tprel_g1:var
6572 adrp x0, :tlsdesc:var => movz R0, :tprel_g1:var
6574 Where R is x for LP64, and w for ILP32. */
6575 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
6576 /* We have relaxed the adrp into a mov, we may have to clear any
6577 pending erratum fixes. */
6578 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
6579 return bfd_reloc_continue
;
6583 /* GD->IE relaxation:
6584 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
6586 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
6588 return bfd_reloc_continue
;
6591 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
6595 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
6598 /* Tiny TLSDESC->LE relaxation:
6599 ldr x1, :tlsdesc:var => movz R0, #:tprel_g1:var
6600 adr x0, :tlsdesc:var => movk R0, #:tprel_g0_nc:var
6604 Where R is x for LP64, and w for ILP32. */
6605 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
6606 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
6608 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
6609 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
6610 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6612 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
6613 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
+ 4);
6614 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
6615 return bfd_reloc_continue
;
6619 /* Tiny TLSDESC->IE relaxation:
6620 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
6621 adr x0, :tlsdesc:var => nop
6625 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
6626 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
6628 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6629 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6631 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
);
6632 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
6633 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
6634 return bfd_reloc_continue
;
6637 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
6640 /* Tiny GD->LE relaxation:
6641 adr x0, :tlsgd:var => mrs x1, tpidr_el0
6642 bl __tls_get_addr => add R0, R1, #:tprel_hi12:x, lsl #12
6643 nop => add R0, R0, #:tprel_lo12_nc:x
6645 Where R is x for LP64, and x for Ilp32. */
6647 /* First kill the tls_get_addr reloc on the bl instruction. */
6648 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
6650 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
6651 bfd_putl32 (add_R0_R1
, contents
+ rel
->r_offset
+ 4);
6652 bfd_putl32 (add_R0_R0
, contents
+ rel
->r_offset
+ 8);
6654 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
6655 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
6656 rel
[1].r_offset
= rel
->r_offset
+ 8;
6658 /* Move the current relocation to the second instruction in
6661 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
6662 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
6663 return bfd_reloc_continue
;
6667 /* Tiny GD->IE relaxation:
6668 adr x0, :tlsgd:var => ldr R0, :gottprel:var
6669 bl __tls_get_addr => mrs x1, tpidr_el0
6670 nop => add R0, R0, R1
6672 Where R is x for LP64, and w for Ilp32. */
6674 /* First kill the tls_get_addr reloc on the bl instruction. */
6675 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
6676 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6678 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
);
6679 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
6680 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 8);
6681 return bfd_reloc_continue
;
6685 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
6686 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSGD_MOVW_G0_NC
));
6687 BFD_ASSERT (rel
->r_offset
+ 12 == rel
[2].r_offset
);
6688 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (CALL26
));
6692 /* Large GD->LE relaxation:
6693 movz x0, #:tlsgd_g1:var => movz x0, #:tprel_g2:var, lsl #32
6694 movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
6695 add x0, gp, x0 => movk x0, #:tprel_g0_nc:var
6696 bl __tls_get_addr => mrs x1, tpidr_el0
6697 nop => add x0, x0, x1
6699 rel
[2].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
6700 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
6701 rel
[2].r_offset
= rel
->r_offset
+ 8;
6703 bfd_putl32 (movz_hw_R0
, contents
+ rel
->r_offset
+ 0);
6704 bfd_putl32 (ldr_hw_R0
, contents
+ rel
->r_offset
+ 4);
6705 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
+ 8);
6706 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 12);
6707 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 16);
6711 /* Large GD->IE relaxation:
6712 movz x0, #:tlsgd_g1:var => movz x0, #:gottprel_g1:var, lsl #16
6713 movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
6714 add x0, gp, x0 => ldr x0, [gp, x0]
6715 bl __tls_get_addr => mrs x1, tpidr_el0
6716 nop => add x0, x0, x1
6718 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6719 bfd_putl32 (0xd2a80000, contents
+ rel
->r_offset
+ 0);
6720 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
+ 8);
6721 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 12);
6722 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 16);
6724 return bfd_reloc_continue
;
6726 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
6727 return bfd_reloc_continue
;
6730 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
6731 return bfd_reloc_continue
;
6733 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
6736 /* GD->LE relaxation:
6737 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
6739 Where R is x for lp64 mode, and w for ILP32 mode. */
6740 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
6741 return bfd_reloc_continue
;
6745 /* GD->IE relaxation:
6746 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr R0, [x0, #:gottprel_lo12:var]
6748 Where R is x for lp64 mode, and w for ILP32 mode. */
6749 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
6750 bfd_putl32 (ldr_R0_mask (insn
), contents
+ rel
->r_offset
);
6751 return bfd_reloc_continue
;
6754 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
6757 /* GD->LE relaxation
6758 add x0, #:tlsgd_lo12:var => movk R0, :tprel_g0_nc:var
6759 bl __tls_get_addr => mrs x1, tpidr_el0
6760 nop => add R0, R1, R0
6762 Where R is x for lp64 mode, and w for ILP32 mode. */
6764 /* First kill the tls_get_addr reloc on the bl instruction. */
6765 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
6766 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6768 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
6769 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
6770 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 8);
6771 return bfd_reloc_continue
;
6775 /* GD->IE relaxation
6776 ADD x0, #:tlsgd_lo12:var => ldr R0, [x0, #:gottprel_lo12:var]
6777 BL __tls_get_addr => mrs x1, tpidr_el0
6779 NOP => add R0, R1, R0
6781 Where R is x for lp64 mode, and w for ilp32 mode. */
6783 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
6785 /* Remove the relocation on the BL instruction. */
6786 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6788 /* We choose to fixup the BL and NOP instructions using the
6789 offset from the second relocation to allow flexibility in
6790 scheduling instructions between the ADD and BL. */
6791 bfd_putl32 (ldr_R0_x0
, contents
+ rel
->r_offset
);
6792 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
6793 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
[1].r_offset
+ 4);
6794 return bfd_reloc_continue
;
6797 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
6798 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
6799 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
6800 /* GD->IE/LE relaxation:
6801 add x0, x0, #:tlsdesc_lo12:var => nop
6804 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
6805 return bfd_reloc_ok
;
6807 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
6810 /* GD->LE relaxation:
6811 ldr xd, [gp, xn] => movk R0, #:tprel_g0_nc:var
6813 Where R is x for lp64 mode, and w for ILP32 mode. */
6814 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
6815 return bfd_reloc_continue
;
6819 /* GD->IE relaxation:
6820 ldr xd, [gp, xn] => ldr R0, [gp, xn]
6822 Where R is x for lp64 mode, and w for ILP32 mode. */
6823 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
6824 bfd_putl32 (ldr_R0_mask (insn
), contents
+ rel
->r_offset
);
6825 return bfd_reloc_ok
;
6828 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
6829 /* GD->LE relaxation:
6830 movk xd, #:tlsdesc_off_g0_nc:var => movk R0, #:tprel_g1_nc:var, lsl #16
6832 movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
6834 Where R is x for lp64 mode, and w for ILP32 mode. */
6836 bfd_putl32 (ldr_hw_R0
, contents
+ rel
->r_offset
);
6837 return bfd_reloc_continue
;
6839 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
6842 /* GD->LE relaxation:
6843 movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
6845 Where R is x for lp64 mode, and w for ILP32 mode. */
6846 bfd_putl32 (movz_hw_R0
, contents
+ rel
->r_offset
);
6847 return bfd_reloc_continue
;
6851 /* GD->IE relaxation:
6852 movz xd, #:tlsdesc_off_g1:var => movz Rd, #:gottprel_g1:var, lsl #16
6854 Where R is x for lp64 mode, and w for ILP32 mode. */
6855 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
6856 bfd_putl32 (movz_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
6857 return bfd_reloc_continue
;
6860 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
6861 /* IE->LE relaxation:
6862 adrp xd, :gottprel:var => movz Rd, :tprel_g1:var
6864 Where R is x for lp64 mode, and w for ILP32 mode. */
6867 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
6868 bfd_putl32 (movz_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
6869 /* We have relaxed the adrp into a mov, we may have to clear any
6870 pending erratum fixes. */
6871 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
6873 return bfd_reloc_continue
;
6875 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
6876 /* IE->LE relaxation:
6877 ldr xd, [xm, #:gottprel_lo12:var] => movk Rd, :tprel_g0_nc:var
6879 Where R is x for lp64 mode, and w for ILP32 mode. */
6882 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
6883 bfd_putl32 (movk_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
6885 return bfd_reloc_continue
;
6887 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
6888 /* LD->LE relaxation (tiny):
6889 adr x0, :tlsldm:x => mrs x0, tpidr_el0
6890 bl __tls_get_addr => add R0, R0, TCB_SIZE
6892 Where R is x for lp64 mode, and w for ilp32 mode. */
6895 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
6896 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
6897 /* No need of CALL26 relocation for tls_get_addr. */
6898 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6899 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
+ 0);
6900 bfd_putl32 (add_R0_R0
| (TCB_SIZE
<< 10),
6901 contents
+ rel
->r_offset
+ 4);
6902 return bfd_reloc_ok
;
6904 return bfd_reloc_continue
;
6906 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
6907 /* LD->LE relaxation (small):
6908 adrp x0, :tlsldm:x => mrs x0, tpidr_el0
6912 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
);
6913 return bfd_reloc_ok
;
6915 return bfd_reloc_continue
;
6917 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
6918 /* LD->LE relaxation (small):
6919 add x0, #:tlsldm_lo12:x => add R0, R0, TCB_SIZE
6920 bl __tls_get_addr => nop
6922 Where R is x for lp64 mode, and w for ilp32 mode. */
6925 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
6926 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
6927 /* No need of CALL26 relocation for tls_get_addr. */
6928 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
6929 bfd_putl32 (add_R0_R0
| (TCB_SIZE
<< 10),
6930 contents
+ rel
->r_offset
+ 0);
6931 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
6932 return bfd_reloc_ok
;
6934 return bfd_reloc_continue
;
6937 return bfd_reloc_continue
;
6940 return bfd_reloc_ok
;
6943 /* Relocate an AArch64 ELF section. */
6946 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
6947 struct bfd_link_info
*info
,
6949 asection
*input_section
,
6951 Elf_Internal_Rela
*relocs
,
6952 Elf_Internal_Sym
*local_syms
,
6953 asection
**local_sections
)
6955 Elf_Internal_Shdr
*symtab_hdr
;
6956 struct elf_link_hash_entry
**sym_hashes
;
6957 Elf_Internal_Rela
*rel
;
6958 Elf_Internal_Rela
*relend
;
6960 struct elf_aarch64_link_hash_table
*globals
;
6961 bool save_addend
= false;
6964 globals
= elf_aarch64_hash_table (info
);
6966 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
6967 sym_hashes
= elf_sym_hashes (input_bfd
);
6970 relend
= relocs
+ input_section
->reloc_count
;
6971 for (; rel
< relend
; rel
++)
6973 unsigned int r_type
;
6974 bfd_reloc_code_real_type bfd_r_type
;
6975 bfd_reloc_code_real_type relaxed_bfd_r_type
;
6976 reloc_howto_type
*howto
;
6977 unsigned long r_symndx
;
6978 Elf_Internal_Sym
*sym
;
6980 struct elf_link_hash_entry
*h
;
6982 bfd_reloc_status_type r
;
6985 bool unresolved_reloc
= false;
6986 char *error_message
= NULL
;
6988 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6989 r_type
= ELFNN_R_TYPE (rel
->r_info
);
6991 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (input_bfd
, r_type
);
6992 howto
= bfd_reloc
.howto
;
6995 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
6997 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
7003 if (r_symndx
< symtab_hdr
->sh_info
)
7005 sym
= local_syms
+ r_symndx
;
7006 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
7007 sec
= local_sections
[r_symndx
];
7009 /* An object file might have a reference to a local
7010 undefined symbol. This is a daft object file, but we
7011 should at least do something about it. NONE and NULL
7012 relocations do not use the symbol and are explicitly
7013 allowed to use an undefined one, so allow those.
7014 Likewise for relocations against STN_UNDEF. */
7015 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
7016 && r_symndx
!= STN_UNDEF
7017 && bfd_is_und_section (sec
)
7018 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
7019 (*info
->callbacks
->undefined_symbol
)
7020 (info
, bfd_elf_string_from_elf_section
7021 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
7022 input_bfd
, input_section
, rel
->r_offset
, true);
7024 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
7026 /* Relocate against local STT_GNU_IFUNC symbol. */
7027 if (!bfd_link_relocatable (info
)
7028 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
7030 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
7035 /* Set STT_GNU_IFUNC symbol value. */
7036 h
->root
.u
.def
.value
= sym
->st_value
;
7037 h
->root
.u
.def
.section
= sec
;
7042 bool warned
, ignored
;
7044 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
7045 r_symndx
, symtab_hdr
, sym_hashes
,
7047 unresolved_reloc
, warned
, ignored
);
7052 if (sec
!= NULL
&& discarded_section (sec
))
7053 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
7054 rel
, 1, relend
, howto
, 0, contents
);
7056 if (bfd_link_relocatable (info
))
7060 name
= h
->root
.root
.string
;
7063 name
= (bfd_elf_string_from_elf_section
7064 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
7065 if (name
== NULL
|| *name
== '\0')
7066 name
= bfd_section_name (sec
);
7070 && r_type
!= R_AARCH64_NONE
7071 && r_type
!= R_AARCH64_NULL
7073 || h
->root
.type
== bfd_link_hash_defined
7074 || h
->root
.type
== bfd_link_hash_defweak
)
7075 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
7078 ((sym_type
== STT_TLS
7079 /* xgettext:c-format */
7080 ? _("%pB(%pA+%#" PRIx64
"): %s used with TLS symbol %s")
7081 /* xgettext:c-format */
7082 : _("%pB(%pA+%#" PRIx64
"): %s used with non-TLS symbol %s")),
7084 input_section
, (uint64_t) rel
->r_offset
, howto
->name
, name
);
7087 /* We relax only if we can see that there can be a valid transition
7088 from a reloc type to another.
7089 We call elfNN_aarch64_final_link_relocate unless we're completely
7090 done, i.e., the relaxation produced the final output we want. */
7092 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, r_type
,
7094 if (relaxed_bfd_r_type
!= bfd_r_type
)
7096 bfd_r_type
= relaxed_bfd_r_type
;
7097 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
7098 BFD_ASSERT (howto
!= NULL
);
7099 r_type
= howto
->type
;
7100 r
= elfNN_aarch64_tls_relax (globals
, input_bfd
, input_section
,
7101 contents
, rel
, h
, info
);
7102 unresolved_reloc
= 0;
7105 r
= bfd_reloc_continue
;
7107 /* There may be multiple consecutive relocations for the
7108 same offset. In that case we are supposed to treat the
7109 output of each relocation as the addend for the next. */
7110 if (rel
+ 1 < relend
7111 && rel
->r_offset
== rel
[1].r_offset
7112 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
7113 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
7116 save_addend
= false;
7118 if (r
== bfd_reloc_continue
)
7119 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
7120 input_section
, contents
, rel
,
7121 relocation
, info
, sec
,
7122 h
, &unresolved_reloc
,
7123 save_addend
, &addend
, sym
);
7125 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
))
7127 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
7128 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
7129 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
7130 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
7131 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
7132 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
7133 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
7134 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
7135 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7137 bool need_relocs
= false;
7142 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
7143 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
7146 (!bfd_link_executable (info
) || indx
!= 0) &&
7148 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7149 || h
->root
.type
!= bfd_link_hash_undefweak
);
7151 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
7155 Elf_Internal_Rela rela
;
7156 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
7158 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
7159 globals
->root
.sgot
->output_offset
+ off
;
7162 loc
= globals
->root
.srelgot
->contents
;
7163 loc
+= globals
->root
.srelgot
->reloc_count
++
7164 * RELOC_SIZE (htab
);
7165 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7167 bfd_reloc_code_real_type real_type
=
7168 elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
7170 if (real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
7171 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
7172 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
)
7174 /* For local dynamic, don't generate DTPREL in any case.
7175 Initialize the DTPREL slot into zero, so we get module
7176 base address when invoke runtime TLS resolver. */
7177 bfd_put_NN (output_bfd
, 0,
7178 globals
->root
.sgot
->contents
+ off
7183 bfd_put_NN (output_bfd
,
7184 relocation
- dtpoff_base (info
),
7185 globals
->root
.sgot
->contents
+ off
7190 /* This TLS symbol is global. We emit a
7191 relocation to fixup the tls offset at load
7194 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
7197 (globals
->root
.sgot
->output_section
->vma
7198 + globals
->root
.sgot
->output_offset
+ off
7201 loc
= globals
->root
.srelgot
->contents
;
7202 loc
+= globals
->root
.srelgot
->reloc_count
++
7203 * RELOC_SIZE (globals
);
7204 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7205 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
7206 globals
->root
.sgot
->contents
+ off
7212 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
7213 globals
->root
.sgot
->contents
+ off
);
7214 bfd_put_NN (output_bfd
,
7215 relocation
- dtpoff_base (info
),
7216 globals
->root
.sgot
->contents
+ off
7220 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
7224 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
7225 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
7226 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
7227 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
7228 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
7229 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7231 bool need_relocs
= false;
7236 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
7238 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
7241 (!bfd_link_executable (info
) || indx
!= 0) &&
7243 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7244 || h
->root
.type
!= bfd_link_hash_undefweak
);
7246 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
7250 Elf_Internal_Rela rela
;
7253 rela
.r_addend
= relocation
- dtpoff_base (info
);
7257 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
7258 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
7259 globals
->root
.sgot
->output_offset
+ off
;
7261 loc
= globals
->root
.srelgot
->contents
;
7262 loc
+= globals
->root
.srelgot
->reloc_count
++
7263 * RELOC_SIZE (htab
);
7265 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7267 bfd_put_NN (output_bfd
, rela
.r_addend
,
7268 globals
->root
.sgot
->contents
+ off
);
7271 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
7272 globals
->root
.sgot
->contents
+ off
);
7274 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
7278 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
7279 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
7280 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
7281 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
7282 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
7283 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
7284 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
7285 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7287 bool need_relocs
= false;
7288 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
7289 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
7291 need_relocs
= (h
== NULL
7292 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
7293 || h
->root
.type
!= bfd_link_hash_undefweak
);
7295 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
7296 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
7301 Elf_Internal_Rela rela
;
7302 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLSDESC
));
7305 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
7306 + globals
->root
.sgotplt
->output_offset
7307 + off
+ globals
->sgotplt_jump_table_size
);
7310 rela
.r_addend
= relocation
- dtpoff_base (info
);
7312 /* Allocate the next available slot in the PLT reloc
7313 section to hold our R_AARCH64_TLSDESC, the next
7314 available slot is determined from reloc_count,
7315 which we step. But note, reloc_count was
7316 artifically moved down while allocating slots for
7317 real PLT relocs such that all of the PLT relocs
7318 will fit above the initial reloc_count and the
7319 extra stuff will fit below. */
7320 loc
= globals
->root
.srelplt
->contents
;
7321 loc
+= globals
->root
.srelplt
->reloc_count
++
7322 * RELOC_SIZE (globals
);
7324 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
7326 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
7327 globals
->root
.sgotplt
->contents
+ off
+
7328 globals
->sgotplt_jump_table_size
);
7329 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
7330 globals
->root
.sgotplt
->contents
+ off
+
7331 globals
->sgotplt_jump_table_size
+
7335 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
7342 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
7343 because such sections are not SEC_ALLOC and thus ld.so will
7344 not process them. */
7345 if (unresolved_reloc
7346 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
7348 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
7349 +rel
->r_offset
) != (bfd_vma
) - 1)
7352 /* xgettext:c-format */
7353 (_("%pB(%pA+%#" PRIx64
"): "
7354 "unresolvable %s relocation against symbol `%s'"),
7355 input_bfd
, input_section
, (uint64_t) rel
->r_offset
, howto
->name
,
7356 h
->root
.root
.string
);
7360 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
7362 bfd_reloc_code_real_type real_r_type
7363 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
7367 case bfd_reloc_overflow
:
7368 (*info
->callbacks
->reloc_overflow
)
7369 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
7370 input_bfd
, input_section
, rel
->r_offset
);
7371 if (real_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
7372 || real_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
7374 (*info
->callbacks
->warning
)
7376 _("too many GOT entries for -fpic, "
7377 "please recompile with -fPIC"),
7378 name
, input_bfd
, input_section
, rel
->r_offset
);
7381 /* Overflow can occur when a variable is referenced with a type
7382 that has a larger alignment than the type with which it was
7384 file1.c: extern int foo; int a (void) { return foo; }
7385 file2.c: char bar, foo, baz;
7386 If the variable is placed into a data section at an offset
7387 that is incompatible with the larger alignment requirement
7388 overflow will occur. (Strictly speaking this is not overflow
7389 but rather an alignment problem, but the bfd_reloc_ error
7390 enum does not have a value to cover that situation).
7392 Try to catch this situation here and provide a more helpful
7393 error message to the user. */
7394 if (addend
& (((bfd_vma
) 1 << howto
->rightshift
) - 1)
7395 /* FIXME: Are we testing all of the appropriate reloc
7397 && (real_r_type
== BFD_RELOC_AARCH64_LD_LO19_PCREL
7398 || real_r_type
== BFD_RELOC_AARCH64_LDST16_LO12
7399 || real_r_type
== BFD_RELOC_AARCH64_LDST32_LO12
7400 || real_r_type
== BFD_RELOC_AARCH64_LDST64_LO12
7401 || real_r_type
== BFD_RELOC_AARCH64_LDST128_LO12
))
7403 info
->callbacks
->warning
7404 (info
, _("one possible cause of this error is that the \
7405 symbol is being referenced in the indicated code as if it had a larger \
7406 alignment than was declared where it was defined"),
7407 name
, input_bfd
, input_section
, rel
->r_offset
);
7411 case bfd_reloc_undefined
:
7412 (*info
->callbacks
->undefined_symbol
)
7413 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, true);
7416 case bfd_reloc_outofrange
:
7417 error_message
= _("out of range");
7420 case bfd_reloc_notsupported
:
7421 error_message
= _("unsupported relocation");
7424 case bfd_reloc_dangerous
:
7425 /* error_message should already be set. */
7429 error_message
= _("unknown error");
7433 BFD_ASSERT (error_message
!= NULL
);
7434 (*info
->callbacks
->reloc_dangerous
)
7435 (info
, error_message
, input_bfd
, input_section
, rel
->r_offset
);
7447 /* Set the right machine number. */
7450 elfNN_aarch64_object_p (bfd
*abfd
)
7453 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
7455 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
7460 /* Function to keep AArch64 specific flags in the ELF header. */
7463 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
7465 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
7470 elf_elfheader (abfd
)->e_flags
= flags
;
7471 elf_flags_init (abfd
) = true;
7477 /* Merge backend specific data from an object file to the output
7478 object file when linking. */
7481 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
7483 bfd
*obfd
= info
->output_bfd
;
7486 bool flags_compatible
= true;
7489 /* Check if we have the same endianess. */
7490 if (!_bfd_generic_verify_endian_match (ibfd
, info
))
7493 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
7496 /* The input BFD must have had its flags initialised. */
7497 /* The following seems bogus to me -- The flags are initialized in
7498 the assembler but I don't think an elf_flags_init field is
7499 written into the object. */
7500 /* BFD_ASSERT (elf_flags_init (ibfd)); */
7502 in_flags
= elf_elfheader (ibfd
)->e_flags
;
7503 out_flags
= elf_elfheader (obfd
)->e_flags
;
7505 if (!elf_flags_init (obfd
))
7507 /* If the input is the default architecture and had the default
7508 flags then do not bother setting the flags for the output
7509 architecture, instead allow future merges to do this. If no
7510 future merges ever set these flags then they will retain their
7511 uninitialised values, which surprise surprise, correspond
7512 to the default values. */
7513 if (bfd_get_arch_info (ibfd
)->the_default
7514 && elf_elfheader (ibfd
)->e_flags
== 0)
7517 elf_flags_init (obfd
) = true;
7518 elf_elfheader (obfd
)->e_flags
= in_flags
;
7520 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
7521 && bfd_get_arch_info (obfd
)->the_default
)
7522 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
7523 bfd_get_mach (ibfd
));
7528 /* Identical flags must be compatible. */
7529 if (in_flags
== out_flags
)
7532 /* Check to see if the input BFD actually contains any sections. If
7533 not, its flags may not have been initialised either, but it
7534 cannot actually cause any incompatiblity. Do not short-circuit
7535 dynamic objects; their section list may be emptied by
7536 elf_link_add_object_symbols.
7538 Also check to see if there are no code sections in the input.
7539 In this case there is no need to check for code specific flags.
7540 XXX - do we need to worry about floating-point format compatability
7541 in data sections ? */
7542 if (!(ibfd
->flags
& DYNAMIC
))
7544 bool null_input_bfd
= true;
7545 bool only_data_sections
= true;
7547 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
7549 if ((bfd_section_flags (sec
)
7550 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
7551 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
7552 only_data_sections
= false;
7554 null_input_bfd
= false;
7558 if (null_input_bfd
|| only_data_sections
)
7562 return flags_compatible
;
7565 /* Display the flags field. */
7568 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
7570 FILE *file
= (FILE *) ptr
;
7571 unsigned long flags
;
7573 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
7575 /* Print normal ELF private data. */
7576 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
7578 flags
= elf_elfheader (abfd
)->e_flags
;
7579 /* Ignore init flag - it may not be set, despite the flags field
7580 containing valid data. */
7582 /* xgettext:c-format */
7583 fprintf (file
, _("private flags = 0x%lx:"), elf_elfheader (abfd
)->e_flags
);
7586 fprintf (file
, _(" <Unrecognised flag bits set>"));
7593 /* Return true if we need copy relocation against EH. */
7596 need_copy_relocation_p (struct elf_aarch64_link_hash_entry
*eh
)
7598 struct elf_dyn_relocs
*p
;
7601 for (p
= eh
->root
.dyn_relocs
; p
!= NULL
; p
= p
->next
)
7603 /* If there is any pc-relative reference, we need to keep copy relocation
7604 to avoid propagating the relocation into runtime that current glibc
7605 does not support. */
7609 s
= p
->sec
->output_section
;
7610 /* Need copy relocation if it's against read-only section. */
7611 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
7618 /* Adjust a symbol defined by a dynamic object and referenced by a
7619 regular object. The current definition is in some section of the
7620 dynamic object, but we're not including those sections. We have to
7621 change the definition to something the rest of the link can
7625 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
7626 struct elf_link_hash_entry
*h
)
7628 struct elf_aarch64_link_hash_table
*htab
;
7631 /* If this is a function, put it in the procedure linkage table. We
7632 will fill in the contents of the procedure linkage table later,
7633 when we know the address of the .got section. */
7634 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
7636 if (h
->plt
.refcount
<= 0
7637 || (h
->type
!= STT_GNU_IFUNC
7638 && (SYMBOL_CALLS_LOCAL (info
, h
)
7639 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
7640 && h
->root
.type
== bfd_link_hash_undefweak
))))
7642 /* This case can occur if we saw a CALL26 reloc in
7643 an input file, but the symbol wasn't referred to
7644 by a dynamic object or all references were
7645 garbage collected. In which case we can end up
7647 h
->plt
.offset
= (bfd_vma
) - 1;
7654 /* Otherwise, reset to -1. */
7655 h
->plt
.offset
= (bfd_vma
) - 1;
7658 /* If this is a weak symbol, and there is a real definition, the
7659 processor independent code will have arranged for us to see the
7660 real definition first, and we can just use the same value. */
7661 if (h
->is_weakalias
)
7663 struct elf_link_hash_entry
*def
= weakdef (h
);
7664 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
7665 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
7666 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
7667 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
7668 h
->non_got_ref
= def
->non_got_ref
;
7672 /* If we are creating a shared library, we must presume that the
7673 only references to the symbol are via the global offset table.
7674 For such cases we need not do anything here; the relocations will
7675 be handled correctly by relocate_section. */
7676 if (bfd_link_pic (info
))
7679 /* If there are no references to this symbol that do not use the
7680 GOT, we don't need to generate a copy reloc. */
7681 if (!h
->non_got_ref
)
7684 /* If -z nocopyreloc was given, we won't generate them either. */
7685 if (info
->nocopyreloc
)
7691 if (ELIMINATE_COPY_RELOCS
)
7693 struct elf_aarch64_link_hash_entry
*eh
;
7694 /* If we don't find any dynamic relocs in read-only sections, then
7695 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
7696 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
7697 if (!need_copy_relocation_p (eh
))
7704 /* We must allocate the symbol in our .dynbss section, which will
7705 become part of the .bss section of the executable. There will be
7706 an entry for this symbol in the .dynsym section. The dynamic
7707 object will contain position independent code, so all references
7708 from the dynamic object to this symbol will go through the global
7709 offset table. The dynamic linker will use the .dynsym entry to
7710 determine the address it must put in the global offset table, so
7711 both the dynamic object and the regular object will refer to the
7712 same memory location for the variable. */
7714 htab
= elf_aarch64_hash_table (info
);
7716 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
7717 to copy the initial value out of the dynamic object and into the
7718 runtime process image. */
7719 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
7721 s
= htab
->root
.sdynrelro
;
7722 srel
= htab
->root
.sreldynrelro
;
7726 s
= htab
->root
.sdynbss
;
7727 srel
= htab
->root
.srelbss
;
7729 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
7731 srel
->size
+= RELOC_SIZE (htab
);
7735 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
7740 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
7742 struct elf_aarch64_local_symbol
*locals
;
7743 locals
= elf_aarch64_locals (abfd
);
7746 locals
= (struct elf_aarch64_local_symbol
*)
7747 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
7750 elf_aarch64_locals (abfd
) = locals
;
7755 /* Create the .got section to hold the global offset table. */
7758 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
7760 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
7763 struct elf_link_hash_entry
*h
;
7764 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
7766 /* This function may be called more than once. */
7767 if (htab
->sgot
!= NULL
)
7770 flags
= bed
->dynamic_sec_flags
;
7772 s
= bfd_make_section_anyway_with_flags (abfd
,
7773 (bed
->rela_plts_and_copies_p
7774 ? ".rela.got" : ".rel.got"),
7775 (bed
->dynamic_sec_flags
7778 || !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
7782 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
7784 || !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
7787 htab
->sgot
->size
+= GOT_ENTRY_SIZE
;
7789 if (bed
->want_got_sym
)
7791 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
7792 (or .got.plt) section. We don't do this in the linker script
7793 because we don't want to define the symbol if we are not creating
7794 a global offset table. */
7795 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
7796 "_GLOBAL_OFFSET_TABLE_");
7797 elf_hash_table (info
)->hgot
= h
;
7802 if (bed
->want_got_plt
)
7804 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
7806 || !bfd_set_section_alignment (s
, bed
->s
->log_file_align
))
7811 /* The first bit of the global offset table is the header. */
7812 s
->size
+= bed
->got_header_size
;
7817 /* Look through the relocs for a section during the first phase. */
7820 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
7821 asection
*sec
, const Elf_Internal_Rela
*relocs
)
7823 Elf_Internal_Shdr
*symtab_hdr
;
7824 struct elf_link_hash_entry
**sym_hashes
;
7825 const Elf_Internal_Rela
*rel
;
7826 const Elf_Internal_Rela
*rel_end
;
7829 struct elf_aarch64_link_hash_table
*htab
;
7831 if (bfd_link_relocatable (info
))
7834 BFD_ASSERT (is_aarch64_elf (abfd
));
7836 htab
= elf_aarch64_hash_table (info
);
7839 symtab_hdr
= &elf_symtab_hdr (abfd
);
7840 sym_hashes
= elf_sym_hashes (abfd
);
7842 rel_end
= relocs
+ sec
->reloc_count
;
7843 for (rel
= relocs
; rel
< rel_end
; rel
++)
7845 struct elf_link_hash_entry
*h
;
7846 unsigned int r_symndx
;
7847 unsigned int r_type
;
7848 bfd_reloc_code_real_type bfd_r_type
;
7849 Elf_Internal_Sym
*isym
;
7851 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
7852 r_type
= ELFNN_R_TYPE (rel
->r_info
);
7854 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
7856 /* xgettext:c-format */
7857 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
7861 if (r_symndx
< symtab_hdr
->sh_info
)
7863 /* A local symbol. */
7864 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
7869 /* Check relocation against local STT_GNU_IFUNC symbol. */
7870 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
7872 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
7877 /* Fake a STT_GNU_IFUNC symbol. */
7878 h
->type
= STT_GNU_IFUNC
;
7881 h
->forced_local
= 1;
7882 h
->root
.type
= bfd_link_hash_defined
;
7889 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
7890 while (h
->root
.type
== bfd_link_hash_indirect
7891 || h
->root
.type
== bfd_link_hash_warning
)
7892 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
7895 /* Could be done earlier, if h were already available. */
7896 bfd_r_type
= aarch64_tls_transition (abfd
, info
, r_type
, h
, r_symndx
);
7900 /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
7901 This shows up in particular in an R_AARCH64_PREL64 in large model
7902 when calculating the pc-relative address to .got section which is
7903 used to initialize the gp register. */
7904 if (h
->root
.root
.string
7905 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
7907 if (htab
->root
.dynobj
== NULL
)
7908 htab
->root
.dynobj
= abfd
;
7910 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
7913 BFD_ASSERT (h
== htab
->root
.hgot
);
7916 /* Create the ifunc sections for static executables. If we
7917 never see an indirect function symbol nor we are building
7918 a static executable, those sections will be empty and
7919 won't appear in output. */
7925 case BFD_RELOC_AARCH64_ADD_LO12
:
7926 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
7927 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
7928 case BFD_RELOC_AARCH64_CALL26
:
7929 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
7930 case BFD_RELOC_AARCH64_JUMP26
:
7931 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
7932 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
7933 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
7934 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
7935 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
7936 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
7937 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
7938 case BFD_RELOC_AARCH64_NN
:
7939 if (htab
->root
.dynobj
== NULL
)
7940 htab
->root
.dynobj
= abfd
;
7941 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
7946 /* It is referenced by a non-shared object. */
7952 case BFD_RELOC_AARCH64_16
:
7954 case BFD_RELOC_AARCH64_32
:
7956 if (bfd_link_pic (info
) && (sec
->flags
& SEC_ALLOC
) != 0)
7959 /* This is an absolute symbol. It represents a value instead
7961 && (bfd_is_abs_symbol (&h
->root
)
7962 /* This is an undefined symbol. */
7963 || h
->root
.type
== bfd_link_hash_undefined
))
7966 /* For local symbols, defined global symbols in a non-ABS section,
7967 it is assumed that the value is an address. */
7968 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7970 /* xgettext:c-format */
7971 (_("%pB: relocation %s against `%s' can not be used when making "
7973 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7974 (h
) ? h
->root
.root
.string
: "a local symbol");
7975 bfd_set_error (bfd_error_bad_value
);
7981 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
7982 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
7983 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
7984 case BFD_RELOC_AARCH64_MOVW_G3
:
7985 if (bfd_link_pic (info
))
7987 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7989 /* xgettext:c-format */
7990 (_("%pB: relocation %s against `%s' can not be used when making "
7991 "a shared object; recompile with -fPIC"),
7992 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7993 (h
) ? h
->root
.root
.string
: "a local symbol");
7994 bfd_set_error (bfd_error_bad_value
);
7999 case BFD_RELOC_AARCH64_16_PCREL
:
8000 case BFD_RELOC_AARCH64_32_PCREL
:
8001 case BFD_RELOC_AARCH64_64_PCREL
:
8002 case BFD_RELOC_AARCH64_ADD_LO12
:
8003 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
8004 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
8005 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
8006 case BFD_RELOC_AARCH64_LDST128_LO12
:
8007 case BFD_RELOC_AARCH64_LDST16_LO12
:
8008 case BFD_RELOC_AARCH64_LDST32_LO12
:
8009 case BFD_RELOC_AARCH64_LDST64_LO12
:
8010 case BFD_RELOC_AARCH64_LDST8_LO12
:
8011 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
8012 if (h
== NULL
|| bfd_link_pic (info
))
8016 case BFD_RELOC_AARCH64_NN
:
8018 /* We don't need to handle relocs into sections not going into
8019 the "real" output. */
8020 if ((sec
->flags
& SEC_ALLOC
) == 0)
8025 if (!bfd_link_pic (info
))
8028 h
->plt
.refcount
+= 1;
8029 h
->pointer_equality_needed
= 1;
8032 /* No need to do anything if we're not creating a shared
8034 if (!(bfd_link_pic (info
)
8035 /* If on the other hand, we are creating an executable, we
8036 may need to keep relocations for symbols satisfied by a
8037 dynamic library if we manage to avoid copy relocs for the
8040 NOTE: Currently, there is no support of copy relocs
8041 elimination on pc-relative relocation types, because there is
8042 no dynamic relocation support for them in glibc. We still
8043 record the dynamic symbol reference for them. This is
8044 because one symbol may be referenced by both absolute
8045 relocation (for example, BFD_RELOC_AARCH64_NN) and
8046 pc-relative relocation. We need full symbol reference
8047 information to make correct decision later in
8048 elfNN_aarch64_adjust_dynamic_symbol. */
8049 || (ELIMINATE_COPY_RELOCS
8050 && !bfd_link_pic (info
)
8052 && (h
->root
.type
== bfd_link_hash_defweak
8053 || !h
->def_regular
))))
8057 struct elf_dyn_relocs
*p
;
8058 struct elf_dyn_relocs
**head
;
8059 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
8061 /* We must copy these reloc types into the output file.
8062 Create a reloc section in dynobj and make room for
8066 if (htab
->root
.dynobj
== NULL
)
8067 htab
->root
.dynobj
= abfd
;
8069 sreloc
= _bfd_elf_make_dynamic_reloc_section
8070 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ true);
8076 /* If this is a global symbol, we count the number of
8077 relocations we need for this symbol. */
8080 head
= &h
->dyn_relocs
;
8084 /* Track dynamic relocs needed for local syms too.
8085 We really need local syms available to do this
8091 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
8096 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
8100 /* Beware of type punned pointers vs strict aliasing
8102 vpp
= &(elf_section_data (s
)->local_dynrel
);
8103 head
= (struct elf_dyn_relocs
**) vpp
;
8107 if (p
== NULL
|| p
->sec
!= sec
)
8109 size_t amt
= sizeof *p
;
8110 p
= ((struct elf_dyn_relocs
*)
8111 bfd_zalloc (htab
->root
.dynobj
, amt
));
8121 if (elfNN_aarch64_howto_table
[howto_index
].pc_relative
)
8126 /* RR: We probably want to keep a consistency check that
8127 there are no dangling GOT_PAGE relocs. */
8128 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
8129 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
8130 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
8131 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
8132 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
8133 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
8134 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
8135 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
8136 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
8137 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
8138 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
8139 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
8140 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
8141 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
8142 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
8143 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
8144 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
8145 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
8146 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
8147 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
8148 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
8149 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
8150 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
8151 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
8152 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
8153 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
8154 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
8155 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
8156 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
8157 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
8158 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
8161 unsigned old_got_type
;
8163 got_type
= aarch64_reloc_got_type (bfd_r_type
);
8167 h
->got
.refcount
+= 1;
8168 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
8172 struct elf_aarch64_local_symbol
*locals
;
8174 if (!elfNN_aarch64_allocate_local_symbols
8175 (abfd
, symtab_hdr
->sh_info
))
8178 locals
= elf_aarch64_locals (abfd
);
8179 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
8180 locals
[r_symndx
].got_refcount
+= 1;
8181 old_got_type
= locals
[r_symndx
].got_type
;
8184 /* If a variable is accessed with both general dynamic TLS
8185 methods, two slots may be created. */
8186 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
8187 got_type
|= old_got_type
;
8189 /* We will already have issued an error message if there
8190 is a TLS/non-TLS mismatch, based on the symbol type.
8191 So just combine any TLS types needed. */
8192 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
8193 && got_type
!= GOT_NORMAL
)
8194 got_type
|= old_got_type
;
8196 /* If the symbol is accessed by both IE and GD methods, we
8197 are able to relax. Turn off the GD flag, without
8198 messing up with any other kind of TLS types that may be
8200 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
8201 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
8203 if (old_got_type
!= got_type
)
8206 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
8209 struct elf_aarch64_local_symbol
*locals
;
8210 locals
= elf_aarch64_locals (abfd
);
8211 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
8212 locals
[r_symndx
].got_type
= got_type
;
8216 if (htab
->root
.dynobj
== NULL
)
8217 htab
->root
.dynobj
= abfd
;
8218 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
8223 case BFD_RELOC_AARCH64_CALL26
:
8224 case BFD_RELOC_AARCH64_JUMP26
:
8225 /* If this is a local symbol then we resolve it
8226 directly without creating a PLT entry. */
8231 if (h
->plt
.refcount
<= 0)
8232 h
->plt
.refcount
= 1;
8234 h
->plt
.refcount
+= 1;
8245 /* Treat mapping symbols as special target symbols. */
8248 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
8251 return bfd_is_aarch64_special_symbol_name (sym
->name
,
8252 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
8255 /* If the ELF symbol SYM might be a function in SEC, return the
8256 function size and set *CODE_OFF to the function's entry point,
8257 otherwise return zero. */
8259 static bfd_size_type
8260 elfNN_aarch64_maybe_function_sym (const asymbol
*sym
, asection
*sec
,
8264 elf_symbol_type
* elf_sym
= (elf_symbol_type
*) sym
;
8266 if ((sym
->flags
& (BSF_SECTION_SYM
| BSF_FILE
| BSF_OBJECT
8267 | BSF_THREAD_LOCAL
| BSF_RELC
| BSF_SRELC
)) != 0
8268 || sym
->section
!= sec
)
8271 size
= (sym
->flags
& BSF_SYNTHETIC
) ? 0 : elf_sym
->internal_elf_sym
.st_size
;
8273 if (!(sym
->flags
& BSF_SYNTHETIC
))
8274 switch (ELF_ST_TYPE (elf_sym
->internal_elf_sym
.st_info
))
8277 /* Ignore symbols created by the annobin plugin for gcc and clang.
8278 These symbols are hidden, local, notype and have a size of 0. */
8280 && sym
->flags
& BSF_LOCAL
8281 && ELF_ST_VISIBILITY (elf_sym
->internal_elf_sym
.st_other
) == STV_HIDDEN
)
8285 /* FIXME: Allow STT_GNU_IFUNC as well ? */
8291 if ((sym
->flags
& BSF_LOCAL
)
8292 && bfd_is_aarch64_special_symbol_name (sym
->name
,
8293 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
))
8296 *code_off
= sym
->value
;
8298 /* Do not return 0 for the function's size. */
8299 return size
? size
: 1;
8303 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
8304 const char **filename_ptr
,
8305 const char **functionname_ptr
,
8306 unsigned int *line_ptr
)
8309 found
= _bfd_dwarf2_find_inliner_info
8310 (abfd
, filename_ptr
,
8311 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
8317 elfNN_aarch64_init_file_header (bfd
*abfd
, struct bfd_link_info
*link_info
)
8319 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
8321 if (!_bfd_elf_init_file_header (abfd
, link_info
))
8324 i_ehdrp
= elf_elfheader (abfd
);
8325 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
8329 static enum elf_reloc_type_class
8330 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
8331 const asection
*rel_sec ATTRIBUTE_UNUSED
,
8332 const Elf_Internal_Rela
*rela
)
8334 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
8336 if (htab
->root
.dynsym
!= NULL
8337 && htab
->root
.dynsym
->contents
!= NULL
)
8339 /* Check relocation against STT_GNU_IFUNC symbol if there are
8341 bfd
*abfd
= info
->output_bfd
;
8342 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
8343 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
8344 if (r_symndx
!= STN_UNDEF
)
8346 Elf_Internal_Sym sym
;
8347 if (!bed
->s
->swap_symbol_in (abfd
,
8348 (htab
->root
.dynsym
->contents
8349 + r_symndx
* bed
->s
->sizeof_sym
),
8352 /* xgettext:c-format */
8353 _bfd_error_handler (_("%pB symbol number %lu references"
8354 " nonexistent SHT_SYMTAB_SHNDX section"),
8356 /* Ideally an error class should be returned here. */
8358 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
8359 return reloc_class_ifunc
;
8363 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
8365 case AARCH64_R (IRELATIVE
):
8366 return reloc_class_ifunc
;
8367 case AARCH64_R (RELATIVE
):
8368 return reloc_class_relative
;
8369 case AARCH64_R (JUMP_SLOT
):
8370 return reloc_class_plt
;
8371 case AARCH64_R (COPY
):
8372 return reloc_class_copy
;
8374 return reloc_class_normal
;
8378 /* Handle an AArch64 specific section when reading an object file. This is
8379 called when bfd_section_from_shdr finds a section with an unknown
8383 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
8384 Elf_Internal_Shdr
*hdr
,
8385 const char *name
, int shindex
)
8387 /* There ought to be a place to keep ELF backend specific flags, but
8388 at the moment there isn't one. We just keep track of the
8389 sections by their name, instead. Fortunately, the ABI gives
8390 names for all the AArch64 specific sections, so we will probably get
8392 switch (hdr
->sh_type
)
8394 case SHT_AARCH64_ATTRIBUTES
:
8401 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
8407 /* Process any AArch64-specific program segment types. */
8410 elfNN_aarch64_section_from_phdr (bfd
*abfd ATTRIBUTE_UNUSED
,
8411 Elf_Internal_Phdr
*hdr
,
8412 int hdr_index ATTRIBUTE_UNUSED
,
8413 const char *name ATTRIBUTE_UNUSED
)
8415 /* Right now we only handle the PT_AARCH64_MEMTAG_MTE segment type. */
8416 if (hdr
== NULL
|| hdr
->p_type
!= PT_AARCH64_MEMTAG_MTE
)
8419 if (hdr
->p_filesz
> 0)
8421 /* Sections created from memory tag p_type's are always named
8422 "memtag". This makes it easier for tools (for example, GDB)
8424 asection
*newsect
= bfd_make_section_anyway (abfd
, "memtag");
8426 if (newsect
== NULL
)
8429 unsigned int opb
= bfd_octets_per_byte (abfd
, NULL
);
8431 /* p_vaddr holds the original start address of the tagged memory
8433 newsect
->vma
= hdr
->p_vaddr
/ opb
;
8435 /* p_filesz holds the storage size of the packed tags. */
8436 newsect
->size
= hdr
->p_filesz
;
8437 newsect
->filepos
= hdr
->p_offset
;
8439 /* p_memsz holds the size of the memory range that contains tags. The
8440 section's rawsize field is reused for this purpose. */
8441 newsect
->rawsize
= hdr
->p_memsz
;
8443 /* Make sure the section's flags has SEC_HAS_CONTENTS set, otherwise
8444 BFD will return all zeroes when attempting to get contents from this
8446 newsect
->flags
|= SEC_HAS_CONTENTS
;
8452 /* Implements the bfd_elf_modify_headers hook for aarch64. */
8455 elfNN_aarch64_modify_headers (bfd
*abfd
,
8456 struct bfd_link_info
*info
)
8458 struct elf_segment_map
*m
;
8459 unsigned int segment_count
= 0;
8460 Elf_Internal_Phdr
*p
;
8462 for (m
= elf_seg_map (abfd
); m
!= NULL
; m
= m
->next
, segment_count
++)
8464 /* We are only interested in the memory tag segment that will be dumped
8465 to a core file. If we have no memory tags or this isn't a core file we
8466 are dealing with, just skip this segment. */
8467 if (m
->p_type
!= PT_AARCH64_MEMTAG_MTE
8468 || bfd_get_format (abfd
) != bfd_core
)
8471 /* For memory tag segments in core files, the size of the file contents
8472 is smaller than the size of the memory range. Adjust the memory size
8473 accordingly. The real memory size is held in the section's rawsize
8477 p
= elf_tdata (abfd
)->phdr
;
8479 p
->p_memsz
= m
->sections
[0]->rawsize
;
8486 /* Give the generic code a chance to handle the headers. */
8487 return _bfd_elf_modify_headers (abfd
, info
);
8494 struct bfd_link_info
*info
;
8497 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
8498 asection
*, struct elf_link_hash_entry
*);
8499 } output_arch_syminfo
;
8501 enum map_symbol_type
8508 /* Output a single mapping symbol. */
8511 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
8512 enum map_symbol_type type
, bfd_vma offset
)
8514 static const char *names
[2] = { "$x", "$d" };
8515 Elf_Internal_Sym sym
;
8517 sym
.st_value
= (osi
->sec
->output_section
->vma
8518 + osi
->sec
->output_offset
+ offset
);
8521 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
8522 sym
.st_shndx
= osi
->sec_shndx
;
8523 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
8526 /* Output a single local symbol for a generated stub. */
8529 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
8530 bfd_vma offset
, bfd_vma size
)
8532 Elf_Internal_Sym sym
;
8534 sym
.st_value
= (osi
->sec
->output_section
->vma
8535 + osi
->sec
->output_offset
+ offset
);
8538 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
8539 sym
.st_shndx
= osi
->sec_shndx
;
8540 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
8544 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
8546 struct elf_aarch64_stub_hash_entry
*stub_entry
;
8550 output_arch_syminfo
*osi
;
8552 /* Massage our args to the form they really have. */
8553 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
8554 osi
= (output_arch_syminfo
*) in_arg
;
8556 stub_sec
= stub_entry
->stub_sec
;
8558 /* Ensure this stub is attached to the current section being
8560 if (stub_sec
!= osi
->sec
)
8563 addr
= (bfd_vma
) stub_entry
->stub_offset
;
8565 stub_name
= stub_entry
->output_name
;
8567 switch (stub_entry
->stub_type
)
8569 case aarch64_stub_adrp_branch
:
8570 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
8571 sizeof (aarch64_adrp_branch_stub
)))
8573 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
8576 case aarch64_stub_long_branch
:
8577 if (!elfNN_aarch64_output_stub_sym
8578 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
8580 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
8582 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
8585 case aarch64_stub_bti_direct_branch
:
8586 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
8587 sizeof (aarch64_bti_direct_branch_stub
)))
8589 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
8592 case aarch64_stub_erratum_835769_veneer
:
8593 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
8594 sizeof (aarch64_erratum_835769_stub
)))
8596 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
8599 case aarch64_stub_erratum_843419_veneer
:
8600 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
8601 sizeof (aarch64_erratum_843419_stub
)))
8603 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
8606 case aarch64_stub_none
:
8616 /* Output mapping symbols for linker generated sections. */
8619 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
8620 struct bfd_link_info
*info
,
8622 int (*func
) (void *, const char *,
8625 struct elf_link_hash_entry
8628 output_arch_syminfo osi
;
8629 struct elf_aarch64_link_hash_table
*htab
;
8631 if (info
->strip
== strip_all
8632 && !info
->emitrelocations
8633 && !bfd_link_relocatable (info
))
8636 htab
= elf_aarch64_hash_table (info
);
8642 /* Long calls stubs. */
8643 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
8647 for (stub_sec
= htab
->stub_bfd
->sections
;
8648 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
8650 /* Ignore non-stub sections. */
8651 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
8656 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
8657 (output_bfd
, osi
.sec
->output_section
);
8659 /* The first instruction in a stub is always a branch. */
8660 if (!elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0))
8663 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
8668 /* Finally, output mapping symbols for the PLT. */
8669 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
8672 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
8673 (output_bfd
, htab
->root
.splt
->output_section
);
8674 osi
.sec
= htab
->root
.splt
;
8676 elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0);
8682 /* Allocate target specific section data. */
8685 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
8687 _aarch64_elf_section_data
*sdata
;
8689 sdata
= bfd_zalloc (abfd
, sizeof (*sdata
));
8692 sec
->used_by_bfd
= sdata
;
8694 return _bfd_elf_new_section_hook (abfd
, sec
);
8698 /* Create dynamic sections. This is different from the ARM backend in that
8699 the got, plt, gotplt and their relocation sections are all created in the
8700 standard part of the bfd elf backend. */
8703 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
8704 struct bfd_link_info
*info
)
8706 /* We need to create .got section. */
8707 if (!aarch64_elf_create_got_section (dynobj
, info
))
8710 return _bfd_elf_create_dynamic_sections (dynobj
, info
);
8714 /* Allocate space in .plt, .got and associated reloc sections for
8718 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
8720 struct bfd_link_info
*info
;
8721 struct elf_aarch64_link_hash_table
*htab
;
8722 struct elf_aarch64_link_hash_entry
*eh
;
8723 struct elf_dyn_relocs
*p
;
8725 /* An example of a bfd_link_hash_indirect symbol is versioned
8726 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
8727 -> __gxx_personality_v0(bfd_link_hash_defined)
8729 There is no need to process bfd_link_hash_indirect symbols here
8730 because we will also be presented with the concrete instance of
8731 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
8732 called to copy all relevant data from the generic to the concrete
8734 if (h
->root
.type
== bfd_link_hash_indirect
)
8737 if (h
->root
.type
== bfd_link_hash_warning
)
8738 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
8740 info
= (struct bfd_link_info
*) inf
;
8741 htab
= elf_aarch64_hash_table (info
);
8743 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
8744 here if it is defined and referenced in a non-shared object. */
8745 if (h
->type
== STT_GNU_IFUNC
8748 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
8750 /* Make sure this symbol is output as a dynamic symbol.
8751 Undefined weak syms won't yet be marked as dynamic. */
8752 if (h
->dynindx
== -1 && !h
->forced_local
8753 && h
->root
.type
== bfd_link_hash_undefweak
)
8755 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
8759 if (bfd_link_pic (info
) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
8761 asection
*s
= htab
->root
.splt
;
8763 /* If this is the first .plt entry, make room for the special
8766 s
->size
+= htab
->plt_header_size
;
8768 h
->plt
.offset
= s
->size
;
8770 /* If this symbol is not defined in a regular file, and we are
8771 not generating a shared library, then set the symbol to this
8772 location in the .plt. This is required to make function
8773 pointers compare as equal between the normal executable and
8774 the shared library. */
8775 if (!bfd_link_pic (info
) && !h
->def_regular
)
8777 h
->root
.u
.def
.section
= s
;
8778 h
->root
.u
.def
.value
= h
->plt
.offset
;
8781 /* Make room for this entry. For now we only create the
8782 small model PLT entries. We later need to find a way
8783 of relaxing into these from the large model PLT entries. */
8784 s
->size
+= htab
->plt_entry_size
;
8786 /* We also need to make an entry in the .got.plt section, which
8787 will be placed in the .got section by the linker script. */
8788 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
;
8790 /* We also need to make an entry in the .rela.plt section. */
8791 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
8793 /* We need to ensure that all GOT entries that serve the PLT
8794 are consecutive with the special GOT slots [0] [1] and
8795 [2]. Any addtional relocations, such as
8796 R_AARCH64_TLSDESC, must be placed after the PLT related
8797 entries. We abuse the reloc_count such that during
8798 sizing we adjust reloc_count to indicate the number of
8799 PLT related reserved entries. In subsequent phases when
8800 filling in the contents of the reloc entries, PLT related
8801 entries are placed by computing their PLT index (0
8802 .. reloc_count). While other none PLT relocs are placed
8803 at the slot indicated by reloc_count and reloc_count is
8806 htab
->root
.srelplt
->reloc_count
++;
8808 /* Mark the DSO in case R_<CLS>_JUMP_SLOT relocs against
8809 variant PCS symbols are present. */
8810 if (h
->other
& STO_AARCH64_VARIANT_PCS
)
8811 htab
->variant_pcs
= 1;
8816 h
->plt
.offset
= (bfd_vma
) - 1;
8822 h
->plt
.offset
= (bfd_vma
) - 1;
8826 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
8827 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
8829 if (h
->got
.refcount
> 0)
8832 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
8834 h
->got
.offset
= (bfd_vma
) - 1;
8836 dyn
= htab
->root
.dynamic_sections_created
;
8838 /* Make sure this symbol is output as a dynamic symbol.
8839 Undefined weak syms won't yet be marked as dynamic. */
8840 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
8841 && h
->root
.type
== bfd_link_hash_undefweak
)
8843 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
8847 if (got_type
== GOT_UNKNOWN
)
8850 else if (got_type
== GOT_NORMAL
)
8852 h
->got
.offset
= htab
->root
.sgot
->size
;
8853 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
8854 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8855 || h
->root
.type
!= bfd_link_hash_undefweak
)
8856 && (bfd_link_pic (info
)
8857 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
))
8858 /* Undefined weak symbol in static PIE resolves to 0 without
8859 any dynamic relocations. */
8860 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
8862 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
8868 if (got_type
& GOT_TLSDESC_GD
)
8870 eh
->tlsdesc_got_jump_table_offset
=
8871 (htab
->root
.sgotplt
->size
8872 - aarch64_compute_jump_table_size (htab
));
8873 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
8874 h
->got
.offset
= (bfd_vma
) - 2;
8877 if (got_type
& GOT_TLS_GD
)
8879 h
->got
.offset
= htab
->root
.sgot
->size
;
8880 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
8883 if (got_type
& GOT_TLS_IE
)
8885 h
->got
.offset
= htab
->root
.sgot
->size
;
8886 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
8889 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8890 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8891 || h
->root
.type
!= bfd_link_hash_undefweak
)
8892 && (!bfd_link_executable (info
)
8894 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)))
8896 if (got_type
& GOT_TLSDESC_GD
)
8898 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
8899 /* Note reloc_count not incremented here! We have
8900 already adjusted reloc_count for this relocation
8903 /* TLSDESC PLT is now needed, but not yet determined. */
8904 htab
->root
.tlsdesc_plt
= (bfd_vma
) - 1;
8907 if (got_type
& GOT_TLS_GD
)
8908 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
8910 if (got_type
& GOT_TLS_IE
)
8911 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
8917 h
->got
.offset
= (bfd_vma
) - 1;
8920 if (h
->dyn_relocs
== NULL
)
8923 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
8924 if (eh
->def_protected
)
8926 /* Disallow copy relocations against protected symbol. */
8927 asection
*s
= p
->sec
->output_section
;
8928 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
8930 info
->callbacks
->einfo
8931 /* xgettext:c-format */
8932 (_ ("%F%P: %pB: copy relocation against non-copyable "
8933 "protected symbol `%s'\n"),
8934 p
->sec
->owner
, h
->root
.root
.string
);
8939 /* In the shared -Bsymbolic case, discard space allocated for
8940 dynamic pc-relative relocs against symbols which turn out to be
8941 defined in regular objects. For the normal shared case, discard
8942 space for pc-relative relocs that have become local due to symbol
8943 visibility changes. */
8945 if (bfd_link_pic (info
))
8947 /* Relocs that use pc_count are those that appear on a call
8948 insn, or certain REL relocs that can generated via assembly.
8949 We want calls to protected symbols to resolve directly to the
8950 function rather than going via the plt. If people want
8951 function pointer comparisons to work as expected then they
8952 should avoid writing weird assembly. */
8953 if (SYMBOL_CALLS_LOCAL (info
, h
))
8955 struct elf_dyn_relocs
**pp
;
8957 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
8959 p
->count
-= p
->pc_count
;
8968 /* Also discard relocs on undefined weak syms with non-default
8970 if (h
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
8972 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
8973 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
8974 h
->dyn_relocs
= NULL
;
8976 /* Make sure undefined weak symbols are output as a dynamic
8978 else if (h
->dynindx
== -1
8980 && h
->root
.type
== bfd_link_hash_undefweak
8981 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
8986 else if (ELIMINATE_COPY_RELOCS
)
8988 /* For the non-shared case, discard space for relocs against
8989 symbols which turn out to need copy relocs or are not
8995 || (htab
->root
.dynamic_sections_created
8996 && (h
->root
.type
== bfd_link_hash_undefweak
8997 || h
->root
.type
== bfd_link_hash_undefined
))))
8999 /* Make sure this symbol is output as a dynamic symbol.
9000 Undefined weak syms won't yet be marked as dynamic. */
9001 if (h
->dynindx
== -1
9003 && h
->root
.type
== bfd_link_hash_undefweak
9004 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
9007 /* If that succeeded, we know we'll be keeping all the
9009 if (h
->dynindx
!= -1)
9013 h
->dyn_relocs
= NULL
;
9018 /* Finally, allocate space. */
9019 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
9023 sreloc
= elf_section_data (p
->sec
)->sreloc
;
9025 BFD_ASSERT (sreloc
!= NULL
);
9027 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
9033 /* Allocate space in .plt, .got and associated reloc sections for
9034 ifunc dynamic relocs. */
9037 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
9040 struct bfd_link_info
*info
;
9041 struct elf_aarch64_link_hash_table
*htab
;
9043 /* An example of a bfd_link_hash_indirect symbol is versioned
9044 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
9045 -> __gxx_personality_v0(bfd_link_hash_defined)
9047 There is no need to process bfd_link_hash_indirect symbols here
9048 because we will also be presented with the concrete instance of
9049 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
9050 called to copy all relevant data from the generic to the concrete
9052 if (h
->root
.type
== bfd_link_hash_indirect
)
9055 if (h
->root
.type
== bfd_link_hash_warning
)
9056 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
9058 info
= (struct bfd_link_info
*) inf
;
9059 htab
= elf_aarch64_hash_table (info
);
9061 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
9062 here if it is defined and referenced in a non-shared object. */
9063 if (h
->type
== STT_GNU_IFUNC
9065 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
9067 htab
->plt_entry_size
,
9068 htab
->plt_header_size
,
9074 /* Allocate space in .plt, .got and associated reloc sections for
9075 local ifunc dynamic relocs. */
9078 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
9080 struct elf_link_hash_entry
*h
9081 = (struct elf_link_hash_entry
*) *slot
;
9083 if (h
->type
!= STT_GNU_IFUNC
9087 || h
->root
.type
!= bfd_link_hash_defined
)
9090 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
9093 /* Record a relative relocation that will be emitted packed (DT_RELR).
9094 Called after relocation sections are sized, so undo the size accounting
9095 for this relocation. */
9098 record_relr (struct elf_aarch64_link_hash_table
*htab
, asection
*sec
,
9099 bfd_vma off
, asection
*sreloc
)
9101 /* Undo the relocation section size accounting. */
9102 BFD_ASSERT (sreloc
->size
>= RELOC_SIZE (htab
));
9103 sreloc
->size
-= RELOC_SIZE (htab
);
9104 /* The packing format uses the last bit of the address so that
9105 must be aligned. We don't pack relocations that may not be
9106 aligned even though the final output address could end up
9107 aligned, to avoid complex sizing logic for a rare case. */
9108 BFD_ASSERT (off
% 2 == 0 && sec
->alignment_power
> 0);
9109 if (htab
->relr_count
>= htab
->relr_alloc
)
9111 if (htab
->relr_alloc
== 0)
9112 htab
->relr_alloc
= 4096;
9114 htab
->relr_alloc
*= 2;
9115 htab
->relr
= bfd_realloc (htab
->relr
,
9116 htab
->relr_alloc
* sizeof (*htab
->relr
));
9117 if (htab
->relr
== NULL
)
9120 htab
->relr
[htab
->relr_count
].sec
= sec
;
9121 htab
->relr
[htab
->relr_count
].off
= off
;
9126 /* Follow elfNN_aarch64_allocate_dynrelocs, but only record relative
9127 relocations against the GOT and undo their previous size accounting. */
9130 record_relr_dyn_got_relocs (struct elf_link_hash_entry
*h
, void *inf
)
9133 if (h
->root
.type
== bfd_link_hash_indirect
)
9135 if (h
->root
.type
== bfd_link_hash_warning
)
9136 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
9137 if (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
9139 if (h
->got
.refcount
<= 0)
9141 if (elf_aarch64_hash_entry (h
)->got_type
!= GOT_NORMAL
)
9144 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
9145 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
9147 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
9148 || h
->root
.type
!= bfd_link_hash_undefweak
)
9149 && bfd_link_pic (info
)
9150 /* Undefined weak symbol in static PIE resolves to 0 without
9151 any dynamic relocations. */
9152 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
9154 bool relative_reloc
= SYMBOL_REFERENCES_LOCAL (info
, h
)
9155 && !bfd_is_abs_symbol (&h
->root
);
9157 if (!record_relr (htab
, htab
->root
.sgot
, h
->got
.offset
,
9158 htab
->root
.srelgot
))
9164 /* Record packed relative relocs against the GOT for local symbols.
9165 Undo the size accounting of elfNN_aarch64_late_size_sections. */
9168 record_relr_local_got_relocs (bfd
*input_bfd
, struct bfd_link_info
*info
)
9170 struct elf_aarch64_local_symbol
*locals
;
9171 Elf_Internal_Shdr
*symtab_hdr
;
9172 struct elf_aarch64_link_hash_table
*htab
;
9174 if (!bfd_link_pic (info
))
9177 locals
= elf_aarch64_locals (input_bfd
);
9181 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
9182 htab
= elf_aarch64_hash_table (info
);
9183 for (unsigned int i
= 0; i
< symtab_hdr
->sh_info
; i
++)
9185 bfd_vma off
= locals
[i
].got_offset
;
9186 if (locals
[i
].got_refcount
<= 0)
9188 if ((locals
[i
].got_type
& GOT_NORMAL
) == 0)
9191 /* FIXME: If the local symbol is in SHN_ABS then emitting
9192 a relative relocation is not correct, but it seems to
9193 be wrong in elfNN_aarch64_final_link_relocate too. */
9194 if (!record_relr (htab
, htab
->root
.sgot
, off
, htab
->root
.srelgot
))
9200 /* Follows the logic of elfNN_aarch64_relocate_section to decide which
9201 relocations will become relative and possible to pack. Ignore
9202 relocations against the GOT, those are handled separately per-symbol.
9203 Undo the size accounting of the packed relocations and record them
9204 so the relr section can be sized later. */
9207 record_relr_non_got_relocs (bfd
*input_bfd
, struct bfd_link_info
*info
,
9210 const Elf_Internal_Rela
*relocs
;
9211 const Elf_Internal_Rela
*rel
;
9212 const Elf_Internal_Rela
*rel_end
;
9214 struct elf_aarch64_link_hash_table
*htab
;
9215 Elf_Internal_Shdr
*symtab_hdr
;
9216 struct elf_link_hash_entry
**sym_hashes
;
9218 if (sec
->reloc_count
== 0)
9220 if ((sec
->flags
& (SEC_RELOC
| SEC_ALLOC
| SEC_DEBUGGING
))
9221 != (SEC_RELOC
| SEC_ALLOC
))
9223 if (sec
->alignment_power
== 0)
9225 if (discarded_section (sec
))
9227 sreloc
= elf_section_data (sec
)->sreloc
;
9230 htab
= elf_aarch64_hash_table (info
);
9231 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
9232 sym_hashes
= elf_sym_hashes (input_bfd
);
9233 relocs
= _bfd_elf_link_info_read_relocs (input_bfd
, info
, sec
, NULL
, NULL
,
9235 BFD_ASSERT (relocs
!= NULL
);
9236 rel_end
= relocs
+ sec
->reloc_count
;
9237 for (rel
= relocs
; rel
< rel_end
; rel
++)
9239 unsigned int r_symndx
= ELFNN_R_SYM (rel
->r_info
);
9240 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
9242 bfd_reloc_code_real_type bfd_r_type
9243 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
9244 /* Handle relocs that can become R_AARCH64_RELATIVE,
9245 but not ones against the GOT as those are handled
9246 separately per-symbol. */
9247 if (bfd_r_type
!= BFD_RELOC_AARCH64_NN
)
9249 /* Can only pack relocation against an aligned address. */
9250 if (rel
->r_offset
% 2 != 0)
9253 struct elf_link_hash_entry
*h
= NULL
;
9254 asection
*def_sec
= NULL
;
9255 bool resolved_to_zero
= false;
9256 if (r_symndx
< symtab_hdr
->sh_info
)
9258 /* A local symbol. */
9259 Elf_Internal_Sym
*isym
;
9260 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
9261 input_bfd
, r_symndx
);
9262 BFD_ASSERT (isym
!= NULL
);
9263 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
9265 def_sec
= bfd_section_from_elf_index (input_bfd
, isym
->st_shndx
);
9269 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
9270 while (h
->root
.type
== bfd_link_hash_indirect
9271 || h
->root
.type
== bfd_link_hash_warning
)
9272 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
9274 /* Filter out symbols that cannot have a relative reloc. */
9275 if (h
->dyn_relocs
== NULL
)
9277 if (bfd_is_abs_symbol (&h
->root
))
9279 if (h
->type
== STT_GNU_IFUNC
)
9282 if (h
->root
.type
== bfd_link_hash_defined
9283 || h
->root
.type
== bfd_link_hash_defweak
)
9284 def_sec
= h
->root
.u
.def
.section
;
9285 resolved_to_zero
= UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
);
9287 if (def_sec
!= NULL
&& discarded_section (def_sec
))
9289 /* Same logic as in elfNN_aarch64_final_link_relocate.
9290 Except conditionals trimmed that cannot result a reltive reloc. */
9291 if (bfd_link_pic (info
)
9293 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
9294 && !resolved_to_zero
)
9295 || h
->root
.type
!= bfd_link_hash_undefweak
))
9299 && (!(bfd_link_pie (info
) || SYMBOLIC_BIND (info
, h
))
9300 || !h
->def_regular
))
9302 if (!record_relr (htab
, sec
, rel
->r_offset
, sreloc
))
9310 cmp_relr_addr (const void *p
, const void *q
)
9312 const bfd_vma
*a
= p
;
9313 const bfd_vma
*b
= q
;
9314 return *a
< *b
? -1 : *a
> *b
? 1 : 0;
9317 /* Produce a malloc'd sorted array of reloc addresses in htab->relr_sorted.
9318 Returns false on allocation failure. */
9321 sort_relr (struct bfd_link_info
*info
,
9322 struct elf_aarch64_link_hash_table
*htab
)
9324 if (htab
->relr_count
== 0)
9327 bfd_vma
*addr
= htab
->relr_sorted
;
9330 addr
= bfd_malloc (htab
->relr_count
* sizeof (*addr
));
9333 htab
->relr_sorted
= addr
;
9336 for (bfd_size_type i
= 0; i
< htab
->relr_count
; i
++)
9338 bfd_vma off
= _bfd_elf_section_offset (info
->output_bfd
, info
,
9341 addr
[i
] = htab
->relr
[i
].sec
->output_section
->vma
9342 + htab
->relr
[i
].sec
->output_offset
9345 qsort (addr
, htab
->relr_count
, sizeof (*addr
), cmp_relr_addr
);
9349 /* Size of a relr entry and a relocated location. */
9350 #define RELR_SZ (ARCH_SIZE / 8)
9351 /* Number of consecutive locations a relr bitmap entry references. */
9352 #define RELR_N (ARCH_SIZE - 1)
9354 /* Size .relr.dyn whenever the layout changes, the number of packed
9355 relocs are unchanged but the packed representation can. */
9358 elfNN_aarch64_size_relative_relocs (struct bfd_link_info
*info
,
9361 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
9362 asection
*srelrdyn
= htab
->root
.srelrdyn
;
9363 *need_layout
= false;
9365 if (!sort_relr (info
, htab
))
9367 bfd_vma
*addr
= htab
->relr_sorted
;
9369 BFD_ASSERT (srelrdyn
!= NULL
);
9370 bfd_size_type oldsize
= srelrdyn
->size
;
9372 for (bfd_size_type i
= 0; i
< htab
->relr_count
; )
9374 bfd_vma base
= addr
[i
];
9376 srelrdyn
->size
+= RELR_SZ
;
9380 bfd_size_type start_i
= i
;
9381 while (i
< htab
->relr_count
9382 && addr
[i
] - base
< RELR_N
* RELR_SZ
9383 && (addr
[i
] - base
) % RELR_SZ
== 0)
9387 srelrdyn
->size
+= RELR_SZ
;
9388 base
+= RELR_N
* RELR_SZ
;
9391 if (srelrdyn
->size
!= oldsize
)
9393 *need_layout
= true;
9394 /* Stop after a few iterations in case the layout does not converge,
9395 we can do this when the size would shrink. */
9396 if (htab
->relr_layout_iter
++ > 5 && srelrdyn
->size
< oldsize
)
9398 srelrdyn
->size
= oldsize
;
9399 *need_layout
= false;
9405 /* Emit the .relr.dyn section after it is sized and the layout is fixed. */
9408 elfNN_aarch64_finish_relative_relocs (struct bfd_link_info
*info
)
9410 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
9411 asection
*srelrdyn
= htab
->root
.srelrdyn
;
9412 bfd
*dynobj
= htab
->root
.dynobj
;
9414 if (srelrdyn
== NULL
|| srelrdyn
->size
== 0)
9416 srelrdyn
->contents
= bfd_alloc (dynobj
, srelrdyn
->size
);
9417 if (srelrdyn
->contents
== NULL
)
9419 srelrdyn
->alloced
= 1;
9420 bfd_vma
*addr
= htab
->relr_sorted
;
9421 bfd_byte
*loc
= srelrdyn
->contents
;
9422 for (bfd_size_type i
= 0; i
< htab
->relr_count
; )
9424 bfd_vma base
= addr
[i
];
9426 bfd_put_NN (dynobj
, base
, loc
);
9432 while (i
< htab
->relr_count
)
9434 bfd_vma delta
= addr
[i
] - base
;
9435 if (delta
>= RELR_N
* RELR_SZ
|| delta
% RELR_SZ
!= 0)
9437 bits
|= (bfd_vma
) 1 << (delta
/ RELR_SZ
);
9442 bfd_put_NN (dynobj
, (bits
<< 1) | 1, loc
);
9444 base
+= RELR_N
* RELR_SZ
;
9448 htab
->relr_sorted
= NULL
;
9449 /* Pad any excess with 1's, a do-nothing encoding. */
9450 while (loc
< srelrdyn
->contents
+ srelrdyn
->size
)
9452 bfd_put_NN (dynobj
, 1, loc
);
9458 /* This is the most important function of all . Innocuosly named
9462 elfNN_aarch64_late_size_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
9463 struct bfd_link_info
*info
)
9465 struct elf_aarch64_link_hash_table
*htab
;
9471 htab
= elf_aarch64_hash_table ((info
));
9472 dynobj
= htab
->root
.dynobj
;
9477 if (htab
->root
.dynamic_sections_created
)
9479 if (bfd_link_executable (info
) && !info
->nointerp
)
9481 s
= bfd_get_linker_section (dynobj
, ".interp");
9484 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
9485 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
9490 /* Set up .got offsets for local syms, and space for local dynamic
9492 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
9494 struct elf_aarch64_local_symbol
*locals
= NULL
;
9495 Elf_Internal_Shdr
*symtab_hdr
;
9499 if (!is_aarch64_elf (ibfd
))
9502 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
9504 struct elf_dyn_relocs
*p
;
9506 for (p
= (struct elf_dyn_relocs
*)
9507 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
9509 if (discarded_section (p
->sec
))
9511 /* Input section has been discarded, either because
9512 it is a copy of a linkonce section or due to
9513 linker script /DISCARD/, so we'll be discarding
9516 else if (p
->count
!= 0)
9518 srel
= elf_section_data (p
->sec
)->sreloc
;
9519 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
9520 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
9521 info
->flags
|= DF_TEXTREL
;
9526 locals
= elf_aarch64_locals (ibfd
);
9530 symtab_hdr
= &elf_symtab_hdr (ibfd
);
9531 srel
= htab
->root
.srelgot
;
9532 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
9534 locals
[i
].got_offset
= (bfd_vma
) - 1;
9535 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
9536 if (locals
[i
].got_refcount
> 0)
9538 unsigned got_type
= locals
[i
].got_type
;
9539 if (got_type
& GOT_TLSDESC_GD
)
9541 locals
[i
].tlsdesc_got_jump_table_offset
=
9542 (htab
->root
.sgotplt
->size
9543 - aarch64_compute_jump_table_size (htab
));
9544 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE
* 2;
9545 locals
[i
].got_offset
= (bfd_vma
) - 2;
9548 if (got_type
& GOT_TLS_GD
)
9550 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
9551 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
* 2;
9554 if (got_type
& GOT_TLS_IE
9555 || got_type
& GOT_NORMAL
)
9557 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
9558 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
9561 if (got_type
== GOT_UNKNOWN
)
9565 if (bfd_link_pic (info
))
9567 if (got_type
& GOT_TLSDESC_GD
)
9569 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
9570 /* Note RELOC_COUNT not incremented here! */
9571 htab
->root
.tlsdesc_plt
= (bfd_vma
) - 1;
9574 if (got_type
& GOT_TLS_GD
)
9575 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
9577 if (got_type
& GOT_TLS_IE
9578 || got_type
& GOT_NORMAL
)
9579 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
9584 locals
[i
].got_refcount
= (bfd_vma
) - 1;
9590 /* Allocate global sym .plt and .got entries, and space for global
9591 sym dynamic relocs. */
9592 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
9595 /* Allocate global ifunc sym .plt and .got entries, and space for global
9596 ifunc sym dynamic relocs. */
9597 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
9600 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
9601 htab_traverse (htab
->loc_hash_table
,
9602 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
9605 /* For every jump slot reserved in the sgotplt, reloc_count is
9606 incremented. However, when we reserve space for TLS descriptors,
9607 it's not incremented, so in order to compute the space reserved
9608 for them, it suffices to multiply the reloc count by the jump
9611 if (htab
->root
.srelplt
)
9612 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
9614 if (htab
->root
.tlsdesc_plt
)
9616 if (htab
->root
.splt
->size
== 0)
9617 htab
->root
.splt
->size
+= htab
->plt_header_size
;
9619 /* If we're not using lazy TLS relocations, don't generate the
9620 GOT and PLT entry required. */
9621 if ((info
->flags
& DF_BIND_NOW
))
9622 htab
->root
.tlsdesc_plt
= 0;
9625 htab
->root
.tlsdesc_plt
= htab
->root
.splt
->size
;
9626 htab
->root
.splt
->size
+= htab
->tlsdesc_plt_entry_size
;
9628 htab
->root
.tlsdesc_got
= htab
->root
.sgot
->size
;
9629 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE
;
9633 /* Record the relative relocations that will be packed and undo the
9634 size allocation for them in .rela.*. The size of .relr.dyn will be
9635 computed later iteratively since it depends on the final layout. */
9636 if (info
->enable_dt_relr
&& !bfd_link_relocatable (info
))
9638 elf_link_hash_traverse (&htab
->root
, record_relr_dyn_got_relocs
, info
);
9640 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
9642 if (!is_aarch64_elf (ibfd
))
9645 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
9646 if (!record_relr_non_got_relocs (ibfd
, info
, s
))
9649 if (!record_relr_local_got_relocs (ibfd
, info
))
9654 /* Init mapping symbols information to use later to distingush between
9655 code and data while scanning for errata. */
9656 if (htab
->fix_erratum_835769
|| htab
->fix_erratum_843419
)
9657 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
9659 if (!is_aarch64_elf (ibfd
))
9661 bfd_elfNN_aarch64_init_maps (ibfd
);
9664 /* We now have determined the sizes of the various dynamic sections.
9665 Allocate memory for them. */
9667 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
9669 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
9672 if (s
== htab
->root
.splt
9673 || s
== htab
->root
.sgot
9674 || s
== htab
->root
.sgotplt
9675 || s
== htab
->root
.iplt
9676 || s
== htab
->root
.igotplt
9677 || s
== htab
->root
.sdynbss
9678 || s
== htab
->root
.sdynrelro
)
9680 /* Strip this section if we don't need it; see the
9683 else if (startswith (bfd_section_name (s
), ".rela"))
9685 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
9688 /* We use the reloc_count field as a counter if we need
9689 to copy relocs into the output file. */
9690 if (s
!= htab
->root
.srelplt
)
9693 else if (s
== htab
->root
.srelrdyn
)
9695 /* Remove .relr.dyn based on relr_count, not size, since
9696 it is not sized yet. */
9697 if (htab
->relr_count
== 0)
9698 s
->flags
|= SEC_EXCLUDE
;
9700 /* Force dynamic tags for relocs even if there are no
9701 .rela* relocs, required for setting DT_TEXTREL. */
9703 /* Allocate contents later. */
9708 /* It's not one of our sections, so don't allocate space. */
9714 /* If we don't need this section, strip it from the
9715 output file. This is mostly to handle .rela.bss and
9716 .rela.plt. We must create both sections in
9717 create_dynamic_sections, because they must be created
9718 before the linker maps input sections to output
9719 sections. The linker does that before
9720 adjust_dynamic_symbol is called, and it is that
9721 function which decides whether anything needs to go
9722 into these sections. */
9723 s
->flags
|= SEC_EXCLUDE
;
9727 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
9730 /* Allocate memory for the section contents. We use bfd_zalloc
9731 here in case unused entries are not reclaimed before the
9732 section's contents are written out. This should not happen,
9733 but this way if it does, we get a R_AARCH64_NONE reloc instead
9735 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
9736 if (s
->contents
== NULL
)
9741 if (htab
->root
.dynamic_sections_created
)
9743 /* Add some entries to the .dynamic section. We fill in the
9744 values later, in elfNN_aarch64_finish_dynamic_sections, but we
9745 must add the entries now so that we get the correct size for
9746 the .dynamic section. The DT_DEBUG entry is filled in by the
9747 dynamic linker and used by the debugger. */
9748 #define add_dynamic_entry(TAG, VAL) \
9749 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
9751 if (!_bfd_elf_add_dynamic_tags (output_bfd
, info
, relocs
))
9754 if (htab
->root
.splt
->size
!= 0)
9756 if (htab
->variant_pcs
9757 && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS
, 0))
9760 aarch64_plt_type plt_type
9761 = elf_aarch64_tdata (output_bfd
)->sw_protections
.plt_type
;
9762 if ((plt_type
== PLT_BTI_PAC
)
9763 && (!add_dynamic_entry (DT_AARCH64_BTI_PLT
, 0)
9764 || !add_dynamic_entry (DT_AARCH64_PAC_PLT
, 0)))
9767 else if ((plt_type
== PLT_BTI
)
9768 && !add_dynamic_entry (DT_AARCH64_BTI_PLT
, 0))
9771 else if ((plt_type
== PLT_PAC
)
9772 && !add_dynamic_entry (DT_AARCH64_PAC_PLT
, 0))
9776 #undef add_dynamic_entry
9782 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
9783 bfd_reloc_code_real_type r_type
,
9784 bfd_byte
*plt_entry
, bfd_vma value
)
9786 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
9788 /* FIXME: We should check the return value from this function call. */
9789 (void) _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
9793 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
9794 struct elf_aarch64_link_hash_table
9795 *htab
, bfd
*output_bfd
,
9796 struct bfd_link_info
*info
)
9798 bfd_byte
*plt_entry
;
9801 bfd_vma gotplt_entry_address
;
9802 bfd_vma plt_entry_address
;
9803 Elf_Internal_Rela rela
;
9805 asection
*plt
, *gotplt
, *relplt
;
9807 /* When building a static executable, use .iplt, .igot.plt and
9808 .rela.iplt sections for STT_GNU_IFUNC symbols. */
9809 if (htab
->root
.splt
!= NULL
)
9811 plt
= htab
->root
.splt
;
9812 gotplt
= htab
->root
.sgotplt
;
9813 relplt
= htab
->root
.srelplt
;
9817 plt
= htab
->root
.iplt
;
9818 gotplt
= htab
->root
.igotplt
;
9819 relplt
= htab
->root
.irelplt
;
9822 /* Get the index in the procedure linkage table which
9823 corresponds to this symbol. This is the index of this symbol
9824 in all the symbols for which we are making plt entries. The
9825 first entry in the procedure linkage table is reserved.
9827 Get the offset into the .got table of the entry that
9828 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
9829 bytes. The first three are reserved for the dynamic linker.
9831 For static executables, we don't reserve anything. */
9833 if (plt
== htab
->root
.splt
)
9835 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
9836 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
9840 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
9841 got_offset
= plt_index
* GOT_ENTRY_SIZE
;
9844 plt_entry
= plt
->contents
+ h
->plt
.offset
;
9845 plt_entry_address
= plt
->output_section
->vma
9846 + plt
->output_offset
+ h
->plt
.offset
;
9847 gotplt_entry_address
= gotplt
->output_section
->vma
+
9848 gotplt
->output_offset
+ got_offset
;
9850 /* Copy in the boiler-plate for the PLTn entry. */
9851 memcpy (plt_entry
, htab
->plt_entry
, htab
->plt_entry_size
);
9853 /* Allow for any delta (such as a BTI instruction) before the common
9855 plt_entry
+= htab
->plt_entry_delta
;
9857 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
9858 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
9859 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
9861 PG (gotplt_entry_address
) -
9862 PG (plt_entry_address
));
9864 /* Fill in the lo12 bits for the load from the pltgot. */
9865 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
9867 PG_OFFSET (gotplt_entry_address
));
9869 /* Fill in the lo12 bits for the add from the pltgot entry. */
9870 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
9872 PG_OFFSET (gotplt_entry_address
));
9874 /* All the GOTPLT Entries are essentially initialized to PLT0. */
9875 bfd_put_NN (output_bfd
,
9876 plt
->output_section
->vma
+ plt
->output_offset
,
9877 gotplt
->contents
+ got_offset
);
9879 rela
.r_offset
= gotplt_entry_address
;
9881 if (h
->dynindx
== -1
9882 || ((bfd_link_executable (info
)
9883 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
9885 && h
->type
== STT_GNU_IFUNC
))
9887 /* If an STT_GNU_IFUNC symbol is locally defined, generate
9888 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
9889 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
));
9890 rela
.r_addend
= (h
->root
.u
.def
.value
9891 + h
->root
.u
.def
.section
->output_section
->vma
9892 + h
->root
.u
.def
.section
->output_offset
);
9896 /* Fill in the entry in the .rela.plt section. */
9897 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
));
9901 /* Compute the relocation entry to used based on PLT index and do
9902 not adjust reloc_count. The reloc_count has already been adjusted
9903 to account for this entry. */
9904 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
9905 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
9908 /* Size sections even though they're not dynamic. We use it to setup
9909 _TLS_MODULE_BASE_, if needed. */
9912 elfNN_aarch64_early_size_sections (bfd
*output_bfd
,
9913 struct bfd_link_info
*info
)
9917 if (bfd_link_relocatable (info
))
9920 tls_sec
= elf_hash_table (info
)->tls_sec
;
9924 struct elf_link_hash_entry
*tlsbase
;
9926 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
9927 "_TLS_MODULE_BASE_", true, true, false);
9931 struct bfd_link_hash_entry
*h
= NULL
;
9932 const struct elf_backend_data
*bed
=
9933 get_elf_backend_data (output_bfd
);
9935 if (!(_bfd_generic_link_add_one_symbol
9936 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
9937 tls_sec
, 0, NULL
, false, bed
->collect
, &h
)))
9940 tlsbase
->type
= STT_TLS
;
9941 tlsbase
= (struct elf_link_hash_entry
*) h
;
9942 tlsbase
->def_regular
= 1;
9943 tlsbase
->other
= STV_HIDDEN
;
9944 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, true);
9951 /* Finish up dynamic symbol handling. We set the contents of various
9952 dynamic sections here. */
9955 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
9956 struct bfd_link_info
*info
,
9957 struct elf_link_hash_entry
*h
,
9958 Elf_Internal_Sym
*sym
)
9960 struct elf_aarch64_link_hash_table
*htab
;
9961 htab
= elf_aarch64_hash_table (info
);
9963 if (h
->plt
.offset
!= (bfd_vma
) - 1)
9965 asection
*plt
, *gotplt
, *relplt
;
9967 /* This symbol has an entry in the procedure linkage table. Set
9970 /* When building a static executable, use .iplt, .igot.plt and
9971 .rela.iplt sections for STT_GNU_IFUNC symbols. */
9972 if (htab
->root
.splt
!= NULL
)
9974 plt
= htab
->root
.splt
;
9975 gotplt
= htab
->root
.sgotplt
;
9976 relplt
= htab
->root
.srelplt
;
9980 plt
= htab
->root
.iplt
;
9981 gotplt
= htab
->root
.igotplt
;
9982 relplt
= htab
->root
.irelplt
;
9985 /* This symbol has an entry in the procedure linkage table. Set
9987 if ((h
->dynindx
== -1
9988 && !((h
->forced_local
|| bfd_link_executable (info
))
9990 && h
->type
== STT_GNU_IFUNC
))
9996 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
9997 if (!h
->def_regular
)
9999 /* Mark the symbol as undefined, rather than as defined in
10000 the .plt section. */
10001 sym
->st_shndx
= SHN_UNDEF
;
10002 /* If the symbol is weak we need to clear the value.
10003 Otherwise, the PLT entry would provide a definition for
10004 the symbol even if the symbol wasn't defined anywhere,
10005 and so the symbol would never be NULL. Leave the value if
10006 there were any relocations where pointer equality matters
10007 (this is a clue for the dynamic linker, to make function
10008 pointer comparisons work between an application and shared
10010 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
10015 if (h
->got
.offset
!= (bfd_vma
) - 1
10016 && elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
10017 /* Undefined weak symbol in static PIE resolves to 0 without
10018 any dynamic relocations. */
10019 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10021 Elf_Internal_Rela rela
;
10024 /* This symbol has an entry in the global offset table. Set it
10026 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
10029 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
10030 + htab
->root
.sgot
->output_offset
10031 + (h
->got
.offset
& ~(bfd_vma
) 1));
10034 && h
->type
== STT_GNU_IFUNC
)
10036 if (bfd_link_pic (info
))
10038 /* Generate R_AARCH64_GLOB_DAT. */
10045 if (!h
->pointer_equality_needed
)
10048 /* For non-shared object, we can't use .got.plt, which
10049 contains the real function address if we need pointer
10050 equality. We load the GOT entry with the PLT entry. */
10051 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
10052 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
10053 + plt
->output_offset
10055 htab
->root
.sgot
->contents
10056 + (h
->got
.offset
& ~(bfd_vma
) 1));
10060 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
10062 if (!(h
->def_regular
|| ELF_COMMON_DEF_P (h
)))
10064 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
10065 /* Don't emit relative relocs if they are packed. */
10066 if (info
->enable_dt_relr
)
10067 goto skip_got_reloc
;
10068 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
10069 rela
.r_addend
= (h
->root
.u
.def
.value
10070 + h
->root
.u
.def
.section
->output_section
->vma
10071 + h
->root
.u
.def
.section
->output_offset
);
10076 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
10077 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
10078 htab
->root
.sgot
->contents
+ h
->got
.offset
);
10079 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (GLOB_DAT
));
10083 loc
= htab
->root
.srelgot
->contents
;
10084 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
10085 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
10091 Elf_Internal_Rela rela
;
10095 /* This symbol needs a copy reloc. Set it up. */
10096 if (h
->dynindx
== -1
10097 || (h
->root
.type
!= bfd_link_hash_defined
10098 && h
->root
.type
!= bfd_link_hash_defweak
)
10099 || htab
->root
.srelbss
== NULL
)
10102 rela
.r_offset
= (h
->root
.u
.def
.value
10103 + h
->root
.u
.def
.section
->output_section
->vma
10104 + h
->root
.u
.def
.section
->output_offset
);
10105 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
10107 if (h
->root
.u
.def
.section
== htab
->root
.sdynrelro
)
10108 s
= htab
->root
.sreldynrelro
;
10110 s
= htab
->root
.srelbss
;
10111 loc
= s
->contents
+ s
->reloc_count
++ * RELOC_SIZE (htab
);
10112 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
10115 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
10116 be NULL for local symbols. */
10118 && (h
== elf_hash_table (info
)->hdynamic
10119 || h
== elf_hash_table (info
)->hgot
))
10120 sym
->st_shndx
= SHN_ABS
;
10125 /* Finish up local dynamic symbol handling. We set the contents of
10126 various dynamic sections here. */
10129 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
10131 struct elf_link_hash_entry
*h
10132 = (struct elf_link_hash_entry
*) *slot
;
10133 struct bfd_link_info
*info
10134 = (struct bfd_link_info
*) inf
;
10136 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
10141 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
10142 struct elf_aarch64_link_hash_table
10145 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
10146 small and large plts and at the minute just generates
10149 /* PLT0 of the small PLT looks like this in ELF64 -
10150 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
10151 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
10152 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
10154 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
10155 // GOTPLT entry for this.
10157 PLT0 will be slightly different in ELF32 due to different got entry
10159 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
10163 memcpy (htab
->root
.splt
->contents
, htab
->plt0_entry
,
10164 htab
->plt_header_size
);
10166 /* PR 26312: Explicitly set the sh_entsize to 0 so that
10167 consumers do not think that the section contains fixed
10169 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
= 0;
10171 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
10172 + htab
->root
.sgotplt
->output_offset
10173 + GOT_ENTRY_SIZE
* 2);
10175 plt_base
= htab
->root
.splt
->output_section
->vma
+
10176 htab
->root
.splt
->output_offset
;
10178 /* First instruction in BTI enabled PLT stub is a BTI
10179 instruction so skip it. */
10180 bfd_byte
*plt0_entry
= htab
->root
.splt
->contents
;
10181 if (elf_aarch64_tdata (output_bfd
)->sw_protections
.plt_type
& PLT_BTI
)
10182 plt0_entry
= plt0_entry
+ 4;
10184 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
10185 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
10186 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
10188 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
10190 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
10192 PG_OFFSET (plt_got_2nd_ent
));
10194 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
10196 PG_OFFSET (plt_got_2nd_ent
));
10200 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
10201 struct bfd_link_info
*info
)
10203 struct elf_aarch64_link_hash_table
*htab
;
10207 htab
= elf_aarch64_hash_table (info
);
10208 dynobj
= htab
->root
.dynobj
;
10209 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
10211 if (htab
->root
.dynamic_sections_created
)
10213 ElfNN_External_Dyn
*dyncon
, *dynconend
;
10215 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
10218 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
10219 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
10220 for (; dyncon
< dynconend
; dyncon
++)
10222 Elf_Internal_Dyn dyn
;
10225 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
10233 s
= htab
->root
.sgotplt
;
10234 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
10238 s
= htab
->root
.srelplt
;
10239 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
10243 s
= htab
->root
.srelplt
;
10244 dyn
.d_un
.d_val
= s
->size
;
10247 case DT_TLSDESC_PLT
:
10248 s
= htab
->root
.splt
;
10249 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
10250 + htab
->root
.tlsdesc_plt
;
10253 case DT_TLSDESC_GOT
:
10254 s
= htab
->root
.sgot
;
10255 BFD_ASSERT (htab
->root
.tlsdesc_got
!= (bfd_vma
)-1);
10256 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
10257 + htab
->root
.tlsdesc_got
;
10261 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
10266 /* Fill in the special first entry in the procedure linkage table. */
10267 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
10269 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
10271 if (htab
->root
.tlsdesc_plt
&& !(info
->flags
& DF_BIND_NOW
))
10273 BFD_ASSERT (htab
->root
.tlsdesc_got
!= (bfd_vma
)-1);
10274 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
10275 htab
->root
.sgot
->contents
+ htab
->root
.tlsdesc_got
);
10277 const bfd_byte
*entry
= elfNN_aarch64_tlsdesc_small_plt_entry
;
10278 htab
->tlsdesc_plt_entry_size
= PLT_TLSDESC_ENTRY_SIZE
;
10280 aarch64_plt_type type
10281 = elf_aarch64_tdata (output_bfd
)->sw_protections
.plt_type
;
10282 if (type
== PLT_BTI
|| type
== PLT_BTI_PAC
)
10284 entry
= elfNN_aarch64_tlsdesc_small_plt_bti_entry
;
10287 memcpy (htab
->root
.splt
->contents
+ htab
->root
.tlsdesc_plt
,
10288 entry
, htab
->tlsdesc_plt_entry_size
);
10291 bfd_vma adrp1_addr
=
10292 htab
->root
.splt
->output_section
->vma
10293 + htab
->root
.splt
->output_offset
10294 + htab
->root
.tlsdesc_plt
+ 4;
10296 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
10299 htab
->root
.sgot
->output_section
->vma
10300 + htab
->root
.sgot
->output_offset
;
10302 bfd_vma pltgot_addr
=
10303 htab
->root
.sgotplt
->output_section
->vma
10304 + htab
->root
.sgotplt
->output_offset
;
10306 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->root
.tlsdesc_got
;
10308 bfd_byte
*plt_entry
=
10309 htab
->root
.splt
->contents
+ htab
->root
.tlsdesc_plt
;
10311 /* First instruction in BTI enabled PLT stub is a BTI
10312 instruction so skip it. */
10313 if (type
& PLT_BTI
)
10315 plt_entry
= plt_entry
+ 4;
10316 adrp1_addr
= adrp1_addr
+ 4;
10317 adrp2_addr
= adrp2_addr
+ 4;
10320 /* adrp x2, DT_TLSDESC_GOT */
10321 elf_aarch64_update_plt_entry (output_bfd
,
10322 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
10324 (PG (dt_tlsdesc_got
)
10325 - PG (adrp1_addr
)));
10328 elf_aarch64_update_plt_entry (output_bfd
,
10329 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
10332 - PG (adrp2_addr
)));
10334 /* ldr x2, [x2, #0] */
10335 elf_aarch64_update_plt_entry (output_bfd
,
10336 BFD_RELOC_AARCH64_LDSTNN_LO12
,
10338 PG_OFFSET (dt_tlsdesc_got
));
10340 /* add x3, x3, 0 */
10341 elf_aarch64_update_plt_entry (output_bfd
,
10342 BFD_RELOC_AARCH64_ADD_LO12
,
10344 PG_OFFSET (pltgot_addr
));
10349 if (htab
->root
.sgotplt
)
10351 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
10354 (_("discarded output section: `%pA'"), htab
->root
.sgotplt
);
10358 /* Fill in the first three entries in the global offset table. */
10359 if (htab
->root
.sgotplt
->size
> 0)
10361 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
10363 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
10364 bfd_put_NN (output_bfd
,
10366 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
10367 bfd_put_NN (output_bfd
,
10369 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE
* 2);
10372 if (htab
->root
.sgot
)
10374 if (htab
->root
.sgot
->size
> 0)
10377 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
10378 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
10382 elf_section_data (htab
->root
.sgotplt
->output_section
)->
10383 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE
;
10386 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
10387 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
10390 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
10391 htab_traverse (htab
->loc_hash_table
,
10392 elfNN_aarch64_finish_local_dynamic_symbol
,
10398 /* Check if BTI enabled PLTs are needed. Returns the type needed. */
10399 static aarch64_plt_type
10400 get_plt_type (bfd
*abfd
)
10402 aarch64_plt_type ret
= PLT_NORMAL
;
10403 bfd_byte
*contents
, *extdyn
, *extdynend
;
10404 asection
*sec
= bfd_get_section_by_name (abfd
, ".dynamic");
10406 || (sec
->flags
& SEC_HAS_CONTENTS
) == 0
10407 || sec
->size
< sizeof (ElfNN_External_Dyn
)
10408 || !bfd_malloc_and_get_section (abfd
, sec
, &contents
))
10411 extdynend
= contents
+ sec
->size
- sizeof (ElfNN_External_Dyn
);
10412 for (; extdyn
<= extdynend
; extdyn
+= sizeof (ElfNN_External_Dyn
))
10414 Elf_Internal_Dyn dyn
;
10415 bfd_elfNN_swap_dyn_in (abfd
, extdyn
, &dyn
);
10417 /* Let's check the processor specific dynamic array tags. */
10418 bfd_vma tag
= dyn
.d_tag
;
10419 if (tag
< DT_LOPROC
|| tag
> DT_HIPROC
)
10424 case DT_AARCH64_BTI_PLT
:
10428 case DT_AARCH64_PAC_PLT
:
10440 elfNN_aarch64_get_synthetic_symtab (bfd
*abfd
,
10447 elf_aarch64_tdata (abfd
)->sw_protections
.plt_type
= get_plt_type (abfd
);
10448 return _bfd_elf_get_synthetic_symtab (abfd
, symcount
, syms
,
10449 dynsymcount
, dynsyms
, ret
);
10452 /* Return address for Ith PLT stub in section PLT, for relocation REL
10453 or (bfd_vma) -1 if it should not be included. */
10456 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
10457 const arelent
*rel ATTRIBUTE_UNUSED
)
10459 size_t plt0_size
= PLT_ENTRY_SIZE
;
10460 size_t pltn_size
= PLT_SMALL_ENTRY_SIZE
;
10462 aarch64_plt_type plt_type
10463 = elf_aarch64_tdata (plt
->owner
)->sw_protections
.plt_type
;
10464 if (plt_type
== PLT_BTI_PAC
)
10466 if (elf_elfheader (plt
->owner
)->e_type
== ET_EXEC
)
10467 pltn_size
= PLT_BTI_PAC_SMALL_ENTRY_SIZE
;
10469 pltn_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
10471 else if (plt_type
== PLT_BTI
)
10473 if (elf_elfheader (plt
->owner
)->e_type
== ET_EXEC
)
10474 pltn_size
= PLT_BTI_SMALL_ENTRY_SIZE
;
10476 else if (plt_type
== PLT_PAC
)
10478 pltn_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
10481 return plt
->vma
+ plt0_size
+ i
* pltn_size
;
10484 /* Returns TRUE if NAME is an AArch64 mapping symbol.
10485 The ARM ELF standard defines $x (for A64 code) and $d (for data).
10486 It also allows a period initiated suffix to be added to the symbol, ie:
10487 "$[adtx]\.[:sym_char]+". */
10490 is_aarch64_mapping_symbol (const char * name
)
10492 return name
!= NULL
/* Paranoia. */
10493 && name
[0] == '$' /* Note: if objcopy --prefix-symbols has been used then
10494 the mapping symbols could have acquired a prefix.
10495 We do not support this here, since such symbols no
10496 longer conform to the ARM ELF ABI. */
10497 && (name
[1] == 'd' || name
[1] == 'x')
10498 && (name
[2] == 0 || name
[2] == '.');
10499 /* FIXME: Strictly speaking the symbol is only a valid mapping symbol if
10500 any characters that follow the period are legal characters for the body
10501 of a symbol's name. For now we just assume that this is the case. */
10504 /* Make sure that mapping symbols in object files are not removed via the
10505 "strip --strip-unneeded" tool. These symbols might needed in order to
10506 correctly generate linked files. Once an object file has been linked,
10507 it should be safe to remove them. */
10510 elfNN_aarch64_backend_symbol_processing (bfd
*abfd
, asymbol
*sym
)
10512 if (((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
10513 && sym
->section
!= bfd_abs_section_ptr
10514 && is_aarch64_mapping_symbol (sym
->name
))
10515 sym
->flags
|= BSF_KEEP
;
10518 /* Implement elf_backend_setup_gnu_properties for AArch64. It serves as a
10519 wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account
10520 for the effect of GNU properties of the output_bfd. */
10522 elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info
*info
)
10524 bfd
*pbfd
= _bfd_aarch64_elf_link_setup_gnu_properties (info
);
10526 /* When BTI is forced on the command line, information flows from plt_type to
10527 outprop, so plt_type has already been set and outprop don't have any effect
10529 Whereas if BTI is inferred from the input bfds, information flows from
10530 outprop to plt_type. If the property GNU_PROPERTY_AARCH64_FEATURE_1_BTI
10531 has been set on all the input bfds, then BTI is set on the output bfd and
10532 plt_type is updated accordingly. */
10533 struct elf_aarch64_obj_tdata
* tdata
= elf_aarch64_tdata (info
->output_bfd
);
10534 uint32_t outprop
= tdata
->gnu_property_aarch64_feature_1_and
;
10535 if (outprop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
)
10536 tdata
->sw_protections
.plt_type
|= PLT_BTI
;
10537 setup_plt_values (info
, tdata
->sw_protections
.plt_type
);
10541 /* Implement elf_backend_merge_gnu_properties for AArch64. It serves as a
10542 wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account
10543 for the effect of GNU properties of the output_bfd. */
10545 elfNN_aarch64_merge_gnu_properties (struct bfd_link_info
*info
,
10546 bfd
*abfd
, bfd
*bbfd
,
10547 elf_property
*aprop
,
10548 elf_property
*bprop
)
10551 = elf_aarch64_tdata (info
->output_bfd
)->gnu_property_aarch64_feature_1_and
;
10553 /* Properties are merged per type, hence only check for warnings when merging
10554 GNU_PROPERTY_AARCH64_FEATURE_1_AND. */
10555 if ((aprop
&& aprop
->pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
)
10556 || (bprop
&& bprop
->pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
))
10558 const aarch64_protection_opts
*sw_protections
10559 = &elf_aarch64_tdata (info
->output_bfd
)->sw_protections
;
10560 aarch64_feature_marking_report bti_report
= sw_protections
->bti_report
;
10561 aarch64_feature_marking_report gcs_report
= sw_protections
->gcs_report
;
10563 /* If output has been marked with BTI using command line argument, give
10564 out warning if necessary. */
10565 if ((outprop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
)
10566 && (bti_report
!= MARKING_NONE
))
10568 if (!aprop
|| !(aprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
10569 _bfd_aarch64_elf_check_bti_report (info
, abfd
);
10570 if (!bprop
|| !(bprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
10571 _bfd_aarch64_elf_check_bti_report (info
, bbfd
);
10574 /* If the output has been marked with GCS using '-z gcs' and the input is
10575 missing GCS feature tag, throw a warning/error in accordance with
10576 -z gcs-report=warning/error. */
10577 if ((outprop
& GNU_PROPERTY_AARCH64_FEATURE_1_GCS
)
10578 && gcs_report
!= MARKING_NONE
)
10580 if (!aprop
|| !(aprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_GCS
))
10581 _bfd_aarch64_elf_check_gcs_report (info
, abfd
);
10582 if (!bprop
|| !(bprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_GCS
))
10583 _bfd_aarch64_elf_check_gcs_report (info
, bbfd
);
10587 return _bfd_aarch64_elf_merge_gnu_properties (info
, abfd
, aprop
,
10591 /* We use this so we can override certain functions
10592 (though currently we don't). */
10594 const struct elf_size_info elfNN_aarch64_size_info
=
10596 sizeof (ElfNN_External_Ehdr
),
10597 sizeof (ElfNN_External_Phdr
),
10598 sizeof (ElfNN_External_Shdr
),
10599 sizeof (ElfNN_External_Rel
),
10600 sizeof (ElfNN_External_Rela
),
10601 sizeof (ElfNN_External_Sym
),
10602 sizeof (ElfNN_External_Dyn
),
10603 sizeof (Elf_External_Note
),
10604 4, /* Hash table entry size. */
10605 1, /* Internal relocs per external relocs. */
10606 ARCH_SIZE
, /* Arch size. */
10607 LOG_FILE_ALIGN
, /* Log_file_align. */
10608 ELFCLASSNN
, EV_CURRENT
,
10609 bfd_elfNN_write_out_phdrs
,
10610 bfd_elfNN_write_shdrs_and_ehdr
,
10611 bfd_elfNN_checksum_contents
,
10612 bfd_elfNN_write_relocs
,
10613 bfd_elfNN_swap_symbol_in
,
10614 bfd_elfNN_swap_symbol_out
,
10615 bfd_elfNN_slurp_reloc_table
,
10616 bfd_elfNN_slurp_symbol_table
,
10617 bfd_elfNN_swap_dyn_in
,
10618 bfd_elfNN_swap_dyn_out
,
10619 bfd_elfNN_swap_reloc_in
,
10620 bfd_elfNN_swap_reloc_out
,
10621 bfd_elfNN_swap_reloca_in
,
10622 bfd_elfNN_swap_reloca_out
10625 #define ELF_ARCH bfd_arch_aarch64
10626 #define ELF_TARGET_ID AARCH64_ELF_DATA
10627 #define ELF_MACHINE_CODE EM_AARCH64
10628 #define ELF_MAXPAGESIZE 0x10000
10629 #define ELF_COMMONPAGESIZE 0x1000
10631 #define bfd_elfNN_bfd_is_target_special_symbol \
10632 elfNN_aarch64_is_target_special_symbol
10634 #define bfd_elfNN_bfd_link_hash_table_create \
10635 elfNN_aarch64_link_hash_table_create
10637 #define bfd_elfNN_bfd_merge_private_bfd_data \
10638 elfNN_aarch64_merge_private_bfd_data
10640 #define bfd_elfNN_bfd_print_private_bfd_data \
10641 elfNN_aarch64_print_private_bfd_data
10643 #define bfd_elfNN_bfd_reloc_type_lookup \
10644 elfNN_aarch64_reloc_type_lookup
10646 #define bfd_elfNN_bfd_reloc_name_lookup \
10647 elfNN_aarch64_reloc_name_lookup
10649 #define bfd_elfNN_bfd_set_private_flags \
10650 elfNN_aarch64_set_private_flags
10652 #define bfd_elfNN_find_inliner_info \
10653 elfNN_aarch64_find_inliner_info
10655 #define bfd_elfNN_get_synthetic_symtab \
10656 elfNN_aarch64_get_synthetic_symtab
10658 #define bfd_elfNN_mkobject \
10659 elfNN_aarch64_mkobject
10661 #define bfd_elfNN_new_section_hook \
10662 elfNN_aarch64_new_section_hook
10664 #define elf_backend_adjust_dynamic_symbol \
10665 elfNN_aarch64_adjust_dynamic_symbol
10667 #define elf_backend_early_size_sections \
10668 elfNN_aarch64_early_size_sections
10670 #define elf_backend_check_relocs \
10671 elfNN_aarch64_check_relocs
10673 #define elf_backend_copy_indirect_symbol \
10674 elfNN_aarch64_copy_indirect_symbol
10676 #define elf_backend_merge_symbol_attribute \
10677 elfNN_aarch64_merge_symbol_attribute
10679 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
10680 to them in our hash. */
10681 #define elf_backend_create_dynamic_sections \
10682 elfNN_aarch64_create_dynamic_sections
10684 #define elf_backend_init_index_section \
10685 _bfd_elf_init_2_index_sections
10687 #define elf_backend_finish_dynamic_sections \
10688 elfNN_aarch64_finish_dynamic_sections
10690 #define elf_backend_finish_dynamic_symbol \
10691 elfNN_aarch64_finish_dynamic_symbol
10693 #define elf_backend_object_p \
10694 elfNN_aarch64_object_p
10696 #define elf_backend_output_arch_local_syms \
10697 elfNN_aarch64_output_arch_local_syms
10699 #define elf_backend_maybe_function_sym \
10700 elfNN_aarch64_maybe_function_sym
10702 #define elf_backend_plt_sym_val \
10703 elfNN_aarch64_plt_sym_val
10705 #define elf_backend_init_file_header \
10706 elfNN_aarch64_init_file_header
10708 #define elf_backend_relocate_section \
10709 elfNN_aarch64_relocate_section
10711 #define elf_backend_reloc_type_class \
10712 elfNN_aarch64_reloc_type_class
10714 #define elf_backend_section_from_shdr \
10715 elfNN_aarch64_section_from_shdr
10717 #define elf_backend_section_from_phdr \
10718 elfNN_aarch64_section_from_phdr
10720 #define elf_backend_modify_headers \
10721 elfNN_aarch64_modify_headers
10723 #define elf_backend_late_size_sections \
10724 elfNN_aarch64_late_size_sections
10726 #define elf_backend_size_info \
10727 elfNN_aarch64_size_info
10729 #define elf_backend_write_section \
10730 elfNN_aarch64_write_section
10732 #define elf_backend_symbol_processing \
10733 elfNN_aarch64_backend_symbol_processing
10735 #define elf_backend_setup_gnu_properties \
10736 elfNN_aarch64_link_setup_gnu_properties
10738 #define elf_backend_merge_gnu_properties \
10739 elfNN_aarch64_merge_gnu_properties
10741 #define elf_backend_size_relative_relocs \
10742 elfNN_aarch64_size_relative_relocs
10744 #define elf_backend_finish_relative_relocs \
10745 elfNN_aarch64_finish_relative_relocs
10747 #define elf_backend_can_refcount 1
10748 #define elf_backend_can_gc_sections 1
10749 #define elf_backend_plt_readonly 1
10750 #define elf_backend_want_got_plt 1
10751 #define elf_backend_want_plt_sym 0
10752 #define elf_backend_want_dynrelro 1
10753 #define elf_backend_may_use_rel_p 0
10754 #define elf_backend_may_use_rela_p 1
10755 #define elf_backend_default_use_rela_p 1
10756 #define elf_backend_rela_normal 1
10757 #define elf_backend_dtrel_excludes_plt 1
10758 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
10759 #define elf_backend_default_execstack 0
10760 #define elf_backend_extern_protected_data 0
10761 #define elf_backend_hash_symbol elf_aarch64_hash_symbol
10763 #undef elf_backend_obj_attrs_section
10764 #define elf_backend_obj_attrs_section ".ARM.attributes"
10766 #include "elfNN-target.h"
10768 /* CloudABI support. */
10770 #undef TARGET_LITTLE_SYM
10771 #define TARGET_LITTLE_SYM aarch64_elfNN_le_cloudabi_vec
10772 #undef TARGET_LITTLE_NAME
10773 #define TARGET_LITTLE_NAME "elfNN-littleaarch64-cloudabi"
10774 #undef TARGET_BIG_SYM
10775 #define TARGET_BIG_SYM aarch64_elfNN_be_cloudabi_vec
10776 #undef TARGET_BIG_NAME
10777 #define TARGET_BIG_NAME "elfNN-bigaarch64-cloudabi"
10780 #define ELF_OSABI ELFOSABI_CLOUDABI
10783 #define elfNN_bed elfNN_aarch64_cloudabi_bed
10785 #include "elfNN-target.h"