1 /* AArch64-specific support for NN-bit ELF.
2 Copyright (C) 2009-2020 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* Notes on implementation:
23 Thread Local Store (TLS)
27 The implementation currently supports both traditional TLS and TLS
28 descriptors, but only general dynamic (GD).
30 For traditional TLS the assembler will present us with code
31 fragments of the form:
34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
35 add x0, :tlsgd_lo12:foo
36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
40 For TLS descriptors the assembler will present us with code
41 fragments of the form:
43 adrp x0, :tlsdesc:foo R_AARCH64_TLSDESC_ADR_PAGE21(foo)
44 ldr x1, [x0, #:tlsdesc_lo12:foo] R_AARCH64_TLSDESC_LD64_LO12(foo)
45 add x0, x0, #:tlsdesc_lo12:foo R_AARCH64_TLSDESC_ADD_LO12(foo)
47 blr x1 R_AARCH64_TLSDESC_CALL(foo)
49 The relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} against foo
50 indicate that foo is thread local and should be accessed via the
51 traditional TLS mechanims.
53 The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
54 against foo indicate that 'foo' is thread local and should be accessed
55 via a TLS descriptor mechanism.
57 The precise instruction sequence is only relevant from the
58 perspective of linker relaxation which is currently not implemented.
60 The static linker must detect that 'foo' is a TLS object and
61 allocate a double GOT entry. The GOT entry must be created for both
62 global and local TLS symbols. Note that this is different to none
63 TLS local objects which do not need a GOT entry.
65 In the traditional TLS mechanism, the double GOT entry is used to
66 provide the tls_index structure, containing module and offset
67 entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
68 on the module entry. The loader will subsequently fixup this
69 relocation with the module identity.
71 For global traditional TLS symbols the static linker places an
72 R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
73 will subsequently fixup the offset. For local TLS symbols the static
74 linker fixes up offset.
76 In the TLS descriptor mechanism the double GOT entry is used to
77 provide the descriptor. The static linker places the relocation
78 R_AARCH64_TLSDESC on the first GOT slot. The loader will
79 subsequently fix this up.
83 The handling of TLS symbols is implemented across a number of
84 different backend functions. The following is a top level view of
85 what processing is performed where.
87 The TLS implementation maintains state information for each TLS
88 symbol. The state information for local and global symbols is kept
89 in different places. Global symbols use generic BFD structures while
90 local symbols use backend specific structures that are allocated and
91 maintained entirely by the backend.
95 elfNN_aarch64_check_relocs()
97 This function is invoked for each relocation.
99 The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
100 R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
101 spotted. One time creation of local symbol data structures are
102 created when the first local symbol is seen.
104 The reference count for a symbol is incremented. The GOT type for
105 each symbol is marked as general dynamic.
107 elfNN_aarch64_allocate_dynrelocs ()
109 For each global with positive reference count we allocate a double
110 GOT slot. For a traditional TLS symbol we allocate space for two
111 relocation entries on the GOT, for a TLS descriptor symbol we
112 allocate space for one relocation on the slot. Record the GOT offset
115 elfNN_aarch64_size_dynamic_sections ()
117 Iterate all input BFDS, look for in the local symbol data structure
118 constructed earlier for local TLS symbols and allocate them double
119 GOT slots along with space for a single GOT relocation. Update the
120 local symbol structure to record the GOT offset allocated.
122 elfNN_aarch64_relocate_section ()
124 Calls elfNN_aarch64_final_link_relocate ()
126 Emit the relevant TLS relocations against the GOT for each TLS
127 symbol. For local TLS symbols emit the GOT offset directly. The GOT
128 relocations are emitted once the first time a TLS symbol is
129 encountered. The implementation uses the LSB of the GOT offset to
130 flag that the relevant GOT relocations for a symbol have been
131 emitted. All of the TLS code that uses the GOT offset needs to take
132 care to mask out this flag bit before using the offset.
134 elfNN_aarch64_final_link_relocate ()
136 Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
140 #include "libiberty.h"
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
160 #define MORELLO_R(NAME) R_MORELLO_ ## NAME
161 #define MORELLO_R_STR(NAME) "R_MORELLO_" #NAME
164 #define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
165 #define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
166 #define HOWTO64(...) EMPTY_HOWTO (0)
167 #define HOWTO32(...) HOWTO (__VA_ARGS__)
168 #define LOG_FILE_ALIGN 2
169 #define BFD_RELOC_AARCH64_TLSDESC_LD32_LO12 BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
170 #define R_AARCH64_P32_TLSDESC_ADD_LO12 R_AARCH64_P32_TLSDESC_ADD_LO12_NC
173 #define IS_AARCH64_TLS_RELOC(R_TYPE) \
174 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12 \
186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12 \
187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC \
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12 \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12 \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12 \
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12 \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0 \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC \
201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1 \
202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC \
203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2 \
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
207 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12 \
208 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC \
209 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12 \
210 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12 \
212 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC \
213 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12 \
214 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC \
215 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
216 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
220 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
221 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
222 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
223 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
225 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
226 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
227 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
228 || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20 \
229 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
230 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
231 || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_CALL \
232 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
233 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
234 || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_LD128_LO12 \
235 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
236 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
237 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
238 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
239 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
240 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
241 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
242 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
243 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
244 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
245 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
246 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
247 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
248 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
249 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
250 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
252 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
253 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
254 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
255 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
256 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
257 || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20 \
258 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
259 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
260 || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_CALL \
261 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
262 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12 \
263 || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_LD128_LO12 \
264 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
265 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
266 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
267 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
269 #define ELIMINATE_COPY_RELOCS 1
271 /* Return size of a relocation entry. HTAB is the bfd's
272 elf_aarch64_link_hash_entry. */
273 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
275 /* GOT Entry size - 16 bytes in C64, 8 bytes in ELF64 and 4 bytes in ELF32. */
276 #define GOT_ENTRY_SIZE(htab) (ARCH_SIZE >> (3 - htab->c64_rel))
277 #define GOT_RESERVED_HEADER_SLOTS (3)
278 #define PLT_ENTRY_SIZE (32)
279 #define PLT_SMALL_ENTRY_SIZE (16)
280 #define PLT_TLSDESC_ENTRY_SIZE (32)
281 /* PLT sizes with BTI insn. */
282 #define PLT_BTI_SMALL_ENTRY_SIZE (24)
283 /* PLT sizes with PAC insn. */
284 #define PLT_PAC_SMALL_ENTRY_SIZE (24)
285 /* PLT sizes with BTI and PAC insn. */
286 #define PLT_BTI_PAC_SMALL_ENTRY_SIZE (24)
288 /* Encoding of the nop instruction. */
289 #define INSN_NOP 0xd503201f
291 #define aarch64_compute_jump_table_size(htab) \
292 (((htab)->root.srelplt == NULL) ? 0 \
293 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE (htab))
295 /* The first entry in a procedure linkage table looks like this
296 if the distance between the PLTGOT and the PLT is < 4GB use
297 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
298 in x16 and needs to work out PLTGOT[1] by using an address of
299 [x16,#-GOT_ENTRY_SIZE]. */
300 static const bfd_byte elfNN_aarch64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
302 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
303 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
305 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
306 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
308 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
309 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
311 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
312 0x1f, 0x20, 0x03, 0xd5, /* nop */
313 0x1f, 0x20, 0x03, 0xd5, /* nop */
314 0x1f, 0x20, 0x03, 0xd5, /* nop */
317 static const bfd_byte elfNN_aarch64_small_plt0_bti_entry
[PLT_ENTRY_SIZE
] =
319 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
320 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
321 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
323 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
324 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
326 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
327 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
329 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
330 0x1f, 0x20, 0x03, 0xd5, /* nop */
331 0x1f, 0x20, 0x03, 0xd5, /* nop */
335 static const bfd_byte elfNN_c64_small_plt0_entry
[PLT_ENTRY_SIZE
] =
337 0xf0, 0x7b, 0xbf, 0x62, /* stp c16, c30, [csp, #-32]! */
338 0x10, 0x00, 0x80, 0x90, /* adrp c16, (GOT+16) */
339 0x11, 0x0a, 0x40, 0xc2, /* ldr c17, [c16, #PLT_GOT+0x10] */
340 0x10, 0x02, 0x00, 0x02, /* add c16, c16,#PLT_GOT+0x10 */
341 0x20, 0x12, 0xc2, 0xc2, /* br c17 */
342 0x1f, 0x20, 0x03, 0xd5, /* nop */
343 0x1f, 0x20, 0x03, 0xd5, /* nop */
344 0x1f, 0x20, 0x03, 0xd5, /* nop */
347 /* Per function entry in a procedure linkage table looks like this
348 if the distance between the PLTGOT and the PLT is < 4GB use
349 these PLT entries. Use BTI versions of the PLTs when enabled. */
350 static const bfd_byte elfNN_aarch64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
352 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
354 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
355 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
357 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
358 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
360 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
364 static const bfd_byte elfNN_c64_small_plt_entry
[PLT_SMALL_ENTRY_SIZE
] =
366 0x10, 0x00, 0x80, 0x90, /* adrp c16, PLTGOT + offset */
367 0x11, 0x02, 0x40, 0xc2, /* ldr c17, [c16, PLTGOT + offset] */
368 0x10, 0x02, 0x00, 0x02, /* add c16, c16, :lo12:PLTGOT + offset */
369 0x20, 0x12, 0xc2, 0xc2, /* br c17. */
372 static const bfd_byte
373 elfNN_aarch64_small_plt_bti_entry
[PLT_BTI_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 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
385 0x1f, 0x20, 0x03, 0xd5, /* nop */
388 static const bfd_byte
389 elfNN_aarch64_small_plt_pac_entry
[PLT_PAC_SMALL_ENTRY_SIZE
] =
391 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
393 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
394 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
396 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
397 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
399 0x9f, 0x21, 0x03, 0xd5, /* autia1716 */
400 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
401 0x1f, 0x20, 0x03, 0xd5, /* nop */
404 static const bfd_byte
405 elfNN_aarch64_small_plt_bti_pac_entry
[PLT_BTI_PAC_SMALL_ENTRY_SIZE
] =
407 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
408 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
410 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
411 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
413 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
414 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
416 0x9f, 0x21, 0x03, 0xd5, /* autia1716 */
417 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
420 static const bfd_byte
421 elfNN_aarch64_tlsdesc_small_plt_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
423 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
424 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
425 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
427 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
428 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
430 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
431 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
433 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
434 0x1f, 0x20, 0x03, 0xd5, /* nop */
435 0x1f, 0x20, 0x03, 0xd5, /* nop */
438 static const bfd_byte
439 elfNN_aarch64_tlsdesc_small_plt_bti_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
441 0x5f, 0x24, 0x03, 0xd5, /* bti c. */
442 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
443 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
444 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
446 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
447 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
449 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
450 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
452 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
453 0x1f, 0x20, 0x03, 0xd5, /* nop */
456 static const bfd_byte
457 elfNN_aarch64_tlsdesc_small_plt_c64_entry
[PLT_TLSDESC_ENTRY_SIZE
] =
459 0xe2, 0x8f, 0xbf, 0x62, /* stp c2, c3, [sp, #-16]! */
460 0x02, 0x00, 0x80, 0x90, /* adrp c2, 0 */
461 0x03, 0x00, 0x80, 0x90, /* adrp c3, 0 */
462 0x42, 0x00, 0x40, 0xc2, /* ldr c2, [c2, #0] */
463 0x63, 0x00, 0x00, 0x02, /* add c3, c3, 0 */
464 0x40, 0x10, 0xc2, 0xc2, /* br c2 */
465 0x1f, 0x20, 0x03, 0xd5, /* nop */
466 0x1f, 0x20, 0x03, 0xd5, /* nop */
469 #define elf_info_to_howto elfNN_aarch64_info_to_howto
470 #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
472 #define AARCH64_ELF_ABI_VERSION 0
474 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
475 #define ALL_ONES (~ (bfd_vma) 0)
477 /* Indexed by the bfd interal reloc enumerators.
478 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
481 static reloc_howto_type elfNN_aarch64_howto_table
[] =
485 /* Basic data relocations. */
487 /* Deprecated, but retained for backwards compatibility. */
488 HOWTO64 (R_AARCH64_NULL
, /* type */
490 3, /* size (0 = byte, 1 = short, 2 = long) */
492 FALSE
, /* pc_relative */
494 complain_overflow_dont
, /* complain_on_overflow */
495 bfd_elf_generic_reloc
, /* special_function */
496 "R_AARCH64_NULL", /* name */
497 FALSE
, /* partial_inplace */
500 FALSE
), /* pcrel_offset */
501 HOWTO (R_AARCH64_NONE
, /* type */
503 3, /* size (0 = byte, 1 = short, 2 = long) */
505 FALSE
, /* pc_relative */
507 complain_overflow_dont
, /* complain_on_overflow */
508 bfd_elf_generic_reloc
, /* special_function */
509 "R_AARCH64_NONE", /* name */
510 FALSE
, /* partial_inplace */
513 FALSE
), /* pcrel_offset */
516 HOWTO64 (AARCH64_R (ABS64
), /* type */
518 4, /* size (4 = long long) */
520 FALSE
, /* pc_relative */
522 complain_overflow_unsigned
, /* complain_on_overflow */
523 bfd_elf_generic_reloc
, /* special_function */
524 AARCH64_R_STR (ABS64
), /* name */
525 FALSE
, /* partial_inplace */
526 ALL_ONES
, /* src_mask */
527 ALL_ONES
, /* dst_mask */
528 FALSE
), /* pcrel_offset */
531 HOWTO (AARCH64_R (ABS32
), /* type */
533 2, /* size (0 = byte, 1 = short, 2 = long) */
535 FALSE
, /* pc_relative */
537 complain_overflow_unsigned
, /* complain_on_overflow */
538 bfd_elf_generic_reloc
, /* special_function */
539 AARCH64_R_STR (ABS32
), /* name */
540 FALSE
, /* partial_inplace */
541 0xffffffff, /* src_mask */
542 0xffffffff, /* dst_mask */
543 FALSE
), /* pcrel_offset */
546 HOWTO (AARCH64_R (ABS16
), /* type */
548 1, /* size (0 = byte, 1 = short, 2 = long) */
550 FALSE
, /* pc_relative */
552 complain_overflow_unsigned
, /* complain_on_overflow */
553 bfd_elf_generic_reloc
, /* special_function */
554 AARCH64_R_STR (ABS16
), /* name */
555 FALSE
, /* partial_inplace */
556 0xffff, /* src_mask */
557 0xffff, /* dst_mask */
558 FALSE
), /* pcrel_offset */
560 /* .xword: (S+A-P) */
561 HOWTO64 (AARCH64_R (PREL64
), /* type */
563 4, /* size (4 = long long) */
565 TRUE
, /* pc_relative */
567 complain_overflow_signed
, /* complain_on_overflow */
568 bfd_elf_generic_reloc
, /* special_function */
569 AARCH64_R_STR (PREL64
), /* name */
570 FALSE
, /* partial_inplace */
571 ALL_ONES
, /* src_mask */
572 ALL_ONES
, /* dst_mask */
573 TRUE
), /* pcrel_offset */
576 HOWTO (AARCH64_R (PREL32
), /* type */
578 2, /* size (0 = byte, 1 = short, 2 = long) */
580 TRUE
, /* pc_relative */
582 complain_overflow_signed
, /* complain_on_overflow */
583 bfd_elf_generic_reloc
, /* special_function */
584 AARCH64_R_STR (PREL32
), /* name */
585 FALSE
, /* partial_inplace */
586 0xffffffff, /* src_mask */
587 0xffffffff, /* dst_mask */
588 TRUE
), /* pcrel_offset */
591 HOWTO (AARCH64_R (PREL16
), /* type */
593 1, /* size (0 = byte, 1 = short, 2 = long) */
595 TRUE
, /* pc_relative */
597 complain_overflow_signed
, /* complain_on_overflow */
598 bfd_elf_generic_reloc
, /* special_function */
599 AARCH64_R_STR (PREL16
), /* name */
600 FALSE
, /* partial_inplace */
601 0xffff, /* src_mask */
602 0xffff, /* dst_mask */
603 TRUE
), /* pcrel_offset */
605 /* Group relocations to create a 16, 32, 48 or 64 bit
606 unsigned data or abs address inline. */
608 /* MOVZ: ((S+A) >> 0) & 0xffff */
609 HOWTO (AARCH64_R (MOVW_UABS_G0
), /* type */
611 2, /* size (0 = byte, 1 = short, 2 = long) */
613 FALSE
, /* pc_relative */
615 complain_overflow_unsigned
, /* complain_on_overflow */
616 bfd_elf_generic_reloc
, /* special_function */
617 AARCH64_R_STR (MOVW_UABS_G0
), /* name */
618 FALSE
, /* partial_inplace */
619 0xffff, /* src_mask */
620 0xffff, /* dst_mask */
621 FALSE
), /* pcrel_offset */
623 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
624 HOWTO (AARCH64_R (MOVW_UABS_G0_NC
), /* type */
626 2, /* size (0 = byte, 1 = short, 2 = long) */
628 FALSE
, /* pc_relative */
630 complain_overflow_dont
, /* complain_on_overflow */
631 bfd_elf_generic_reloc
, /* special_function */
632 AARCH64_R_STR (MOVW_UABS_G0_NC
), /* name */
633 FALSE
, /* partial_inplace */
634 0xffff, /* src_mask */
635 0xffff, /* dst_mask */
636 FALSE
), /* pcrel_offset */
638 /* MOVZ: ((S+A) >> 16) & 0xffff */
639 HOWTO (AARCH64_R (MOVW_UABS_G1
), /* type */
641 2, /* size (0 = byte, 1 = short, 2 = long) */
643 FALSE
, /* pc_relative */
645 complain_overflow_unsigned
, /* complain_on_overflow */
646 bfd_elf_generic_reloc
, /* special_function */
647 AARCH64_R_STR (MOVW_UABS_G1
), /* name */
648 FALSE
, /* partial_inplace */
649 0xffff, /* src_mask */
650 0xffff, /* dst_mask */
651 FALSE
), /* pcrel_offset */
653 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
654 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC
), /* type */
656 2, /* size (0 = byte, 1 = short, 2 = long) */
658 FALSE
, /* pc_relative */
660 complain_overflow_dont
, /* complain_on_overflow */
661 bfd_elf_generic_reloc
, /* special_function */
662 AARCH64_R_STR (MOVW_UABS_G1_NC
), /* name */
663 FALSE
, /* partial_inplace */
664 0xffff, /* src_mask */
665 0xffff, /* dst_mask */
666 FALSE
), /* pcrel_offset */
668 /* MOVZ: ((S+A) >> 32) & 0xffff */
669 HOWTO64 (AARCH64_R (MOVW_UABS_G2
), /* type */
671 2, /* size (0 = byte, 1 = short, 2 = long) */
673 FALSE
, /* pc_relative */
675 complain_overflow_unsigned
, /* complain_on_overflow */
676 bfd_elf_generic_reloc
, /* special_function */
677 AARCH64_R_STR (MOVW_UABS_G2
), /* name */
678 FALSE
, /* partial_inplace */
679 0xffff, /* src_mask */
680 0xffff, /* dst_mask */
681 FALSE
), /* pcrel_offset */
683 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
684 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC
), /* type */
686 2, /* size (0 = byte, 1 = short, 2 = long) */
688 FALSE
, /* pc_relative */
690 complain_overflow_dont
, /* complain_on_overflow */
691 bfd_elf_generic_reloc
, /* special_function */
692 AARCH64_R_STR (MOVW_UABS_G2_NC
), /* name */
693 FALSE
, /* partial_inplace */
694 0xffff, /* src_mask */
695 0xffff, /* dst_mask */
696 FALSE
), /* pcrel_offset */
698 /* MOVZ: ((S+A) >> 48) & 0xffff */
699 HOWTO64 (AARCH64_R (MOVW_UABS_G3
), /* type */
701 2, /* size (0 = byte, 1 = short, 2 = long) */
703 FALSE
, /* pc_relative */
705 complain_overflow_unsigned
, /* complain_on_overflow */
706 bfd_elf_generic_reloc
, /* special_function */
707 AARCH64_R_STR (MOVW_UABS_G3
), /* name */
708 FALSE
, /* partial_inplace */
709 0xffff, /* src_mask */
710 0xffff, /* dst_mask */
711 FALSE
), /* pcrel_offset */
713 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
714 signed data or abs address inline. Will change instruction
715 to MOVN or MOVZ depending on sign of calculated value. */
717 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
718 HOWTO (AARCH64_R (MOVW_SABS_G0
), /* type */
720 2, /* size (0 = byte, 1 = short, 2 = long) */
722 FALSE
, /* pc_relative */
724 complain_overflow_signed
, /* complain_on_overflow */
725 bfd_elf_generic_reloc
, /* special_function */
726 AARCH64_R_STR (MOVW_SABS_G0
), /* name */
727 FALSE
, /* partial_inplace */
728 0xffff, /* src_mask */
729 0xffff, /* dst_mask */
730 FALSE
), /* pcrel_offset */
732 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
733 HOWTO64 (AARCH64_R (MOVW_SABS_G1
), /* type */
735 2, /* size (0 = byte, 1 = short, 2 = long) */
737 FALSE
, /* pc_relative */
739 complain_overflow_signed
, /* complain_on_overflow */
740 bfd_elf_generic_reloc
, /* special_function */
741 AARCH64_R_STR (MOVW_SABS_G1
), /* name */
742 FALSE
, /* partial_inplace */
743 0xffff, /* src_mask */
744 0xffff, /* dst_mask */
745 FALSE
), /* pcrel_offset */
747 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
748 HOWTO64 (AARCH64_R (MOVW_SABS_G2
), /* type */
750 2, /* size (0 = byte, 1 = short, 2 = long) */
752 FALSE
, /* pc_relative */
754 complain_overflow_signed
, /* complain_on_overflow */
755 bfd_elf_generic_reloc
, /* special_function */
756 AARCH64_R_STR (MOVW_SABS_G2
), /* name */
757 FALSE
, /* partial_inplace */
758 0xffff, /* src_mask */
759 0xffff, /* dst_mask */
760 FALSE
), /* pcrel_offset */
762 /* Group relocations to create a 16, 32, 48 or 64 bit
763 PC relative address inline. */
765 /* MOV[NZ]: ((S+A-P) >> 0) & 0xffff */
766 HOWTO (AARCH64_R (MOVW_PREL_G0
), /* type */
768 2, /* size (0 = byte, 1 = short, 2 = long) */
770 TRUE
, /* pc_relative */
772 complain_overflow_signed
, /* complain_on_overflow */
773 bfd_elf_generic_reloc
, /* special_function */
774 AARCH64_R_STR (MOVW_PREL_G0
), /* name */
775 FALSE
, /* partial_inplace */
776 0xffff, /* src_mask */
777 0xffff, /* dst_mask */
778 TRUE
), /* pcrel_offset */
780 /* MOVK: ((S+A-P) >> 0) & 0xffff [no overflow check] */
781 HOWTO (AARCH64_R (MOVW_PREL_G0_NC
), /* type */
783 2, /* size (0 = byte, 1 = short, 2 = long) */
785 TRUE
, /* pc_relative */
787 complain_overflow_dont
, /* complain_on_overflow */
788 bfd_elf_generic_reloc
, /* special_function */
789 AARCH64_R_STR (MOVW_PREL_G0_NC
), /* name */
790 FALSE
, /* partial_inplace */
791 0xffff, /* src_mask */
792 0xffff, /* dst_mask */
793 TRUE
), /* pcrel_offset */
795 /* MOV[NZ]: ((S+A-P) >> 16) & 0xffff */
796 HOWTO (AARCH64_R (MOVW_PREL_G1
), /* type */
798 2, /* size (0 = byte, 1 = short, 2 = long) */
800 TRUE
, /* pc_relative */
802 complain_overflow_signed
, /* complain_on_overflow */
803 bfd_elf_generic_reloc
, /* special_function */
804 AARCH64_R_STR (MOVW_PREL_G1
), /* name */
805 FALSE
, /* partial_inplace */
806 0xffff, /* src_mask */
807 0xffff, /* dst_mask */
808 TRUE
), /* pcrel_offset */
810 /* MOVK: ((S+A-P) >> 16) & 0xffff [no overflow check] */
811 HOWTO64 (AARCH64_R (MOVW_PREL_G1_NC
), /* type */
813 2, /* size (0 = byte, 1 = short, 2 = long) */
815 TRUE
, /* pc_relative */
817 complain_overflow_dont
, /* complain_on_overflow */
818 bfd_elf_generic_reloc
, /* special_function */
819 AARCH64_R_STR (MOVW_PREL_G1_NC
), /* name */
820 FALSE
, /* partial_inplace */
821 0xffff, /* src_mask */
822 0xffff, /* dst_mask */
823 TRUE
), /* pcrel_offset */
825 /* MOV[NZ]: ((S+A-P) >> 32) & 0xffff */
826 HOWTO64 (AARCH64_R (MOVW_PREL_G2
), /* type */
828 2, /* size (0 = byte, 1 = short, 2 = long) */
830 TRUE
, /* pc_relative */
832 complain_overflow_signed
, /* complain_on_overflow */
833 bfd_elf_generic_reloc
, /* special_function */
834 AARCH64_R_STR (MOVW_PREL_G2
), /* name */
835 FALSE
, /* partial_inplace */
836 0xffff, /* src_mask */
837 0xffff, /* dst_mask */
838 TRUE
), /* pcrel_offset */
840 /* MOVK: ((S+A-P) >> 32) & 0xffff [no overflow check] */
841 HOWTO64 (AARCH64_R (MOVW_PREL_G2_NC
), /* type */
843 2, /* size (0 = byte, 1 = short, 2 = long) */
845 TRUE
, /* pc_relative */
847 complain_overflow_dont
, /* complain_on_overflow */
848 bfd_elf_generic_reloc
, /* special_function */
849 AARCH64_R_STR (MOVW_PREL_G2_NC
), /* name */
850 FALSE
, /* partial_inplace */
851 0xffff, /* src_mask */
852 0xffff, /* dst_mask */
853 TRUE
), /* pcrel_offset */
855 /* MOV[NZ]: ((S+A-P) >> 48) & 0xffff */
856 HOWTO64 (AARCH64_R (MOVW_PREL_G3
), /* type */
858 2, /* size (0 = byte, 1 = short, 2 = long) */
860 TRUE
, /* pc_relative */
862 complain_overflow_dont
, /* complain_on_overflow */
863 bfd_elf_generic_reloc
, /* special_function */
864 AARCH64_R_STR (MOVW_PREL_G3
), /* name */
865 FALSE
, /* partial_inplace */
866 0xffff, /* src_mask */
867 0xffff, /* dst_mask */
868 TRUE
), /* pcrel_offset */
870 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
871 addresses: PG(x) is (x & ~0xfff). */
873 /* LD-lit: ((S+A-P) >> 4) & 0x1ffff */
874 HOWTO64 (MORELLO_R (LD_PREL_LO17
), /* type */
876 2, /* size (0 = byte, 1 = short, 2 = long) */
878 TRUE
, /* pc_relative */
880 complain_overflow_signed
, /* complain_on_overflow */
881 bfd_elf_generic_reloc
, /* special_function */
882 MORELLO_R_STR (LD_PREL_LO17
), /* name */
883 FALSE
, /* partial_inplace */
884 0x1ffff, /* src_mask */
885 0x1ffff, /* dst_mask */
886 TRUE
), /* pcrel_offset */
888 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
889 HOWTO (AARCH64_R (LD_PREL_LO19
), /* type */
891 2, /* size (0 = byte, 1 = short, 2 = long) */
893 TRUE
, /* pc_relative */
895 complain_overflow_signed
, /* complain_on_overflow */
896 bfd_elf_generic_reloc
, /* special_function */
897 AARCH64_R_STR (LD_PREL_LO19
), /* name */
898 FALSE
, /* partial_inplace */
899 0x7ffff, /* src_mask */
900 0x7ffff, /* dst_mask */
901 TRUE
), /* pcrel_offset */
903 /* C64 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
904 HOWTO64 (MORELLO_R (ADR_PREL_PG_HI20
), /* type */
906 2, /* size (0 = byte, 1 = short, 2 = long) */
908 TRUE
, /* pc_relative */
910 complain_overflow_signed
, /* complain_on_overflow */
911 bfd_elf_generic_reloc
, /* special_function */
912 MORELLO_R_STR (ADR_PREL_PG_HI20
), /* name */
913 FALSE
, /* partial_inplace */
914 0xfffff, /* src_mask */
915 0xfffff, /* dst_mask */
916 TRUE
), /* pcrel_offset */
918 /* C64 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0xfffff [no overflow check] */
919 HOWTO64 (MORELLO_R (ADR_PREL_PG_HI20_NC
), /* type */
921 2, /* size (0 = byte, 1 = short, 2 = long) */
923 TRUE
, /* pc_relative */
925 complain_overflow_dont
, /* complain_on_overflow */
926 bfd_elf_generic_reloc
, /* special_function */
927 MORELLO_R_STR (ADR_PREL_PG_HI20_NC
), /* name */
928 FALSE
, /* partial_inplace */
929 0xfffff, /* src_mask */
930 0xfffff, /* dst_mask */
931 TRUE
), /* pcrel_offset */
933 /* ADR: (S+A-P) & 0x1fffff */
934 HOWTO (AARCH64_R (ADR_PREL_LO21
), /* type */
936 2, /* size (0 = byte, 1 = short, 2 = long) */
938 TRUE
, /* pc_relative */
940 complain_overflow_signed
, /* complain_on_overflow */
941 bfd_elf_generic_reloc
, /* special_function */
942 AARCH64_R_STR (ADR_PREL_LO21
), /* name */
943 FALSE
, /* partial_inplace */
944 0x1fffff, /* src_mask */
945 0x1fffff, /* dst_mask */
946 TRUE
), /* pcrel_offset */
948 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
949 HOWTO (AARCH64_R (ADR_PREL_PG_HI21
), /* type */
951 2, /* size (0 = byte, 1 = short, 2 = long) */
953 TRUE
, /* pc_relative */
955 complain_overflow_signed
, /* complain_on_overflow */
956 bfd_elf_generic_reloc
, /* special_function */
957 AARCH64_R_STR (ADR_PREL_PG_HI21
), /* name */
958 FALSE
, /* partial_inplace */
959 0x1fffff, /* src_mask */
960 0x1fffff, /* dst_mask */
961 TRUE
), /* pcrel_offset */
963 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
964 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC
), /* type */
966 2, /* size (0 = byte, 1 = short, 2 = long) */
968 TRUE
, /* pc_relative */
970 complain_overflow_dont
, /* complain_on_overflow */
971 bfd_elf_generic_reloc
, /* special_function */
972 AARCH64_R_STR (ADR_PREL_PG_HI21_NC
), /* name */
973 FALSE
, /* partial_inplace */
974 0x1fffff, /* src_mask */
975 0x1fffff, /* dst_mask */
976 TRUE
), /* pcrel_offset */
978 /* ADD: (S+A) & 0xfff [no overflow check] */
979 HOWTO (AARCH64_R (ADD_ABS_LO12_NC
), /* type */
981 2, /* size (0 = byte, 1 = short, 2 = long) */
983 FALSE
, /* pc_relative */
985 complain_overflow_dont
, /* complain_on_overflow */
986 bfd_elf_generic_reloc
, /* special_function */
987 AARCH64_R_STR (ADD_ABS_LO12_NC
), /* name */
988 FALSE
, /* partial_inplace */
989 0x3ffc00, /* src_mask */
990 0x3ffc00, /* dst_mask */
991 FALSE
), /* pcrel_offset */
993 /* LD/ST8: (S+A) & 0xfff */
994 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC
), /* type */
996 2, /* size (0 = byte, 1 = short, 2 = long) */
998 FALSE
, /* pc_relative */
1000 complain_overflow_dont
, /* complain_on_overflow */
1001 bfd_elf_generic_reloc
, /* special_function */
1002 AARCH64_R_STR (LDST8_ABS_LO12_NC
), /* name */
1003 FALSE
, /* partial_inplace */
1004 0xfff, /* src_mask */
1005 0xfff, /* dst_mask */
1006 FALSE
), /* pcrel_offset */
1008 /* Relocations for control-flow instructions. */
1010 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
1011 HOWTO (AARCH64_R (TSTBR14
), /* type */
1013 2, /* size (0 = byte, 1 = short, 2 = long) */
1015 TRUE
, /* pc_relative */
1017 complain_overflow_signed
, /* complain_on_overflow */
1018 bfd_elf_generic_reloc
, /* special_function */
1019 AARCH64_R_STR (TSTBR14
), /* name */
1020 FALSE
, /* partial_inplace */
1021 0x3fff, /* src_mask */
1022 0x3fff, /* dst_mask */
1023 TRUE
), /* pcrel_offset */
1025 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
1026 HOWTO (AARCH64_R (CONDBR19
), /* type */
1028 2, /* size (0 = byte, 1 = short, 2 = long) */
1030 TRUE
, /* pc_relative */
1032 complain_overflow_signed
, /* complain_on_overflow */
1033 bfd_elf_generic_reloc
, /* special_function */
1034 AARCH64_R_STR (CONDBR19
), /* name */
1035 FALSE
, /* partial_inplace */
1036 0x7ffff, /* src_mask */
1037 0x7ffff, /* dst_mask */
1038 TRUE
), /* pcrel_offset */
1040 /* B: ((S+A-P) >> 2) & 0x3ffffff */
1041 HOWTO (AARCH64_R (JUMP26
), /* type */
1043 2, /* size (0 = byte, 1 = short, 2 = long) */
1045 TRUE
, /* pc_relative */
1047 complain_overflow_signed
, /* complain_on_overflow */
1048 bfd_elf_generic_reloc
, /* special_function */
1049 AARCH64_R_STR (JUMP26
), /* name */
1050 FALSE
, /* partial_inplace */
1051 0x3ffffff, /* src_mask */
1052 0x3ffffff, /* dst_mask */
1053 TRUE
), /* pcrel_offset */
1055 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
1056 HOWTO (AARCH64_R (CALL26
), /* type */
1058 2, /* size (0 = byte, 1 = short, 2 = long) */
1060 TRUE
, /* pc_relative */
1062 complain_overflow_signed
, /* complain_on_overflow */
1063 bfd_elf_generic_reloc
, /* special_function */
1064 AARCH64_R_STR (CALL26
), /* name */
1065 FALSE
, /* partial_inplace */
1066 0x3ffffff, /* src_mask */
1067 0x3ffffff, /* dst_mask */
1068 TRUE
), /* pcrel_offset */
1070 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
1071 HOWTO64 (MORELLO_R (TSTBR14
), /* type */
1073 2, /* size (0 = byte, 1 = short, 2 = long) */
1075 TRUE
, /* pc_relative */
1077 complain_overflow_signed
, /* complain_on_overflow */
1078 bfd_elf_generic_reloc
, /* special_function */
1079 MORELLO_R_STR (TSTBR14
), /* name */
1080 FALSE
, /* partial_inplace */
1081 0x3fff, /* src_mask */
1082 0x3fff, /* dst_mask */
1083 TRUE
), /* pcrel_offset */
1085 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
1086 HOWTO64 (MORELLO_R (CONDBR19
), /* type */
1088 2, /* size (0 = byte, 1 = short, 2 = long) */
1090 TRUE
, /* pc_relative */
1092 complain_overflow_signed
, /* complain_on_overflow */
1093 bfd_elf_generic_reloc
, /* special_function */
1094 MORELLO_R_STR (CONDBR19
), /* name */
1095 FALSE
, /* partial_inplace */
1096 0x7ffff, /* src_mask */
1097 0x7ffff, /* dst_mask */
1098 TRUE
), /* pcrel_offset */
1100 /* B: ((S+A-P) >> 2) & 0x3ffffff */
1101 HOWTO64 (MORELLO_R (JUMP26
), /* type */
1103 2, /* size (0 = byte, 1 = short, 2 = long) */
1105 TRUE
, /* pc_relative */
1107 complain_overflow_signed
, /* complain_on_overflow */
1108 bfd_elf_generic_reloc
, /* special_function */
1109 MORELLO_R_STR (JUMP26
), /* name */
1110 FALSE
, /* partial_inplace */
1111 0x3ffffff, /* src_mask */
1112 0x3ffffff, /* dst_mask */
1113 TRUE
), /* pcrel_offset */
1115 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
1116 HOWTO64 (MORELLO_R (CALL26
), /* type */
1118 2, /* size (0 = byte, 1 = short, 2 = long) */
1120 TRUE
, /* pc_relative */
1122 complain_overflow_signed
, /* complain_on_overflow */
1123 bfd_elf_generic_reloc
, /* special_function */
1124 MORELLO_R_STR (CALL26
), /* name */
1125 FALSE
, /* partial_inplace */
1126 0x3ffffff, /* src_mask */
1127 0x3ffffff, /* dst_mask */
1128 TRUE
), /* pcrel_offset */
1130 /* LD/ST16: (S+A) & 0xffe */
1131 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC
), /* type */
1133 2, /* size (0 = byte, 1 = short, 2 = long) */
1135 FALSE
, /* pc_relative */
1137 complain_overflow_dont
, /* complain_on_overflow */
1138 bfd_elf_generic_reloc
, /* special_function */
1139 AARCH64_R_STR (LDST16_ABS_LO12_NC
), /* name */
1140 FALSE
, /* partial_inplace */
1141 0xffe, /* src_mask */
1142 0xffe, /* dst_mask */
1143 FALSE
), /* pcrel_offset */
1145 /* LD/ST32: (S+A) & 0xffc */
1146 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC
), /* type */
1148 2, /* size (0 = byte, 1 = short, 2 = long) */
1150 FALSE
, /* pc_relative */
1152 complain_overflow_dont
, /* complain_on_overflow */
1153 bfd_elf_generic_reloc
, /* special_function */
1154 AARCH64_R_STR (LDST32_ABS_LO12_NC
), /* name */
1155 FALSE
, /* partial_inplace */
1156 0xffc, /* src_mask */
1157 0xffc, /* dst_mask */
1158 FALSE
), /* pcrel_offset */
1160 /* LD/ST64: (S+A) & 0xff8 */
1161 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC
), /* type */
1163 2, /* size (0 = byte, 1 = short, 2 = long) */
1165 FALSE
, /* pc_relative */
1167 complain_overflow_dont
, /* complain_on_overflow */
1168 bfd_elf_generic_reloc
, /* special_function */
1169 AARCH64_R_STR (LDST64_ABS_LO12_NC
), /* name */
1170 FALSE
, /* partial_inplace */
1171 0xff8, /* src_mask */
1172 0xff8, /* dst_mask */
1173 FALSE
), /* pcrel_offset */
1175 /* LD/ST128: (S+A) & 0xff0 */
1176 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC
), /* type */
1178 2, /* size (0 = byte, 1 = short, 2 = long) */
1180 FALSE
, /* pc_relative */
1182 complain_overflow_dont
, /* complain_on_overflow */
1183 bfd_elf_generic_reloc
, /* special_function */
1184 AARCH64_R_STR (LDST128_ABS_LO12_NC
), /* name */
1185 FALSE
, /* partial_inplace */
1186 0xff0, /* src_mask */
1187 0xff0, /* dst_mask */
1188 FALSE
), /* pcrel_offset */
1190 /* Set a load-literal immediate field to bits
1191 0x1FFFFC of G(S)-P */
1192 HOWTO (AARCH64_R (GOT_LD_PREL19
), /* type */
1194 2, /* size (0 = byte,1 = short,2 = long) */
1196 TRUE
, /* pc_relative */
1198 complain_overflow_signed
, /* complain_on_overflow */
1199 bfd_elf_generic_reloc
, /* special_function */
1200 AARCH64_R_STR (GOT_LD_PREL19
), /* name */
1201 FALSE
, /* partial_inplace */
1202 0xffffe0, /* src_mask */
1203 0xffffe0, /* dst_mask */
1204 TRUE
), /* pcrel_offset */
1206 /* Get to the page for the GOT entry for the symbol
1207 (G(S) - P) using an ADRP instruction. */
1208 HOWTO (AARCH64_R (ADR_GOT_PAGE
), /* type */
1209 12, /* rightshift */
1210 2, /* size (0 = byte, 1 = short, 2 = long) */
1212 TRUE
, /* pc_relative */
1214 complain_overflow_dont
, /* complain_on_overflow */
1215 bfd_elf_generic_reloc
, /* special_function */
1216 AARCH64_R_STR (ADR_GOT_PAGE
), /* name */
1217 FALSE
, /* partial_inplace */
1218 0x1fffff, /* src_mask */
1219 0x1fffff, /* dst_mask */
1220 TRUE
), /* pcrel_offset */
1222 /* Get to the page for the GOT entry for the symbol
1223 (G(S) - P) using a C64 ADRP instruction. */
1224 HOWTO64 (MORELLO_R (ADR_GOT_PAGE
), /* type */
1225 12, /* rightshift */
1226 2, /* size (0 = byte, 1 = short, 2 = long) */
1228 TRUE
, /* pc_relative */
1230 complain_overflow_dont
, /* complain_on_overflow */
1231 bfd_elf_generic_reloc
, /* special_function */
1232 MORELLO_R_STR (ADR_GOT_PAGE
), /* name */
1233 FALSE
, /* partial_inplace */
1234 0xfffff, /* src_mask */
1235 0xfffff, /* dst_mask */
1236 TRUE
), /* pcrel_offset */
1238 /* LD64: GOT offset G(S) & 0xff8 */
1239 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC
), /* type */
1241 2, /* size (0 = byte, 1 = short, 2 = long) */
1243 FALSE
, /* pc_relative */
1245 complain_overflow_dont
, /* complain_on_overflow */
1246 bfd_elf_generic_reloc
, /* special_function */
1247 AARCH64_R_STR (LD64_GOT_LO12_NC
), /* name */
1248 FALSE
, /* partial_inplace */
1249 0xff8, /* src_mask */
1250 0xff8, /* dst_mask */
1251 FALSE
), /* pcrel_offset */
1253 /* LD128: GOT offset G(S) & 0xff0 */
1254 HOWTO64 (MORELLO_R (LD128_GOT_LO12_NC
), /* type */
1256 2, /* size (0 = byte, 1 = short, 2 = long) */
1258 FALSE
, /* pc_relative */
1260 complain_overflow_dont
, /* complain_on_overflow */
1261 bfd_elf_generic_reloc
, /* special_function */
1262 MORELLO_R_STR (LD128_GOT_LO12_NC
), /* name */
1263 FALSE
, /* partial_inplace */
1264 0xff0, /* src_mask */
1265 0xff0, /* dst_mask */
1266 FALSE
), /* pcrel_offset */
1268 /* LD32: GOT offset G(S) & 0xffc */
1269 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC
), /* type */
1271 2, /* size (0 = byte, 1 = short, 2 = long) */
1273 FALSE
, /* pc_relative */
1275 complain_overflow_dont
, /* complain_on_overflow */
1276 bfd_elf_generic_reloc
, /* special_function */
1277 AARCH64_R_STR (LD32_GOT_LO12_NC
), /* name */
1278 FALSE
, /* partial_inplace */
1279 0xffc, /* src_mask */
1280 0xffc, /* dst_mask */
1281 FALSE
), /* pcrel_offset */
1283 /* Lower 16 bits of GOT offset for the symbol. */
1284 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G0_NC
), /* type */
1286 2, /* size (0 = byte, 1 = short, 2 = long) */
1288 FALSE
, /* pc_relative */
1290 complain_overflow_dont
, /* complain_on_overflow */
1291 bfd_elf_generic_reloc
, /* special_function */
1292 AARCH64_R_STR (MOVW_GOTOFF_G0_NC
), /* name */
1293 FALSE
, /* partial_inplace */
1294 0xffff, /* src_mask */
1295 0xffff, /* dst_mask */
1296 FALSE
), /* pcrel_offset */
1298 /* Higher 16 bits of GOT offset for the symbol. */
1299 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G1
), /* type */
1300 16, /* rightshift */
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1303 FALSE
, /* pc_relative */
1305 complain_overflow_unsigned
, /* complain_on_overflow */
1306 bfd_elf_generic_reloc
, /* special_function */
1307 AARCH64_R_STR (MOVW_GOTOFF_G1
), /* name */
1308 FALSE
, /* partial_inplace */
1309 0xffff, /* src_mask */
1310 0xffff, /* dst_mask */
1311 FALSE
), /* pcrel_offset */
1313 /* LD64: GOT offset for the symbol. */
1314 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15
), /* type */
1316 2, /* size (0 = byte, 1 = short, 2 = long) */
1318 FALSE
, /* pc_relative */
1320 complain_overflow_unsigned
, /* complain_on_overflow */
1321 bfd_elf_generic_reloc
, /* special_function */
1322 AARCH64_R_STR (LD64_GOTOFF_LO15
), /* name */
1323 FALSE
, /* partial_inplace */
1324 0x7ff8, /* src_mask */
1325 0x7ff8, /* dst_mask */
1326 FALSE
), /* pcrel_offset */
1328 /* LD32: GOT offset to the page address of GOT table.
1329 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
1330 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14
), /* type */
1332 2, /* size (0 = byte, 1 = short, 2 = long) */
1334 FALSE
, /* pc_relative */
1336 complain_overflow_unsigned
, /* complain_on_overflow */
1337 bfd_elf_generic_reloc
, /* special_function */
1338 AARCH64_R_STR (LD32_GOTPAGE_LO14
), /* name */
1339 FALSE
, /* partial_inplace */
1340 0x5ffc, /* src_mask */
1341 0x5ffc, /* dst_mask */
1342 FALSE
), /* pcrel_offset */
1344 /* LD64: GOT offset to the page address of GOT table.
1345 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
1346 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15
), /* type */
1348 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 FALSE
, /* pc_relative */
1352 complain_overflow_unsigned
, /* complain_on_overflow */
1353 bfd_elf_generic_reloc
, /* special_function */
1354 AARCH64_R_STR (LD64_GOTPAGE_LO15
), /* name */
1355 FALSE
, /* partial_inplace */
1356 0x7ff8, /* src_mask */
1357 0x7ff8, /* dst_mask */
1358 FALSE
), /* pcrel_offset */
1360 /* Get to the page for the GOT entry for the symbol
1361 (G(S) - P) using an ADRP instruction. */
1362 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21
), /* type */
1363 12, /* rightshift */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1366 TRUE
, /* pc_relative */
1368 complain_overflow_dont
, /* complain_on_overflow */
1369 bfd_elf_generic_reloc
, /* special_function */
1370 AARCH64_R_STR (TLSGD_ADR_PAGE21
), /* name */
1371 FALSE
, /* partial_inplace */
1372 0x1fffff, /* src_mask */
1373 0x1fffff, /* dst_mask */
1374 TRUE
), /* pcrel_offset */
1376 HOWTO (AARCH64_R (TLSGD_ADR_PREL21
), /* type */
1378 2, /* size (0 = byte, 1 = short, 2 = long) */
1380 TRUE
, /* pc_relative */
1382 complain_overflow_dont
, /* complain_on_overflow */
1383 bfd_elf_generic_reloc
, /* special_function */
1384 AARCH64_R_STR (TLSGD_ADR_PREL21
), /* name */
1385 FALSE
, /* partial_inplace */
1386 0x1fffff, /* src_mask */
1387 0x1fffff, /* dst_mask */
1388 TRUE
), /* pcrel_offset */
1390 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1391 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC
), /* type */
1393 2, /* size (0 = byte, 1 = short, 2 = long) */
1395 FALSE
, /* pc_relative */
1397 complain_overflow_dont
, /* complain_on_overflow */
1398 bfd_elf_generic_reloc
, /* special_function */
1399 AARCH64_R_STR (TLSGD_ADD_LO12_NC
), /* name */
1400 FALSE
, /* partial_inplace */
1401 0xfff, /* src_mask */
1402 0xfff, /* dst_mask */
1403 FALSE
), /* pcrel_offset */
1405 /* Lower 16 bits of GOT offset to tls_index. */
1406 HOWTO64 (AARCH64_R (TLSGD_MOVW_G0_NC
), /* type */
1408 2, /* size (0 = byte, 1 = short, 2 = long) */
1410 FALSE
, /* pc_relative */
1412 complain_overflow_dont
, /* complain_on_overflow */
1413 bfd_elf_generic_reloc
, /* special_function */
1414 AARCH64_R_STR (TLSGD_MOVW_G0_NC
), /* name */
1415 FALSE
, /* partial_inplace */
1416 0xffff, /* src_mask */
1417 0xffff, /* dst_mask */
1418 FALSE
), /* pcrel_offset */
1420 /* Higher 16 bits of GOT offset to tls_index. */
1421 HOWTO64 (AARCH64_R (TLSGD_MOVW_G1
), /* type */
1422 16, /* rightshift */
1423 2, /* size (0 = byte, 1 = short, 2 = long) */
1425 FALSE
, /* pc_relative */
1427 complain_overflow_unsigned
, /* complain_on_overflow */
1428 bfd_elf_generic_reloc
, /* special_function */
1429 AARCH64_R_STR (TLSGD_MOVW_G1
), /* name */
1430 FALSE
, /* partial_inplace */
1431 0xffff, /* src_mask */
1432 0xffff, /* dst_mask */
1433 FALSE
), /* pcrel_offset */
1435 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21
), /* type */
1436 12, /* rightshift */
1437 2, /* size (0 = byte, 1 = short, 2 = long) */
1439 FALSE
, /* pc_relative */
1441 complain_overflow_dont
, /* complain_on_overflow */
1442 bfd_elf_generic_reloc
, /* special_function */
1443 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21
), /* name */
1444 FALSE
, /* partial_inplace */
1445 0x1fffff, /* src_mask */
1446 0x1fffff, /* dst_mask */
1447 FALSE
), /* pcrel_offset */
1449 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC
), /* type */
1451 2, /* size (0 = byte, 1 = short, 2 = long) */
1453 FALSE
, /* pc_relative */
1455 complain_overflow_dont
, /* complain_on_overflow */
1456 bfd_elf_generic_reloc
, /* special_function */
1457 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC
), /* name */
1458 FALSE
, /* partial_inplace */
1459 0xff8, /* src_mask */
1460 0xff8, /* dst_mask */
1461 FALSE
), /* pcrel_offset */
1463 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC
), /* type */
1465 2, /* size (0 = byte, 1 = short, 2 = long) */
1467 FALSE
, /* pc_relative */
1469 complain_overflow_dont
, /* complain_on_overflow */
1470 bfd_elf_generic_reloc
, /* special_function */
1471 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC
), /* name */
1472 FALSE
, /* partial_inplace */
1473 0xffc, /* src_mask */
1474 0xffc, /* dst_mask */
1475 FALSE
), /* pcrel_offset */
1477 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19
), /* type */
1479 2, /* size (0 = byte, 1 = short, 2 = long) */
1481 FALSE
, /* pc_relative */
1483 complain_overflow_dont
, /* complain_on_overflow */
1484 bfd_elf_generic_reloc
, /* special_function */
1485 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19
), /* name */
1486 FALSE
, /* partial_inplace */
1487 0x1ffffc, /* src_mask */
1488 0x1ffffc, /* dst_mask */
1489 FALSE
), /* pcrel_offset */
1491 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC
), /* type */
1493 2, /* size (0 = byte, 1 = short, 2 = long) */
1495 FALSE
, /* pc_relative */
1497 complain_overflow_dont
, /* complain_on_overflow */
1498 bfd_elf_generic_reloc
, /* special_function */
1499 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC
), /* name */
1500 FALSE
, /* partial_inplace */
1501 0xffff, /* src_mask */
1502 0xffff, /* dst_mask */
1503 FALSE
), /* pcrel_offset */
1505 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1
), /* type */
1506 16, /* rightshift */
1507 2, /* size (0 = byte, 1 = short, 2 = long) */
1509 FALSE
, /* pc_relative */
1511 complain_overflow_unsigned
, /* complain_on_overflow */
1512 bfd_elf_generic_reloc
, /* special_function */
1513 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1
), /* name */
1514 FALSE
, /* partial_inplace */
1515 0xffff, /* src_mask */
1516 0xffff, /* dst_mask */
1517 FALSE
), /* pcrel_offset */
1519 /* ADD: bit[23:12] of byte offset to module TLS base address. */
1520 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12
), /* type */
1521 12, /* rightshift */
1522 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 FALSE
, /* pc_relative */
1526 complain_overflow_unsigned
, /* complain_on_overflow */
1527 bfd_elf_generic_reloc
, /* special_function */
1528 AARCH64_R_STR (TLSLD_ADD_DTPREL_HI12
), /* name */
1529 FALSE
, /* partial_inplace */
1530 0xfff, /* src_mask */
1531 0xfff, /* dst_mask */
1532 FALSE
), /* pcrel_offset */
1534 /* Unsigned 12 bit byte offset to module TLS base address. */
1535 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12
), /* type */
1537 2, /* size (0 = byte, 1 = short, 2 = long) */
1539 FALSE
, /* pc_relative */
1541 complain_overflow_unsigned
, /* complain_on_overflow */
1542 bfd_elf_generic_reloc
, /* special_function */
1543 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12
), /* name */
1544 FALSE
, /* partial_inplace */
1545 0xfff, /* src_mask */
1546 0xfff, /* dst_mask */
1547 FALSE
), /* pcrel_offset */
1549 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1550 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC
), /* type */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1554 FALSE
, /* pc_relative */
1556 complain_overflow_dont
, /* complain_on_overflow */
1557 bfd_elf_generic_reloc
, /* special_function */
1558 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC
), /* name */
1559 FALSE
, /* partial_inplace */
1560 0xfff, /* src_mask */
1561 0xfff, /* dst_mask */
1562 FALSE
), /* pcrel_offset */
1564 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1565 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC
), /* type */
1567 2, /* size (0 = byte, 1 = short, 2 = long) */
1569 FALSE
, /* pc_relative */
1571 complain_overflow_dont
, /* complain_on_overflow */
1572 bfd_elf_generic_reloc
, /* special_function */
1573 AARCH64_R_STR (TLSLD_ADD_LO12_NC
), /* name */
1574 FALSE
, /* partial_inplace */
1575 0xfff, /* src_mask */
1576 0xfff, /* dst_mask */
1577 FALSE
), /* pcrel_offset */
1579 /* Get to the page for the GOT entry for the symbol
1580 (G(S) - P) using an ADRP instruction. */
1581 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21
), /* type */
1582 12, /* rightshift */
1583 2, /* size (0 = byte, 1 = short, 2 = long) */
1585 TRUE
, /* pc_relative */
1587 complain_overflow_signed
, /* complain_on_overflow */
1588 bfd_elf_generic_reloc
, /* special_function */
1589 AARCH64_R_STR (TLSLD_ADR_PAGE21
), /* name */
1590 FALSE
, /* partial_inplace */
1591 0x1fffff, /* src_mask */
1592 0x1fffff, /* dst_mask */
1593 TRUE
), /* pcrel_offset */
1595 HOWTO (AARCH64_R (TLSLD_ADR_PREL21
), /* type */
1597 2, /* size (0 = byte, 1 = short, 2 = long) */
1599 TRUE
, /* pc_relative */
1601 complain_overflow_signed
, /* complain_on_overflow */
1602 bfd_elf_generic_reloc
, /* special_function */
1603 AARCH64_R_STR (TLSLD_ADR_PREL21
), /* name */
1604 FALSE
, /* partial_inplace */
1605 0x1fffff, /* src_mask */
1606 0x1fffff, /* dst_mask */
1607 TRUE
), /* pcrel_offset */
1609 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1610 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12
), /* type */
1612 2, /* size (0 = byte, 1 = short, 2 = long) */
1614 FALSE
, /* pc_relative */
1616 complain_overflow_unsigned
, /* complain_on_overflow */
1617 bfd_elf_generic_reloc
, /* special_function */
1618 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12
), /* name */
1619 FALSE
, /* partial_inplace */
1620 0x1ffc00, /* src_mask */
1621 0x1ffc00, /* dst_mask */
1622 FALSE
), /* pcrel_offset */
1624 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, but no overflow check. */
1625 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12_NC
), /* type */
1627 2, /* size (0 = byte, 1 = short, 2 = long) */
1629 FALSE
, /* pc_relative */
1631 complain_overflow_dont
, /* complain_on_overflow */
1632 bfd_elf_generic_reloc
, /* special_function */
1633 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12_NC
), /* name */
1634 FALSE
, /* partial_inplace */
1635 0x1ffc00, /* src_mask */
1636 0x1ffc00, /* dst_mask */
1637 FALSE
), /* pcrel_offset */
1639 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1640 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12
), /* type */
1642 2, /* size (0 = byte, 1 = short, 2 = long) */
1644 FALSE
, /* pc_relative */
1646 complain_overflow_unsigned
, /* complain_on_overflow */
1647 bfd_elf_generic_reloc
, /* special_function */
1648 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12
), /* name */
1649 FALSE
, /* partial_inplace */
1650 0x3ffc00, /* src_mask */
1651 0x3ffc00, /* dst_mask */
1652 FALSE
), /* pcrel_offset */
1654 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no overflow check. */
1655 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12_NC
), /* type */
1657 2, /* size (0 = byte, 1 = short, 2 = long) */
1659 FALSE
, /* pc_relative */
1661 complain_overflow_dont
, /* complain_on_overflow */
1662 bfd_elf_generic_reloc
, /* special_function */
1663 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12_NC
), /* name */
1664 FALSE
, /* partial_inplace */
1665 0xffc00, /* src_mask */
1666 0xffc00, /* dst_mask */
1667 FALSE
), /* pcrel_offset */
1669 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1670 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12
), /* type */
1672 2, /* size (0 = byte, 1 = short, 2 = long) */
1674 FALSE
, /* pc_relative */
1676 complain_overflow_unsigned
, /* complain_on_overflow */
1677 bfd_elf_generic_reloc
, /* special_function */
1678 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12
), /* name */
1679 FALSE
, /* partial_inplace */
1680 0x3ffc00, /* src_mask */
1681 0x3ffc00, /* dst_mask */
1682 FALSE
), /* pcrel_offset */
1684 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, but no overflow check. */
1685 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12_NC
), /* type */
1687 2, /* size (0 = byte, 1 = short, 2 = long) */
1689 FALSE
, /* pc_relative */
1691 complain_overflow_dont
, /* complain_on_overflow */
1692 bfd_elf_generic_reloc
, /* special_function */
1693 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12_NC
), /* name */
1694 FALSE
, /* partial_inplace */
1695 0x7fc00, /* src_mask */
1696 0x7fc00, /* dst_mask */
1697 FALSE
), /* pcrel_offset */
1699 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1700 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12
), /* type */
1702 2, /* size (0 = byte, 1 = short, 2 = long) */
1704 FALSE
, /* pc_relative */
1706 complain_overflow_unsigned
, /* complain_on_overflow */
1707 bfd_elf_generic_reloc
, /* special_function */
1708 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12
), /* name */
1709 FALSE
, /* partial_inplace */
1710 0x3ffc00, /* src_mask */
1711 0x3ffc00, /* dst_mask */
1712 FALSE
), /* pcrel_offset */
1714 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, but no overflow check. */
1715 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12_NC
), /* type */
1717 2, /* size (0 = byte, 1 = short, 2 = long) */
1719 FALSE
, /* pc_relative */
1721 complain_overflow_dont
, /* complain_on_overflow */
1722 bfd_elf_generic_reloc
, /* special_function */
1723 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12_NC
), /* name */
1724 FALSE
, /* partial_inplace */
1725 0x3ffc00, /* src_mask */
1726 0x3ffc00, /* dst_mask */
1727 FALSE
), /* pcrel_offset */
1729 /* MOVZ: bit[15:0] of byte offset to module TLS base address. */
1730 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0
), /* type */
1732 2, /* size (0 = byte, 1 = short, 2 = long) */
1734 FALSE
, /* pc_relative */
1736 complain_overflow_unsigned
, /* complain_on_overflow */
1737 bfd_elf_generic_reloc
, /* special_function */
1738 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0
), /* name */
1739 FALSE
, /* partial_inplace */
1740 0xffff, /* src_mask */
1741 0xffff, /* dst_mask */
1742 FALSE
), /* pcrel_offset */
1744 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */
1745 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0_NC
), /* type */
1747 2, /* size (0 = byte, 1 = short, 2 = long) */
1749 FALSE
, /* pc_relative */
1751 complain_overflow_dont
, /* complain_on_overflow */
1752 bfd_elf_generic_reloc
, /* special_function */
1753 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0_NC
), /* name */
1754 FALSE
, /* partial_inplace */
1755 0xffff, /* src_mask */
1756 0xffff, /* dst_mask */
1757 FALSE
), /* pcrel_offset */
1759 /* MOVZ: bit[31:16] of byte offset to module TLS base address. */
1760 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G1
), /* type */
1761 16, /* rightshift */
1762 2, /* size (0 = byte, 1 = short, 2 = long) */
1764 FALSE
, /* pc_relative */
1766 complain_overflow_unsigned
, /* complain_on_overflow */
1767 bfd_elf_generic_reloc
, /* special_function */
1768 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1
), /* name */
1769 FALSE
, /* partial_inplace */
1770 0xffff, /* src_mask */
1771 0xffff, /* dst_mask */
1772 FALSE
), /* pcrel_offset */
1774 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */
1775 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G1_NC
), /* type */
1776 16, /* rightshift */
1777 2, /* size (0 = byte, 1 = short, 2 = long) */
1779 FALSE
, /* pc_relative */
1781 complain_overflow_dont
, /* complain_on_overflow */
1782 bfd_elf_generic_reloc
, /* special_function */
1783 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1_NC
), /* name */
1784 FALSE
, /* partial_inplace */
1785 0xffff, /* src_mask */
1786 0xffff, /* dst_mask */
1787 FALSE
), /* pcrel_offset */
1789 /* MOVZ: bit[47:32] of byte offset to module TLS base address. */
1790 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G2
), /* type */
1791 32, /* rightshift */
1792 2, /* size (0 = byte, 1 = short, 2 = long) */
1794 FALSE
, /* pc_relative */
1796 complain_overflow_unsigned
, /* complain_on_overflow */
1797 bfd_elf_generic_reloc
, /* special_function */
1798 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G2
), /* name */
1799 FALSE
, /* partial_inplace */
1800 0xffff, /* src_mask */
1801 0xffff, /* dst_mask */
1802 FALSE
), /* pcrel_offset */
1804 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2
), /* type */
1805 32, /* rightshift */
1806 2, /* size (0 = byte, 1 = short, 2 = long) */
1808 FALSE
, /* pc_relative */
1810 complain_overflow_unsigned
, /* complain_on_overflow */
1811 bfd_elf_generic_reloc
, /* special_function */
1812 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2
), /* name */
1813 FALSE
, /* partial_inplace */
1814 0xffff, /* src_mask */
1815 0xffff, /* dst_mask */
1816 FALSE
), /* pcrel_offset */
1818 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1
), /* type */
1819 16, /* rightshift */
1820 2, /* size (0 = byte, 1 = short, 2 = long) */
1822 FALSE
, /* pc_relative */
1824 complain_overflow_dont
, /* complain_on_overflow */
1825 bfd_elf_generic_reloc
, /* special_function */
1826 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1
), /* name */
1827 FALSE
, /* partial_inplace */
1828 0xffff, /* src_mask */
1829 0xffff, /* dst_mask */
1830 FALSE
), /* pcrel_offset */
1832 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC
), /* type */
1833 16, /* rightshift */
1834 2, /* size (0 = byte, 1 = short, 2 = long) */
1836 FALSE
, /* pc_relative */
1838 complain_overflow_dont
, /* complain_on_overflow */
1839 bfd_elf_generic_reloc
, /* special_function */
1840 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC
), /* name */
1841 FALSE
, /* partial_inplace */
1842 0xffff, /* src_mask */
1843 0xffff, /* dst_mask */
1844 FALSE
), /* pcrel_offset */
1846 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0
), /* type */
1848 2, /* size (0 = byte, 1 = short, 2 = long) */
1850 FALSE
, /* pc_relative */
1852 complain_overflow_dont
, /* complain_on_overflow */
1853 bfd_elf_generic_reloc
, /* special_function */
1854 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0
), /* name */
1855 FALSE
, /* partial_inplace */
1856 0xffff, /* src_mask */
1857 0xffff, /* dst_mask */
1858 FALSE
), /* pcrel_offset */
1860 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
), /* type */
1862 2, /* size (0 = byte, 1 = short, 2 = long) */
1864 FALSE
, /* pc_relative */
1866 complain_overflow_dont
, /* complain_on_overflow */
1867 bfd_elf_generic_reloc
, /* special_function */
1868 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC
), /* name */
1869 FALSE
, /* partial_inplace */
1870 0xffff, /* src_mask */
1871 0xffff, /* dst_mask */
1872 FALSE
), /* pcrel_offset */
1874 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12
), /* type */
1875 12, /* rightshift */
1876 2, /* size (0 = byte, 1 = short, 2 = long) */
1878 FALSE
, /* pc_relative */
1880 complain_overflow_unsigned
, /* complain_on_overflow */
1881 bfd_elf_generic_reloc
, /* special_function */
1882 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12
), /* name */
1883 FALSE
, /* partial_inplace */
1884 0xfff, /* src_mask */
1885 0xfff, /* dst_mask */
1886 FALSE
), /* pcrel_offset */
1888 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12
), /* type */
1890 2, /* size (0 = byte, 1 = short, 2 = long) */
1892 FALSE
, /* pc_relative */
1894 complain_overflow_unsigned
, /* complain_on_overflow */
1895 bfd_elf_generic_reloc
, /* special_function */
1896 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12
), /* name */
1897 FALSE
, /* partial_inplace */
1898 0xfff, /* src_mask */
1899 0xfff, /* dst_mask */
1900 FALSE
), /* pcrel_offset */
1902 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
), /* type */
1904 2, /* size (0 = byte, 1 = short, 2 = long) */
1906 FALSE
, /* pc_relative */
1908 complain_overflow_dont
, /* complain_on_overflow */
1909 bfd_elf_generic_reloc
, /* special_function */
1910 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC
), /* name */
1911 FALSE
, /* partial_inplace */
1912 0xfff, /* src_mask */
1913 0xfff, /* dst_mask */
1914 FALSE
), /* pcrel_offset */
1916 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1917 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12
), /* type */
1919 2, /* size (0 = byte, 1 = short, 2 = long) */
1921 FALSE
, /* pc_relative */
1923 complain_overflow_unsigned
, /* complain_on_overflow */
1924 bfd_elf_generic_reloc
, /* special_function */
1925 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12
), /* name */
1926 FALSE
, /* partial_inplace */
1927 0x1ffc00, /* src_mask */
1928 0x1ffc00, /* dst_mask */
1929 FALSE
), /* pcrel_offset */
1931 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check. */
1932 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12_NC
), /* type */
1934 2, /* size (0 = byte, 1 = short, 2 = long) */
1936 FALSE
, /* pc_relative */
1938 complain_overflow_dont
, /* complain_on_overflow */
1939 bfd_elf_generic_reloc
, /* special_function */
1940 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12_NC
), /* name */
1941 FALSE
, /* partial_inplace */
1942 0x1ffc00, /* src_mask */
1943 0x1ffc00, /* dst_mask */
1944 FALSE
), /* pcrel_offset */
1946 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1947 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12
), /* type */
1949 2, /* size (0 = byte, 1 = short, 2 = long) */
1951 FALSE
, /* pc_relative */
1953 complain_overflow_unsigned
, /* complain_on_overflow */
1954 bfd_elf_generic_reloc
, /* special_function */
1955 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12
), /* name */
1956 FALSE
, /* partial_inplace */
1957 0xffc00, /* src_mask */
1958 0xffc00, /* dst_mask */
1959 FALSE
), /* pcrel_offset */
1961 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check. */
1962 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12_NC
), /* type */
1964 2, /* size (0 = byte, 1 = short, 2 = long) */
1966 FALSE
, /* pc_relative */
1968 complain_overflow_dont
, /* complain_on_overflow */
1969 bfd_elf_generic_reloc
, /* special_function */
1970 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12_NC
), /* name */
1971 FALSE
, /* partial_inplace */
1972 0xffc00, /* src_mask */
1973 0xffc00, /* dst_mask */
1974 FALSE
), /* pcrel_offset */
1976 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1977 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12
), /* type */
1979 2, /* size (0 = byte, 1 = short, 2 = long) */
1981 FALSE
, /* pc_relative */
1983 complain_overflow_unsigned
, /* complain_on_overflow */
1984 bfd_elf_generic_reloc
, /* special_function */
1985 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12
), /* name */
1986 FALSE
, /* partial_inplace */
1987 0x7fc00, /* src_mask */
1988 0x7fc00, /* dst_mask */
1989 FALSE
), /* pcrel_offset */
1991 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check. */
1992 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12_NC
), /* type */
1994 2, /* size (0 = byte, 1 = short, 2 = long) */
1996 FALSE
, /* pc_relative */
1998 complain_overflow_dont
, /* complain_on_overflow */
1999 bfd_elf_generic_reloc
, /* special_function */
2000 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12_NC
), /* name */
2001 FALSE
, /* partial_inplace */
2002 0x7fc00, /* src_mask */
2003 0x7fc00, /* dst_mask */
2004 FALSE
), /* pcrel_offset */
2006 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
2007 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12
), /* type */
2009 2, /* size (0 = byte, 1 = short, 2 = long) */
2011 FALSE
, /* pc_relative */
2013 complain_overflow_unsigned
, /* complain_on_overflow */
2014 bfd_elf_generic_reloc
, /* special_function */
2015 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12
), /* name */
2016 FALSE
, /* partial_inplace */
2017 0x3ffc00, /* src_mask */
2018 0x3ffc00, /* dst_mask */
2019 FALSE
), /* pcrel_offset */
2021 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check. */
2022 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12_NC
), /* type */
2024 2, /* size (0 = byte, 1 = short, 2 = long) */
2026 FALSE
, /* pc_relative */
2028 complain_overflow_dont
, /* complain_on_overflow */
2029 bfd_elf_generic_reloc
, /* special_function */
2030 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12_NC
), /* name */
2031 FALSE
, /* partial_inplace */
2032 0x3ffc00, /* src_mask */
2033 0x3ffc00, /* dst_mask */
2034 FALSE
), /* pcrel_offset */
2036 HOWTO (AARCH64_R (TLSDESC_LD_PREL19
), /* type */
2038 2, /* size (0 = byte, 1 = short, 2 = long) */
2040 TRUE
, /* pc_relative */
2042 complain_overflow_dont
, /* complain_on_overflow */
2043 bfd_elf_generic_reloc
, /* special_function */
2044 AARCH64_R_STR (TLSDESC_LD_PREL19
), /* name */
2045 FALSE
, /* partial_inplace */
2046 0x0ffffe0, /* src_mask */
2047 0x0ffffe0, /* dst_mask */
2048 TRUE
), /* pcrel_offset */
2050 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21
), /* type */
2052 2, /* size (0 = byte, 1 = short, 2 = long) */
2054 TRUE
, /* pc_relative */
2056 complain_overflow_dont
, /* complain_on_overflow */
2057 bfd_elf_generic_reloc
, /* special_function */
2058 AARCH64_R_STR (TLSDESC_ADR_PREL21
), /* name */
2059 FALSE
, /* partial_inplace */
2060 0x1fffff, /* src_mask */
2061 0x1fffff, /* dst_mask */
2062 TRUE
), /* pcrel_offset */
2064 /* Get to the page for the GOT entry for the symbol
2065 (G(S) - P) using an ADRP instruction. */
2066 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21
), /* type */
2067 12, /* rightshift */
2068 2, /* size (0 = byte, 1 = short, 2 = long) */
2070 TRUE
, /* pc_relative */
2072 complain_overflow_dont
, /* complain_on_overflow */
2073 bfd_elf_generic_reloc
, /* special_function */
2074 AARCH64_R_STR (TLSDESC_ADR_PAGE21
), /* name */
2075 FALSE
, /* partial_inplace */
2076 0x1fffff, /* src_mask */
2077 0x1fffff, /* dst_mask */
2078 TRUE
), /* pcrel_offset */
2080 /* LD64: GOT offset G(S) & 0xff8. */
2081 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12
), /* type */
2083 2, /* size (0 = byte, 1 = short, 2 = long) */
2085 FALSE
, /* pc_relative */
2087 complain_overflow_dont
, /* complain_on_overflow */
2088 bfd_elf_generic_reloc
, /* special_function */
2089 AARCH64_R_STR (TLSDESC_LD64_LO12
), /* name */
2090 FALSE
, /* partial_inplace */
2091 0xff8, /* src_mask */
2092 0xff8, /* dst_mask */
2093 FALSE
), /* pcrel_offset */
2095 /* LD32: GOT offset G(S) & 0xffc. */
2096 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC
), /* type */
2098 2, /* size (0 = byte, 1 = short, 2 = long) */
2100 FALSE
, /* pc_relative */
2102 complain_overflow_dont
, /* complain_on_overflow */
2103 bfd_elf_generic_reloc
, /* special_function */
2104 AARCH64_R_STR (TLSDESC_LD32_LO12_NC
), /* name */
2105 FALSE
, /* partial_inplace */
2106 0xffc, /* src_mask */
2107 0xffc, /* dst_mask */
2108 FALSE
), /* pcrel_offset */
2110 /* ADD: GOT offset G(S) & 0xfff. */
2111 HOWTO (AARCH64_R (TLSDESC_ADD_LO12
), /* type */
2113 2, /* size (0 = byte, 1 = short, 2 = long) */
2115 FALSE
, /* pc_relative */
2117 complain_overflow_dont
,/* complain_on_overflow */
2118 bfd_elf_generic_reloc
, /* special_function */
2119 AARCH64_R_STR (TLSDESC_ADD_LO12
), /* name */
2120 FALSE
, /* partial_inplace */
2121 0xfff, /* src_mask */
2122 0xfff, /* dst_mask */
2123 FALSE
), /* pcrel_offset */
2125 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1
), /* type */
2126 16, /* rightshift */
2127 2, /* size (0 = byte, 1 = short, 2 = long) */
2129 FALSE
, /* pc_relative */
2131 complain_overflow_unsigned
, /* complain_on_overflow */
2132 bfd_elf_generic_reloc
, /* special_function */
2133 AARCH64_R_STR (TLSDESC_OFF_G1
), /* name */
2134 FALSE
, /* partial_inplace */
2135 0xffff, /* src_mask */
2136 0xffff, /* dst_mask */
2137 FALSE
), /* pcrel_offset */
2139 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC
), /* type */
2141 2, /* size (0 = byte, 1 = short, 2 = long) */
2143 FALSE
, /* pc_relative */
2145 complain_overflow_dont
, /* complain_on_overflow */
2146 bfd_elf_generic_reloc
, /* special_function */
2147 AARCH64_R_STR (TLSDESC_OFF_G0_NC
), /* name */
2148 FALSE
, /* partial_inplace */
2149 0xffff, /* src_mask */
2150 0xffff, /* dst_mask */
2151 FALSE
), /* pcrel_offset */
2153 HOWTO64 (AARCH64_R (TLSDESC_LDR
), /* type */
2155 2, /* size (0 = byte, 1 = short, 2 = long) */
2157 FALSE
, /* pc_relative */
2159 complain_overflow_dont
, /* complain_on_overflow */
2160 bfd_elf_generic_reloc
, /* special_function */
2161 AARCH64_R_STR (TLSDESC_LDR
), /* name */
2162 FALSE
, /* partial_inplace */
2165 FALSE
), /* pcrel_offset */
2167 HOWTO64 (AARCH64_R (TLSDESC_ADD
), /* type */
2169 2, /* size (0 = byte, 1 = short, 2 = long) */
2171 FALSE
, /* pc_relative */
2173 complain_overflow_dont
, /* complain_on_overflow */
2174 bfd_elf_generic_reloc
, /* special_function */
2175 AARCH64_R_STR (TLSDESC_ADD
), /* name */
2176 FALSE
, /* partial_inplace */
2179 FALSE
), /* pcrel_offset */
2181 HOWTO (AARCH64_R (TLSDESC_CALL
), /* type */
2183 2, /* size (0 = byte, 1 = short, 2 = long) */
2185 FALSE
, /* pc_relative */
2187 complain_overflow_dont
, /* complain_on_overflow */
2188 bfd_elf_generic_reloc
, /* special_function */
2189 AARCH64_R_STR (TLSDESC_CALL
), /* name */
2190 FALSE
, /* partial_inplace */
2193 FALSE
), /* pcrel_offset */
2195 /* Get to the page for the GOT entry for the symbol
2196 (G(S) - P) using an ADRP instruction. */
2197 HOWTO64 (MORELLO_R (TLSDESC_ADR_PAGE20
), /* type */
2198 12, /* rightshift */
2199 2, /* size (0 = byte, 1 = short, 2 = long) */
2201 TRUE
, /* pc_relative */
2203 complain_overflow_dont
, /* complain_on_overflow */
2204 bfd_elf_generic_reloc
, /* special_function */
2205 MORELLO_R_STR (TLSDESC_ADR_PAGE20
), /* name */
2206 FALSE
, /* partial_inplace */
2207 0xfffff, /* src_mask */
2208 0xfffff, /* dst_mask */
2209 TRUE
), /* pcrel_offset */
2211 /* LD128: GOT offset G(S) & 0xff0. */
2212 HOWTO64 (MORELLO_R (TLSDESC_LD128_LO12
), /* type */
2214 2, /* size (0 = byte, 1 = short, 2 = long) */
2216 FALSE
, /* pc_relative */
2218 complain_overflow_dont
, /* complain_on_overflow */
2219 bfd_elf_generic_reloc
, /* special_function */
2220 MORELLO_R_STR (TLSDESC_LD128_LO12
), /* name */
2221 FALSE
, /* partial_inplace */
2222 0xff0, /* src_mask */
2223 0xff0, /* dst_mask */
2224 FALSE
), /* pcrel_offset */
2226 HOWTO64 (MORELLO_R (TLSDESC_CALL
), /* type */
2228 2, /* size (0 = byte, 1 = short, 2 = long) */
2230 FALSE
, /* pc_relative */
2232 complain_overflow_dont
, /* complain_on_overflow */
2233 bfd_elf_generic_reloc
, /* special_function */
2234 MORELLO_R_STR (TLSDESC_CALL
), /* name */
2235 FALSE
, /* partial_inplace */
2238 FALSE
), /* pcrel_offset */
2240 HOWTO (AARCH64_R (COPY
), /* type */
2242 2, /* size (0 = byte, 1 = short, 2 = long) */
2244 FALSE
, /* pc_relative */
2246 complain_overflow_bitfield
, /* complain_on_overflow */
2247 bfd_elf_generic_reloc
, /* special_function */
2248 AARCH64_R_STR (COPY
), /* name */
2249 TRUE
, /* partial_inplace */
2250 0xffffffff, /* src_mask */
2251 0xffffffff, /* dst_mask */
2252 FALSE
), /* pcrel_offset */
2254 HOWTO (AARCH64_R (GLOB_DAT
), /* type */
2256 2, /* size (0 = byte, 1 = short, 2 = long) */
2258 FALSE
, /* pc_relative */
2260 complain_overflow_bitfield
, /* complain_on_overflow */
2261 bfd_elf_generic_reloc
, /* special_function */
2262 AARCH64_R_STR (GLOB_DAT
), /* name */
2263 TRUE
, /* partial_inplace */
2264 0xffffffff, /* src_mask */
2265 0xffffffff, /* dst_mask */
2266 FALSE
), /* pcrel_offset */
2268 HOWTO (AARCH64_R (JUMP_SLOT
), /* type */
2270 2, /* size (0 = byte, 1 = short, 2 = long) */
2272 FALSE
, /* pc_relative */
2274 complain_overflow_bitfield
, /* complain_on_overflow */
2275 bfd_elf_generic_reloc
, /* special_function */
2276 AARCH64_R_STR (JUMP_SLOT
), /* name */
2277 TRUE
, /* partial_inplace */
2278 0xffffffff, /* src_mask */
2279 0xffffffff, /* dst_mask */
2280 FALSE
), /* pcrel_offset */
2282 HOWTO (AARCH64_R (RELATIVE
), /* type */
2284 2, /* size (0 = byte, 1 = short, 2 = long) */
2286 FALSE
, /* pc_relative */
2288 complain_overflow_bitfield
, /* complain_on_overflow */
2289 bfd_elf_generic_reloc
, /* special_function */
2290 AARCH64_R_STR (RELATIVE
), /* name */
2291 TRUE
, /* partial_inplace */
2292 ALL_ONES
, /* src_mask */
2293 ALL_ONES
, /* dst_mask */
2294 FALSE
), /* pcrel_offset */
2296 HOWTO (AARCH64_R (TLS_DTPMOD
), /* type */
2298 2, /* size (0 = byte, 1 = short, 2 = long) */
2300 FALSE
, /* pc_relative */
2302 complain_overflow_dont
, /* complain_on_overflow */
2303 bfd_elf_generic_reloc
, /* special_function */
2305 AARCH64_R_STR (TLS_DTPMOD64
), /* name */
2307 AARCH64_R_STR (TLS_DTPMOD
), /* name */
2309 FALSE
, /* partial_inplace */
2311 ALL_ONES
, /* dst_mask */
2312 FALSE
), /* pc_reloffset */
2314 HOWTO (AARCH64_R (TLS_DTPREL
), /* type */
2316 2, /* size (0 = byte, 1 = short, 2 = long) */
2318 FALSE
, /* pc_relative */
2320 complain_overflow_dont
, /* complain_on_overflow */
2321 bfd_elf_generic_reloc
, /* special_function */
2323 AARCH64_R_STR (TLS_DTPREL64
), /* name */
2325 AARCH64_R_STR (TLS_DTPREL
), /* name */
2327 FALSE
, /* partial_inplace */
2329 ALL_ONES
, /* dst_mask */
2330 FALSE
), /* pcrel_offset */
2332 HOWTO (AARCH64_R (TLS_TPREL
), /* type */
2334 2, /* size (0 = byte, 1 = short, 2 = long) */
2336 FALSE
, /* pc_relative */
2338 complain_overflow_dont
, /* complain_on_overflow */
2339 bfd_elf_generic_reloc
, /* special_function */
2341 AARCH64_R_STR (TLS_TPREL64
), /* name */
2343 AARCH64_R_STR (TLS_TPREL
), /* name */
2345 FALSE
, /* partial_inplace */
2347 ALL_ONES
, /* dst_mask */
2348 FALSE
), /* pcrel_offset */
2350 HOWTO (AARCH64_R (TLSDESC
), /* type */
2352 2, /* size (0 = byte, 1 = short, 2 = long) */
2354 FALSE
, /* pc_relative */
2356 complain_overflow_dont
, /* complain_on_overflow */
2357 bfd_elf_generic_reloc
, /* special_function */
2358 AARCH64_R_STR (TLSDESC
), /* name */
2359 FALSE
, /* partial_inplace */
2361 ALL_ONES
, /* dst_mask */
2362 FALSE
), /* pcrel_offset */
2364 HOWTO (AARCH64_R (IRELATIVE
), /* type */
2366 2, /* size (0 = byte, 1 = short, 2 = long) */
2368 FALSE
, /* pc_relative */
2370 complain_overflow_bitfield
, /* complain_on_overflow */
2371 bfd_elf_generic_reloc
, /* special_function */
2372 AARCH64_R_STR (IRELATIVE
), /* name */
2373 FALSE
, /* partial_inplace */
2375 ALL_ONES
, /* dst_mask */
2376 FALSE
), /* pcrel_offset */
2378 HOWTO64 (MORELLO_R (CAPINIT
), /* type */
2380 4, /* size (0 = byte, 1 = short, 2 = long) */
2382 FALSE
, /* pc_relative */
2384 complain_overflow_dont
, /* complain_on_overflow */
2385 bfd_elf_generic_reloc
, /* special_function */
2386 MORELLO_R_STR (CAPINIT
), /* name */
2387 FALSE
, /* partial_inplace */
2388 ALL_ONES
, /* src_mask */
2389 ALL_ONES
, /* dst_mask */
2390 FALSE
), /* pcrel_offset */
2392 HOWTO64 (MORELLO_R (GLOB_DAT
),/* type */
2394 2, /* size (0 = byte, 1 = short, 2 = long) */
2396 FALSE
, /* pc_relative */
2398 complain_overflow_bitfield
, /* complain_on_overflow */
2399 bfd_elf_generic_reloc
, /* special_function */
2400 MORELLO_R_STR (GLOB_DAT
), /* name */
2401 TRUE
, /* partial_inplace */
2402 0xffffffff, /* src_mask */
2403 0xffffffff, /* dst_mask */
2404 FALSE
), /* pcrel_offset */
2406 HOWTO64 (MORELLO_R (JUMP_SLOT
), /* type */
2408 2, /* size (0 = byte, 1 = short, 2 = long) */
2410 FALSE
, /* pc_relative */
2412 complain_overflow_bitfield
, /* complain_on_overflow */
2413 bfd_elf_generic_reloc
, /* special_function */
2414 MORELLO_R_STR (JUMP_SLOT
), /* name */
2415 TRUE
, /* partial_inplace */
2416 0xffffffff, /* src_mask */
2417 0xffffffff, /* dst_mask */
2418 FALSE
), /* pcrel_offset */
2420 HOWTO64 (MORELLO_R (RELATIVE
), /* type */
2422 2, /* size (0 = byte, 1 = short, 2 = long) */
2424 FALSE
, /* pc_relative */
2426 complain_overflow_bitfield
, /* complain_on_overflow */
2427 bfd_elf_generic_reloc
, /* special_function */
2428 MORELLO_R_STR (RELATIVE
), /* name */
2429 TRUE
, /* partial_inplace */
2430 ALL_ONES
, /* src_mask */
2431 ALL_ONES
, /* dst_mask */
2432 FALSE
), /* pcrel_offset */
2434 HOWTO64 (MORELLO_R (IRELATIVE
), /* type */
2436 2, /* size (0 = byte, 1 = short, 2 = long) */
2438 FALSE
, /* pc_relative */
2440 complain_overflow_bitfield
, /* complain_on_overflow */
2441 bfd_elf_generic_reloc
, /* special_function */
2442 MORELLO_R_STR (IRELATIVE
), /* name */
2443 FALSE
, /* partial_inplace */
2445 ALL_ONES
, /* dst_mask */
2446 FALSE
), /* pcrel_offset */
2448 HOWTO64 (MORELLO_R (TLSDESC
), /* type */
2450 2, /* size (0 = byte, 1 = short, 2 = long) */
2452 FALSE
, /* pc_relative */
2454 complain_overflow_dont
, /* complain_on_overflow */
2455 bfd_elf_generic_reloc
, /* special_function */
2456 MORELLO_R_STR (TLSDESC
), /* name */
2457 FALSE
, /* partial_inplace */
2459 ALL_ONES
, /* dst_mask */
2460 FALSE
), /* pcrel_offset */
2465 static reloc_howto_type elfNN_aarch64_howto_none
=
2466 HOWTO (R_AARCH64_NONE
, /* type */
2468 3, /* size (0 = byte, 1 = short, 2 = long) */
2470 FALSE
, /* pc_relative */
2472 complain_overflow_dont
,/* complain_on_overflow */
2473 bfd_elf_generic_reloc
, /* special_function */
2474 "R_AARCH64_NONE", /* name */
2475 FALSE
, /* partial_inplace */
2478 FALSE
); /* pcrel_offset */
2480 /* Given HOWTO, return the bfd internal relocation enumerator. */
2482 static bfd_reloc_code_real_type
2483 elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type
*howto
)
2486 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table
);
2487 const ptrdiff_t offset
2488 = howto
- elfNN_aarch64_howto_table
;
2490 if (offset
> 0 && offset
< size
- 1)
2491 return BFD_RELOC_AARCH64_RELOC_START
+ offset
;
2493 if (howto
== &elfNN_aarch64_howto_none
)
2494 return BFD_RELOC_AARCH64_NONE
;
2496 return BFD_RELOC_AARCH64_RELOC_START
;
2499 /* Given R_TYPE, return the bfd internal relocation enumerator. */
2501 static bfd_reloc_code_real_type
2502 elfNN_aarch64_bfd_reloc_from_type (bfd
*abfd
, unsigned int r_type
)
2504 static bfd_boolean initialized_p
= FALSE
;
2505 /* Indexed by R_TYPE, values are offsets in the howto_table. */
2506 static unsigned int offsets
[R_AARCH64_end
];
2512 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
2513 if (elfNN_aarch64_howto_table
[i
].type
!= 0)
2514 offsets
[elfNN_aarch64_howto_table
[i
].type
] = i
;
2516 initialized_p
= TRUE
;
2519 if (r_type
== R_AARCH64_NONE
|| r_type
== R_AARCH64_NULL
)
2520 return BFD_RELOC_AARCH64_NONE
;
2522 /* PR 17512: file: b371e70a. */
2523 if (r_type
>= R_AARCH64_end
)
2525 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
2527 bfd_set_error (bfd_error_bad_value
);
2528 return BFD_RELOC_AARCH64_NONE
;
2531 return BFD_RELOC_AARCH64_RELOC_START
+ offsets
[r_type
];
2534 struct elf_aarch64_reloc_map
2536 bfd_reloc_code_real_type from
;
2537 bfd_reloc_code_real_type to
;
2540 /* Map bfd generic reloc to AArch64-specific reloc. */
2541 static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map
[] =
2543 {BFD_RELOC_NONE
, BFD_RELOC_AARCH64_NONE
},
2545 /* Basic data relocations. */
2546 {BFD_RELOC_CTOR
, BFD_RELOC_AARCH64_NN
},
2547 {BFD_RELOC_64
, BFD_RELOC_AARCH64_64
},
2548 {BFD_RELOC_32
, BFD_RELOC_AARCH64_32
},
2549 {BFD_RELOC_16
, BFD_RELOC_AARCH64_16
},
2550 {BFD_RELOC_64_PCREL
, BFD_RELOC_AARCH64_64_PCREL
},
2551 {BFD_RELOC_32_PCREL
, BFD_RELOC_AARCH64_32_PCREL
},
2552 {BFD_RELOC_16_PCREL
, BFD_RELOC_AARCH64_16_PCREL
},
2555 /* Given the bfd internal relocation enumerator in CODE, return the
2556 corresponding howto entry. */
2558 static reloc_howto_type
*
2559 elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code
)
2563 /* Convert bfd generic reloc to AArch64-specific reloc. */
2564 if (code
< BFD_RELOC_AARCH64_RELOC_START
2565 || code
> BFD_RELOC_AARCH64_RELOC_END
)
2566 for (i
= 0; i
< ARRAY_SIZE (elf_aarch64_reloc_map
); i
++)
2567 if (elf_aarch64_reloc_map
[i
].from
== code
)
2569 code
= elf_aarch64_reloc_map
[i
].to
;
2573 if (code
> BFD_RELOC_AARCH64_RELOC_START
2574 && code
< BFD_RELOC_AARCH64_RELOC_END
)
2575 if (elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
].type
)
2576 return &elfNN_aarch64_howto_table
[code
- BFD_RELOC_AARCH64_RELOC_START
];
2578 if (code
== BFD_RELOC_AARCH64_NONE
)
2579 return &elfNN_aarch64_howto_none
;
2584 static reloc_howto_type
*
2585 elfNN_aarch64_howto_from_type (bfd
*abfd
, unsigned int r_type
)
2587 bfd_reloc_code_real_type val
;
2588 reloc_howto_type
*howto
;
2593 bfd_set_error (bfd_error_bad_value
);
2598 if (r_type
== R_AARCH64_NONE
)
2599 return &elfNN_aarch64_howto_none
;
2601 val
= elfNN_aarch64_bfd_reloc_from_type (abfd
, r_type
);
2602 howto
= elfNN_aarch64_howto_from_bfd_reloc (val
);
2607 bfd_set_error (bfd_error_bad_value
);
2612 elfNN_aarch64_info_to_howto (bfd
*abfd
, arelent
*bfd_reloc
,
2613 Elf_Internal_Rela
*elf_reloc
)
2615 unsigned int r_type
;
2617 r_type
= ELFNN_R_TYPE (elf_reloc
->r_info
);
2618 bfd_reloc
->howto
= elfNN_aarch64_howto_from_type (abfd
, r_type
);
2620 if (bfd_reloc
->howto
== NULL
)
2622 /* xgettext:c-format */
2623 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd
, r_type
);
2629 static reloc_howto_type
*
2630 elfNN_aarch64_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2631 bfd_reloc_code_real_type code
)
2633 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (code
);
2638 bfd_set_error (bfd_error_bad_value
);
2642 static reloc_howto_type
*
2643 elfNN_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2648 for (i
= 1; i
< ARRAY_SIZE (elfNN_aarch64_howto_table
) - 1; ++i
)
2649 if (elfNN_aarch64_howto_table
[i
].name
!= NULL
2650 && strcasecmp (elfNN_aarch64_howto_table
[i
].name
, r_name
) == 0)
2651 return &elfNN_aarch64_howto_table
[i
];
2656 #define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
2657 #define TARGET_LITTLE_NAME "elfNN-littleaarch64"
2658 #define TARGET_BIG_SYM aarch64_elfNN_be_vec
2659 #define TARGET_BIG_NAME "elfNN-bigaarch64"
2661 /* The linker script knows the section names for placement.
2662 The entry_names are used to do simple name mangling on the stubs.
2663 Given a function name, and its type, the stub can be found. The
2664 name can be changed. The only requirement is the %s be present. */
2665 #define STUB_ENTRY_NAME "__%s%s_veneer"
2667 /* The name of the dynamic interpreter. This is put in the .interp
2669 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
2671 #define AARCH64_MAX_FWD_BRANCH_OFFSET \
2672 (((1 << 25) - 1) << 2)
2673 #define AARCH64_MAX_BWD_BRANCH_OFFSET \
2676 #define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
2677 #define AARCH64_MIN_ADRP_IMM (-(1 << 20))
2679 #define C64_MAX_ADRP_IMM ((1 << 19) - 1)
2680 #define C64_MIN_ADRP_IMM (-(1 << 19))
2683 aarch64_branch_reloc_p (unsigned int r_type
)
2687 case MORELLO_R (JUMP26
):
2688 case MORELLO_R (CALL26
):
2689 case AARCH64_R (JUMP26
):
2690 case AARCH64_R (CALL26
):
2700 aarch64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
2702 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
2703 return offset
<= AARCH64_MAX_ADRP_IMM
&& offset
>= AARCH64_MIN_ADRP_IMM
;
2707 c64_valid_for_adrp_p (bfd_vma value
, bfd_vma place
)
2709 bfd_signed_vma offset
= (bfd_signed_vma
) (PG (value
) - PG (place
)) >> 12;
2710 return offset
<= C64_MAX_ADRP_IMM
&& offset
>= C64_MIN_ADRP_IMM
;
2714 aarch64_valid_branch_p (bfd_vma value
, bfd_vma place
)
2716 bfd_signed_vma offset
= (bfd_signed_vma
) (value
- place
);
2717 return (offset
<= AARCH64_MAX_FWD_BRANCH_OFFSET
2718 && offset
>= AARCH64_MAX_BWD_BRANCH_OFFSET
);
2721 static const uint32_t aarch64_adrp_branch_stub
[] =
2723 0x90000010, /* adrp ip0, X */
2724 /* R_AARCH64_ADR_HI21_PCREL(X) */
2725 0x91000210, /* add ip0, ip0, :lo12:X */
2726 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2727 0xd61f0200, /* br ip0 */
2730 static const uint32_t aarch64_long_branch_stub
[] =
2733 0x58000090, /* ldr ip0, 1f */
2735 0x18000090, /* ldr wip0, 1f */
2737 0x10000011, /* adr ip1, #0 */
2738 0x8b110210, /* add ip0, ip0, ip1 */
2739 0xd61f0200, /* br ip0 */
2740 0x00000000, /* 1: .xword or .word
2741 R_AARCH64_PRELNN(X) + 12
2746 static const uint32_t aarch64_erratum_835769_stub
[] =
2748 0x00000000, /* Placeholder for multiply accumulate. */
2749 0x14000000, /* b <label> */
2752 static const uint32_t aarch64_erratum_843419_stub
[] =
2754 0x00000000, /* Placeholder for LDR instruction. */
2755 0x14000000, /* b <label> */
2758 static const uint32_t aarch64_c64_branch_stub
[] =
2760 0xc2c273e0, /* bx #4 */
2761 0x90800010, /* adrp c16, X */
2762 /* R_MORELLO_ADR_HI20_PCREL(X) */
2763 0x02000210, /* add c16, c16, :lo12:X */
2764 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2765 0xc2c21200, /* br c16 */
2768 static const uint32_t c64_aarch64_branch_stub
[] =
2770 0x90800010, /* adrp c16, X */
2771 /* R_MORELLO_ADR_HI20_PCREL(X) */
2772 0x02000210, /* add c16, c16, :lo12:X */
2773 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2774 0xc2c21200, /* br c16 */
2777 /* Section name for stubs is the associated section name plus this
2779 #define STUB_SUFFIX ".stub"
2781 enum elf_aarch64_stub_type
2784 aarch64_stub_adrp_branch
,
2785 aarch64_stub_long_branch
,
2786 aarch64_stub_erratum_835769_veneer
,
2787 aarch64_stub_erratum_843419_veneer
,
2788 aarch64_stub_branch_c64
,
2789 c64_stub_branch_aarch64
,
2790 c64_stub_branch_c64
,
2793 struct elf_aarch64_stub_hash_entry
2795 /* Base hash table entry structure. */
2796 struct bfd_hash_entry root
;
2798 /* The stub section. */
2801 /* Offset within stub_sec of the beginning of this stub. */
2802 bfd_vma stub_offset
;
2804 /* Given the symbol's value and its section we can determine its final
2805 value when building the stubs (so the stub knows where to jump). */
2806 bfd_vma target_value
;
2807 asection
*target_section
;
2809 enum elf_aarch64_stub_type stub_type
;
2811 /* The symbol table entry, if any, that this was derived from. */
2812 struct elf_aarch64_link_hash_entry
*h
;
2814 /* Destination symbol type */
2815 unsigned char st_type
;
2817 /* Where this stub is being called from, or, in the case of combined
2818 stub sections, the first input section in the group. */
2821 /* The name for the local symbol at the start of this stub. The
2822 stub name in the hash table has to be unique; this does not, so
2823 it can be friendlier. */
2826 /* The instruction which caused this stub to be generated (only valid for
2827 erratum 835769 workaround stubs at present). */
2828 uint32_t veneered_insn
;
2830 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
2831 bfd_vma adrp_offset
;
2834 /* Used to build a map of a section. This is required for mixed-endian
2837 typedef struct elf_elf_section_map
2842 elf_aarch64_section_map
;
2845 typedef struct _aarch64_elf_section_data
2847 struct bfd_elf_section_data elf
;
2848 unsigned int mapcount
;
2849 unsigned int mapsize
;
2850 elf_aarch64_section_map
*map
;
2853 _aarch64_elf_section_data
;
2855 #define elf_aarch64_section_data(sec) \
2856 ((_aarch64_elf_section_data *) elf_section_data (sec))
2858 /* Used to order a list of mapping symbols by address. */
2861 elf_aarch64_compare_mapping (const void *a
, const void *b
)
2863 const elf_aarch64_section_map
*amap
= (const elf_aarch64_section_map
*) a
;
2864 const elf_aarch64_section_map
*bmap
= (const elf_aarch64_section_map
*) b
;
2866 if (amap
->vma
> bmap
->vma
)
2868 else if (amap
->vma
< bmap
->vma
)
2870 else if (amap
->type
> bmap
->type
)
2871 /* Ensure results do not depend on the host qsort for objects with
2872 multiple mapping symbols at the same address by sorting on type
2875 else if (amap
->type
< bmap
->type
)
2881 static _aarch64_elf_section_data
*
2882 elf_aarch64_section_data_get (asection
*sec
)
2884 _aarch64_elf_section_data
*sec_data
= elf_aarch64_section_data(sec
);
2886 /* A section that does not have aarch64 section data, so it does not have any
2887 map information. Assume A64. */
2888 if (sec_data
== NULL
|| !sec_data
->elf
.is_target_section_data
)
2891 if (sec_data
->sorted
)
2894 qsort (sec_data
->map
, sec_data
->mapcount
, sizeof (elf_aarch64_section_map
),
2895 elf_aarch64_compare_mapping
);
2897 sec_data
->sorted
= TRUE
;
2903 /* Returns TRUE if the label with st_value as VALUE is within a C64 code
2907 c64_value_p (asection
*section
, unsigned int value
)
2909 struct _aarch64_elf_section_data
*sec_data
=
2910 elf_aarch64_section_data_get (section
);
2912 if (sec_data
== NULL
)
2917 for (span
= 0; span
< sec_data
->mapcount
; span
++)
2919 unsigned int span_start
= sec_data
->map
[span
].vma
;
2920 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
2921 ? sec_data
->map
[0].vma
+ section
->size
2922 : sec_data
->map
[span
+ 1].vma
);
2923 char span_type
= sec_data
->map
[span
].type
;
2925 if (span_start
<= value
&& value
< span_end
&& span_type
== 'c')
2931 /* The size of the thread control block which is defined to be two pointers. */
2932 #define TCB_SIZE (ARCH_SIZE/8)*2
2934 struct elf_aarch64_local_symbol
2936 unsigned int got_type
;
2937 bfd_signed_vma got_refcount
;
2940 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2941 offset is from the end of the jump table and reserved entries
2944 The magic value (bfd_vma) -1 indicates that an offset has not be
2946 bfd_vma tlsdesc_got_jump_table_offset
;
2949 struct elf_aarch64_obj_tdata
2951 struct elf_obj_tdata root
;
2953 /* local symbol descriptors */
2954 struct elf_aarch64_local_symbol
*locals
;
2956 /* Zero to warn when linking objects with incompatible enum sizes. */
2957 int no_enum_size_warning
;
2959 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
2960 int no_wchar_size_warning
;
2962 /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties. */
2963 uint32_t gnu_and_prop
;
2965 /* Zero to warn when linking objects with incompatible
2966 GNU_PROPERTY_AARCH64_FEATURE_1_BTI. */
2969 /* PLT type based on security. */
2970 aarch64_plt_type plt_type
;
2972 /* Flag to check if section maps have been initialised for all sections in
2974 bfd_boolean secmaps_initialised
;
2977 #define elf_aarch64_tdata(bfd) \
2978 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
2980 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
2982 #define is_aarch64_elf(bfd) \
2983 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2984 && elf_tdata (bfd) != NULL \
2985 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2988 elfNN_aarch64_mkobject (bfd
*abfd
)
2990 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
),
2994 #define elf_aarch64_hash_entry(ent) \
2995 ((struct elf_aarch64_link_hash_entry *)(ent))
2997 #define GOT_UNKNOWN 0
2998 #define GOT_NORMAL 1
2999 #define GOT_TLS_GD 2
3000 #define GOT_TLS_IE 4
3001 #define GOT_TLSDESC_GD 8
3004 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
3006 /* AArch64 ELF linker hash entry. */
3007 struct elf_aarch64_link_hash_entry
3009 struct elf_link_hash_entry root
;
3011 /* Since PLT entries have variable size, we need to record the
3012 index into .got.plt instead of recomputing it from the PLT
3014 bfd_signed_vma plt_got_offset
;
3016 /* Bit mask representing the type of GOT entry(s) if any required by
3018 unsigned int got_type
;
3020 /* A pointer to the most recently used stub hash entry against this
3022 struct elf_aarch64_stub_hash_entry
*stub_cache
;
3024 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
3025 is from the end of the jump table and reserved entries within the PLTGOT.
3027 The magic value (bfd_vma) -1 indicates that an offset has not
3029 bfd_vma tlsdesc_got_jump_table_offset
;
3033 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
3035 unsigned long r_symndx
)
3038 return elf_aarch64_hash_entry (h
)->got_type
;
3040 if (! elf_aarch64_locals (abfd
))
3043 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
3046 /* Get the AArch64 elf linker hash table from a link_info structure. */
3047 #define elf_aarch64_hash_table(info) \
3048 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
3050 #define aarch64_stub_hash_lookup(table, string, create, copy) \
3051 ((struct elf_aarch64_stub_hash_entry *) \
3052 bfd_hash_lookup ((table), (string), (create), (copy)))
3054 /* AArch64 ELF linker hash table. */
3055 struct elf_aarch64_link_hash_table
3057 /* The main hash table. */
3058 struct elf_link_hash_table root
;
3060 /* Nonzero to force PIC branch veneers. */
3063 /* Fix erratum 835769. */
3064 int fix_erratum_835769
;
3066 /* Fix erratum 843419. */
3067 erratum_84319_opts fix_erratum_843419
;
3069 /* Don't apply link-time values for dynamic relocations. */
3070 int no_apply_dynamic_relocs
;
3072 /* The number of bytes in the initial entry in the PLT. */
3073 bfd_size_type plt_header_size
;
3075 /* The bytes of the initial PLT entry. */
3076 const bfd_byte
*plt0_entry
;
3078 /* The number of bytes in the subsequent PLT entries. */
3079 bfd_size_type plt_entry_size
;
3081 /* The bytes of the subsequent PLT entry. */
3082 const bfd_byte
*plt_entry
;
3084 /* For convenience in allocate_dynrelocs. */
3087 /* The amount of space used by the reserved portion of the sgotplt
3088 section, plus whatever space is used by the jump slots. */
3089 bfd_vma sgotplt_jump_table_size
;
3091 /* The stub hash table. */
3092 struct bfd_hash_table stub_hash_table
;
3094 /* Linker stub bfd. */
3097 /* Linker call-backs. */
3098 asection
*(*add_stub_section
) (const char *, asection
*);
3099 void (*layout_sections_again
) (void);
3101 /* Array to keep track of which stub sections have been created, and
3102 information on stub grouping. */
3105 /* This is the section to which stubs in the group will be
3108 /* The stub section. */
3112 /* Assorted information used by elfNN_aarch64_size_stubs. */
3113 unsigned int bfd_count
;
3114 unsigned int top_index
;
3115 asection
**input_list
;
3117 /* JUMP_SLOT relocs for variant PCS symbols may be present. */
3120 /* The number of bytes in the PLT enty for the TLS descriptor. */
3121 bfd_size_type tlsdesc_plt_entry_size
;
3123 /* Used by local STT_GNU_IFUNC symbols. */
3124 htab_t loc_hash_table
;
3125 void * loc_hash_memory
;
3127 /* Used for capability relocations. */
3130 bfd_boolean c64_output
;
3133 /* Create an entry in an AArch64 ELF linker hash table. */
3135 static struct bfd_hash_entry
*
3136 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
3137 struct bfd_hash_table
*table
,
3140 struct elf_aarch64_link_hash_entry
*ret
=
3141 (struct elf_aarch64_link_hash_entry
*) entry
;
3143 /* Allocate the structure if it has not already been allocated by a
3146 ret
= bfd_hash_allocate (table
,
3147 sizeof (struct elf_aarch64_link_hash_entry
));
3149 return (struct bfd_hash_entry
*) ret
;
3151 /* Call the allocation method of the superclass. */
3152 ret
= ((struct elf_aarch64_link_hash_entry
*)
3153 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
3157 ret
->got_type
= GOT_UNKNOWN
;
3158 ret
->plt_got_offset
= (bfd_vma
) - 1;
3159 ret
->stub_cache
= NULL
;
3160 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
3163 return (struct bfd_hash_entry
*) ret
;
3166 /* Initialize an entry in the stub hash table. */
3168 static struct bfd_hash_entry
*
3169 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
3170 struct bfd_hash_table
*table
, const char *string
)
3172 /* Allocate the structure if it has not already been allocated by a
3176 entry
= bfd_hash_allocate (table
,
3178 elf_aarch64_stub_hash_entry
));
3183 /* Call the allocation method of the superclass. */
3184 entry
= bfd_hash_newfunc (entry
, table
, string
);
3187 struct elf_aarch64_stub_hash_entry
*eh
;
3189 /* Initialize the local fields. */
3190 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
3191 eh
->adrp_offset
= 0;
3192 eh
->stub_sec
= NULL
;
3193 eh
->stub_offset
= 0;
3194 eh
->target_value
= 0;
3195 eh
->target_section
= NULL
;
3196 eh
->stub_type
= aarch64_stub_none
;
3204 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
3205 for local symbol so that we can handle local STT_GNU_IFUNC symbols
3206 as global symbol. We reuse indx and dynstr_index for local symbol
3207 hash since they aren't used by global symbols in this backend. */
3210 elfNN_aarch64_local_htab_hash (const void *ptr
)
3212 struct elf_link_hash_entry
*h
3213 = (struct elf_link_hash_entry
*) ptr
;
3214 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
3217 /* Compare local hash entries. */
3220 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
3222 struct elf_link_hash_entry
*h1
3223 = (struct elf_link_hash_entry
*) ptr1
;
3224 struct elf_link_hash_entry
*h2
3225 = (struct elf_link_hash_entry
*) ptr2
;
3227 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
3230 /* Find and/or create a hash entry for local symbol. */
3232 static struct elf_link_hash_entry
*
3233 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
3234 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
3237 struct elf_aarch64_link_hash_entry e
, *ret
;
3238 asection
*sec
= abfd
->sections
;
3239 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
3240 ELFNN_R_SYM (rel
->r_info
));
3243 e
.root
.indx
= sec
->id
;
3244 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
3245 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
3246 create
? INSERT
: NO_INSERT
);
3253 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
3257 ret
= (struct elf_aarch64_link_hash_entry
*)
3258 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
3259 sizeof (struct elf_aarch64_link_hash_entry
));
3262 memset (ret
, 0, sizeof (*ret
));
3263 ret
->root
.indx
= sec
->id
;
3264 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
3265 ret
->root
.dynindx
= -1;
3271 /* Copy the extra info we tack onto an elf_link_hash_entry. */
3274 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
3275 struct elf_link_hash_entry
*dir
,
3276 struct elf_link_hash_entry
*ind
)
3278 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
3280 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
3281 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
3283 if (ind
->root
.type
== bfd_link_hash_indirect
)
3285 /* Copy over PLT info. */
3286 if (dir
->got
.refcount
<= 0)
3288 edir
->got_type
= eind
->got_type
;
3289 eind
->got_type
= GOT_UNKNOWN
;
3293 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
3296 /* Merge non-visibility st_other attributes. */
3299 elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry
*h
,
3300 const Elf_Internal_Sym
*isym
,
3301 bfd_boolean definition ATTRIBUTE_UNUSED
,
3302 bfd_boolean dynamic ATTRIBUTE_UNUSED
)
3304 unsigned int isym_sto
= isym
->st_other
& ~ELF_ST_VISIBILITY (-1);
3305 unsigned int h_sto
= h
->other
& ~ELF_ST_VISIBILITY (-1);
3307 if (isym_sto
== h_sto
)
3310 if (isym_sto
& ~STO_AARCH64_VARIANT_PCS
)
3311 /* Not fatal, this callback cannot fail. */
3312 _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"),
3313 h
->root
.root
.string
, isym_sto
);
3315 /* Note: Ideally we would warn about any attribute mismatch, but
3316 this api does not allow that without substantial changes. */
3317 if (isym_sto
& STO_AARCH64_VARIANT_PCS
)
3318 h
->other
|= STO_AARCH64_VARIANT_PCS
;
3321 /* Destroy an AArch64 elf linker hash table. */
3324 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
3326 struct elf_aarch64_link_hash_table
*ret
3327 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
3329 if (ret
->loc_hash_table
)
3330 htab_delete (ret
->loc_hash_table
);
3331 if (ret
->loc_hash_memory
)
3332 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
3334 bfd_hash_table_free (&ret
->stub_hash_table
);
3335 _bfd_elf_link_hash_table_free (obfd
);
3338 /* Create an AArch64 elf linker hash table. */
3340 static struct bfd_link_hash_table
*
3341 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
3343 struct elf_aarch64_link_hash_table
*ret
;
3344 size_t amt
= sizeof (struct elf_aarch64_link_hash_table
);
3346 ret
= bfd_zmalloc (amt
);
3350 if (!_bfd_elf_link_hash_table_init
3351 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
3352 sizeof (struct elf_aarch64_link_hash_entry
), AARCH64_ELF_DATA
))
3358 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
3359 ret
->plt0_entry
= elfNN_aarch64_small_plt0_entry
;
3360 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
3361 ret
->plt_entry
= elfNN_aarch64_small_plt_entry
;
3362 ret
->tlsdesc_plt_entry_size
= PLT_TLSDESC_ENTRY_SIZE
;
3364 ret
->root
.tlsdesc_got
= (bfd_vma
) - 1;
3366 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
3367 sizeof (struct elf_aarch64_stub_hash_entry
)))
3369 _bfd_elf_link_hash_table_free (abfd
);
3373 ret
->loc_hash_table
= htab_try_create (1024,
3374 elfNN_aarch64_local_htab_hash
,
3375 elfNN_aarch64_local_htab_eq
,
3377 ret
->loc_hash_memory
= objalloc_create ();
3378 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
3380 elfNN_aarch64_link_hash_table_free (abfd
);
3383 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
3385 return &ret
->root
.root
;
3388 /* Perform relocation R_TYPE. Returns TRUE upon success, FALSE otherwise. */
3391 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
3392 bfd_vma offset
, bfd_vma value
)
3394 reloc_howto_type
*howto
;
3397 howto
= elfNN_aarch64_howto_from_type (input_bfd
, r_type
);
3398 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
3401 r_type
= elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
3402 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, r_type
, place
,
3404 return _bfd_aarch64_elf_put_addend (input_bfd
,
3405 input_section
->contents
+ offset
, r_type
,
3406 howto
, value
) == bfd_reloc_ok
;
3409 /* Return interworking stub for a relocation. */
3411 static enum elf_aarch64_stub_type
3412 aarch64_interwork_stub (unsigned int r_type
,
3413 bfd_boolean branch_to_c64
)
3417 case MORELLO_R (JUMP26
):
3418 case MORELLO_R (CALL26
):
3420 return c64_stub_branch_aarch64
;
3422 case AARCH64_R (JUMP26
):
3423 case AARCH64_R (CALL26
):
3425 return aarch64_stub_branch_c64
;
3431 return aarch64_stub_none
;
3434 static enum elf_aarch64_stub_type
3435 aarch64_select_branch_stub (bfd_vma value
, bfd_vma place
)
3437 if (aarch64_valid_for_adrp_p (value
, place
))
3438 return aarch64_stub_adrp_branch
;
3439 return aarch64_stub_long_branch
;
3442 /* Determine the type of stub needed, if any, for a call. */
3444 static enum elf_aarch64_stub_type
3445 aarch64_type_of_stub (asection
*input_sec
,
3446 const Elf_Internal_Rela
*rel
,
3448 unsigned char st_type
,
3449 bfd_vma destination
)
3452 bfd_signed_vma branch_offset
;
3453 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
3454 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
3456 if (st_type
!= STT_FUNC
3457 && (sym_sec
== input_sec
))
3460 /* Determine where the call point is. */
3461 location
= (input_sec
->output_offset
3462 + input_sec
->output_section
->vma
+ rel
->r_offset
);
3464 branch_offset
= (bfd_signed_vma
) (destination
- location
);
3466 /* For A64 <-> C64 branches we only come here for jumps to PLT. Treat them
3467 as regular branches and leave the interworking to PLT. */
3468 if (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
3469 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
)
3473 /* We don't want to redirect any old unconditional jump in this way,
3474 only one which is being used for a sibcall, where it is
3475 acceptable for the IP0 and IP1 registers to be clobbered. */
3476 case AARCH64_R (CALL26
):
3477 case AARCH64_R (JUMP26
):
3478 return aarch64_stub_long_branch
;
3479 case MORELLO_R (CALL26
):
3480 case MORELLO_R (JUMP26
):
3481 return c64_stub_branch_c64
;
3487 return aarch64_stub_none
;
3490 /* Return a string to add as suffix to a veneer name. */
3493 aarch64_lookup_stub_type_suffix (enum elf_aarch64_stub_type stub_type
)
3497 case aarch64_stub_branch_c64
:
3499 case c64_stub_branch_aarch64
:
3507 /* Build a name for an entry in the stub hash table. */
3510 elfNN_aarch64_stub_name (const asection
*input_section
,
3511 const asection
*sym_sec
,
3512 const struct elf_aarch64_link_hash_entry
*hash
,
3513 const Elf_Internal_Rela
*rel
,
3514 enum elf_aarch64_stub_type stub_type
)
3518 const char *suffix
= aarch64_lookup_stub_type_suffix (stub_type
);;
3522 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
3523 stub_name
= bfd_malloc (len
);
3524 if (stub_name
!= NULL
)
3525 snprintf (stub_name
, len
, "%08x_%s%s+%" BFD_VMA_FMT
"x",
3526 (unsigned int) input_section
->id
,
3527 hash
->root
.root
.root
.string
,
3528 suffix
, rel
->r_addend
);
3532 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
3533 stub_name
= bfd_malloc (len
);
3534 if (stub_name
!= NULL
)
3535 snprintf (stub_name
, len
, "%08x_%x:%x%s+%" BFD_VMA_FMT
"x",
3536 (unsigned int) input_section
->id
,
3537 (unsigned int) sym_sec
->id
,
3538 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
3539 suffix
, rel
->r_addend
);
3545 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
3546 executable PLT slots where the executable never takes the address of those
3547 functions, the function symbols are not added to the hash table. */
3550 elf_aarch64_hash_symbol (struct elf_link_hash_entry
*h
)
3552 if (h
->plt
.offset
!= (bfd_vma
) -1
3554 && !h
->pointer_equality_needed
)
3557 return _bfd_elf_hash_symbol (h
);
3560 /* Look up an entry in the stub hash. Stub entries are cached because
3561 creating the stub name takes a bit of time. */
3563 static struct elf_aarch64_stub_hash_entry
*
3564 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
3565 const asection
*sym_sec
,
3566 struct elf_link_hash_entry
*hash
,
3567 const Elf_Internal_Rela
*rel
,
3568 struct elf_aarch64_link_hash_table
*htab
,
3569 enum elf_aarch64_stub_type stub_type
)
3571 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3572 struct elf_aarch64_link_hash_entry
*h
=
3573 (struct elf_aarch64_link_hash_entry
*) hash
;
3574 const asection
*id_sec
;
3576 if ((input_section
->flags
& SEC_CODE
) == 0)
3579 /* If this input section is part of a group of sections sharing one
3580 stub section, then use the id of the first section in the group.
3581 Stub names need to include a section id, as there may well be
3582 more than one stub used to reach say, printf, and we need to
3583 distinguish between them. */
3584 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
3586 if (h
!= NULL
&& h
->stub_cache
!= NULL
3587 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
3589 stub_entry
= h
->stub_cache
;
3595 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
, stub_type
);
3596 if (stub_name
== NULL
)
3599 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
3600 stub_name
, FALSE
, FALSE
);
3602 h
->stub_cache
= stub_entry
;
3611 /* Create a stub section. */
3614 _bfd_aarch64_create_stub_section (asection
*section
,
3615 struct elf_aarch64_link_hash_table
*htab
)
3621 namelen
= strlen (section
->name
);
3622 len
= namelen
+ sizeof (STUB_SUFFIX
);
3623 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
3627 memcpy (s_name
, section
->name
, namelen
);
3628 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
3629 return (*htab
->add_stub_section
) (s_name
, section
);
3633 /* Find or create a stub section for a link section.
3635 Fix or create the stub section used to collect stubs attached to
3636 the specified link section. */
3639 _bfd_aarch64_get_stub_for_link_section (asection
*link_section
,
3640 struct elf_aarch64_link_hash_table
*htab
)
3642 if (htab
->stub_group
[link_section
->id
].stub_sec
== NULL
)
3643 htab
->stub_group
[link_section
->id
].stub_sec
3644 = _bfd_aarch64_create_stub_section (link_section
, htab
);
3645 return htab
->stub_group
[link_section
->id
].stub_sec
;
3649 /* Find or create a stub section in the stub group for an input
3653 _bfd_aarch64_create_or_find_stub_sec (asection
*section
,
3654 struct elf_aarch64_link_hash_table
*htab
)
3656 asection
*link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3657 return _bfd_aarch64_get_stub_for_link_section (link_sec
, htab
);
3661 /* Add a new stub entry in the stub group associated with an input
3662 section to the stub hash. Not all fields of the new stub entry are
3665 static struct elf_aarch64_stub_hash_entry
*
3666 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name
,
3668 struct elf_aarch64_link_hash_table
*htab
)
3672 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3674 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3675 stub_sec
= _bfd_aarch64_create_or_find_stub_sec (section
, htab
);
3677 /* Enter this entry into the linker stub hash table. */
3678 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3680 if (stub_entry
== NULL
)
3682 /* xgettext:c-format */
3683 _bfd_error_handler (_("%pB: cannot create stub entry %s"),
3684 section
->owner
, stub_name
);
3688 stub_entry
->stub_sec
= stub_sec
;
3689 stub_entry
->stub_offset
= 0;
3690 stub_entry
->id_sec
= link_sec
;
3695 /* Add a new stub entry in the final stub section to the stub hash.
3696 Not all fields of the new stub entry are initialised. */
3698 static struct elf_aarch64_stub_hash_entry
*
3699 _bfd_aarch64_add_stub_entry_after (const char *stub_name
,
3700 asection
*link_section
,
3701 struct elf_aarch64_link_hash_table
*htab
)
3704 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3707 /* Only create the actual stub if we will end up needing it. */
3708 if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
3709 stub_sec
= _bfd_aarch64_get_stub_for_link_section (link_section
, htab
);
3710 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3712 if (stub_entry
== NULL
)
3714 _bfd_error_handler (_("cannot create stub entry %s"), stub_name
);
3718 stub_entry
->stub_sec
= stub_sec
;
3719 stub_entry
->stub_offset
= 0;
3720 stub_entry
->id_sec
= link_section
;
3727 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
3730 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3735 bfd_vma veneered_insn_loc
;
3736 bfd_vma veneer_entry_loc
;
3737 bfd_signed_vma branch_offset
= 0;
3738 unsigned int template_size
;
3739 const uint32_t *template;
3741 struct bfd_link_info
*info
;
3743 /* Massage our args to the form they really have. */
3744 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
3746 info
= (struct bfd_link_info
*) in_arg
;
3748 /* Fail if the target section could not be assigned to an output
3749 section. The user should fix his linker script. */
3750 if (stub_entry
->target_section
->output_section
== NULL
3751 && info
->non_contiguous_regions
)
3752 info
->callbacks
->einfo (_("%F%P: Could not assign '%pA' to an output section. "
3754 "--enable-non-contiguous-regions.\n"),
3755 stub_entry
->target_section
);
3757 stub_sec
= stub_entry
->stub_sec
;
3759 /* Make a note of the offset within the stubs for this entry. */
3760 stub_entry
->stub_offset
= stub_sec
->size
;
3761 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
3763 stub_bfd
= stub_sec
->owner
;
3765 /* This is the address of the stub destination. */
3766 sym_value
= (stub_entry
->target_value
3767 + stub_entry
->target_section
->output_offset
3768 + stub_entry
->target_section
->output_section
->vma
);
3770 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
3771 + stub_sec
->output_offset
);
3773 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
3775 /* See if we can relax the stub. */
3776 if (aarch64_valid_for_adrp_p (sym_value
, place
))
3777 stub_entry
->stub_type
= aarch64_select_branch_stub (sym_value
, place
);
3780 if ((stub_entry
->stub_type
== aarch64_stub_branch_c64
3781 || stub_entry
->stub_type
== c64_stub_branch_aarch64
3782 || stub_entry
->stub_type
== c64_stub_branch_c64
)
3783 && !c64_valid_for_adrp_p (sym_value
, place
))
3786 (_("%s: stub target out of range for %s branch"),
3787 stub_entry
->output_name
,
3788 (stub_entry
->stub_type
== aarch64_stub_branch_c64
3789 ? "A64 to C64" : "C64 to A64"));
3790 bfd_set_error (bfd_error_bad_value
);
3794 switch (stub_entry
->stub_type
)
3796 case aarch64_stub_adrp_branch
:
3797 template = aarch64_adrp_branch_stub
;
3798 template_size
= sizeof (aarch64_adrp_branch_stub
);
3800 case aarch64_stub_long_branch
:
3801 template = aarch64_long_branch_stub
;
3802 template_size
= sizeof (aarch64_long_branch_stub
);
3804 case aarch64_stub_erratum_835769_veneer
:
3805 template = aarch64_erratum_835769_stub
;
3806 template_size
= sizeof (aarch64_erratum_835769_stub
);
3808 case aarch64_stub_erratum_843419_veneer
:
3809 template = aarch64_erratum_843419_stub
;
3810 template_size
= sizeof (aarch64_erratum_843419_stub
);
3812 case aarch64_stub_branch_c64
:
3813 template = aarch64_c64_branch_stub
;
3814 template_size
= sizeof (aarch64_c64_branch_stub
);
3816 case c64_stub_branch_aarch64
:
3817 case c64_stub_branch_c64
:
3818 template = c64_aarch64_branch_stub
;
3819 template_size
= sizeof (c64_aarch64_branch_stub
);
3825 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
3827 bfd_putl32 (template[i
], loc
);
3831 template_size
= (template_size
+ 7) & ~7;
3832 stub_sec
->size
+= template_size
;
3834 bfd_vma stub_offset
= stub_entry
->stub_offset
;
3836 switch (stub_entry
->stub_type
)
3838 case aarch64_stub_adrp_branch
:
3839 if (!aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
3840 stub_entry
->stub_offset
, sym_value
))
3841 /* The stub would not have been relaxed if the offset was out
3845 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
3846 stub_entry
->stub_offset
+ 4, sym_value
))
3850 case aarch64_stub_long_branch
:
3851 /* We want the value relative to the address 12 bytes back from the
3853 if (!aarch64_relocate (AARCH64_R (PRELNN
), stub_bfd
, stub_sec
,
3854 stub_entry
->stub_offset
+ 16, sym_value
+ 12))
3858 case aarch64_stub_erratum_835769_veneer
:
3859 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
3860 + stub_entry
->target_section
->output_offset
3861 + stub_entry
->target_value
;
3862 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
3863 + stub_entry
->stub_sec
->output_offset
3864 + stub_entry
->stub_offset
;
3865 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
3866 branch_offset
>>= 2;
3867 branch_offset
&= 0x3ffffff;
3868 bfd_putl32 (stub_entry
->veneered_insn
,
3869 stub_sec
->contents
+ stub_entry
->stub_offset
);
3870 bfd_putl32 (template[1] | branch_offset
,
3871 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
3874 case aarch64_stub_erratum_843419_veneer
:
3875 if (!aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
3876 stub_entry
->stub_offset
+ 4, sym_value
+ 4))
3880 case aarch64_stub_branch_c64
:
3883 case c64_stub_branch_aarch64
:
3884 case c64_stub_branch_c64
:
3885 if (!aarch64_relocate (R_MORELLO_ADR_PREL_PG_HI20
, stub_bfd
, stub_sec
,
3886 stub_offset
, sym_value
))
3887 /* We fail early if offset is out of range. */
3890 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
3891 stub_offset
+ 4, sym_value
))
3902 /* As above, but don't actually build the stub. Just bump offset so
3903 we know stub section sizes. */
3906 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
3908 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3909 struct elf_aarch64_link_hash_table
*htab
;
3912 /* Massage our args to the form they really have. */
3913 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
3914 htab
= (struct elf_aarch64_link_hash_table
*) in_arg
;
3916 switch (stub_entry
->stub_type
)
3918 case aarch64_stub_adrp_branch
:
3919 size
= sizeof (aarch64_adrp_branch_stub
);
3921 case aarch64_stub_long_branch
:
3922 size
= sizeof (aarch64_long_branch_stub
);
3924 case aarch64_stub_erratum_835769_veneer
:
3925 size
= sizeof (aarch64_erratum_835769_stub
);
3927 case aarch64_stub_erratum_843419_veneer
:
3929 if (htab
->fix_erratum_843419
== ERRAT_ADR
)
3931 size
= sizeof (aarch64_erratum_843419_stub
);
3934 case aarch64_stub_branch_c64
:
3935 size
= sizeof (aarch64_c64_branch_stub
);
3937 case c64_stub_branch_aarch64
:
3938 case c64_stub_branch_c64
:
3939 size
= sizeof (c64_aarch64_branch_stub
);
3945 size
= (size
+ 7) & ~7;
3946 stub_entry
->stub_sec
->size
+= size
;
3950 /* External entry points for sizing and building linker stubs. */
3952 /* Set up various things so that we can make a list of input sections
3953 for each output section included in the link. Returns -1 on error,
3954 0 when no stubs will be needed, and 1 on success. */
3957 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
3958 struct bfd_link_info
*info
)
3961 unsigned int bfd_count
;
3962 unsigned int top_id
, top_index
;
3964 asection
**input_list
, **list
;
3966 struct elf_aarch64_link_hash_table
*htab
=
3967 elf_aarch64_hash_table (info
);
3969 if (!is_elf_hash_table (htab
))
3972 /* Count the number of input BFDs and find the top input section id. */
3973 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
3974 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3977 for (section
= input_bfd
->sections
;
3978 section
!= NULL
; section
= section
->next
)
3980 if (top_id
< section
->id
)
3981 top_id
= section
->id
;
3984 htab
->bfd_count
= bfd_count
;
3986 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
3987 htab
->stub_group
= bfd_zmalloc (amt
);
3988 if (htab
->stub_group
== NULL
)
3991 /* We can't use output_bfd->section_count here to find the top output
3992 section index as some sections may have been removed, and
3993 _bfd_strip_section_from_output doesn't renumber the indices. */
3994 for (section
= output_bfd
->sections
, top_index
= 0;
3995 section
!= NULL
; section
= section
->next
)
3997 if (top_index
< section
->index
)
3998 top_index
= section
->index
;
4001 htab
->top_index
= top_index
;
4002 amt
= sizeof (asection
*) * (top_index
+ 1);
4003 input_list
= bfd_malloc (amt
);
4004 htab
->input_list
= input_list
;
4005 if (input_list
== NULL
)
4008 /* For sections we aren't interested in, mark their entries with a
4009 value we can check later. */
4010 list
= input_list
+ top_index
;
4012 *list
= bfd_abs_section_ptr
;
4013 while (list
-- != input_list
);
4015 for (section
= output_bfd
->sections
;
4016 section
!= NULL
; section
= section
->next
)
4018 if ((section
->flags
& SEC_CODE
) != 0)
4019 input_list
[section
->index
] = NULL
;
4025 /* Used by elfNN_aarch64_next_input_section and group_sections. */
4026 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
4028 /* The linker repeatedly calls this function for each input section,
4029 in the order that input sections are linked into output sections.
4030 Build lists of input sections to determine groupings between which
4031 we may insert linker stubs. */
4034 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
4036 struct elf_aarch64_link_hash_table
*htab
=
4037 elf_aarch64_hash_table (info
);
4039 if (isec
->output_section
->index
<= htab
->top_index
)
4041 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
4043 if (*list
!= bfd_abs_section_ptr
&& (isec
->flags
& SEC_CODE
) != 0)
4045 /* Steal the link_sec pointer for our list. */
4046 /* This happens to make the list in reverse order,
4047 which is what we want. */
4048 PREV_SEC (isec
) = *list
;
4054 /* See whether we can group stub sections together. Grouping stub
4055 sections may result in fewer stubs. More importantly, we need to
4056 put all .init* and .fini* stubs at the beginning of the .init or
4057 .fini output sections respectively, because glibc splits the
4058 _init and _fini functions into multiple parts. Putting a stub in
4059 the middle of a function is not a good idea. */
4062 group_sections (struct elf_aarch64_link_hash_table
*htab
,
4063 bfd_size_type stub_group_size
,
4064 bfd_boolean stubs_always_after_branch
)
4066 asection
**list
= htab
->input_list
;
4070 asection
*tail
= *list
;
4073 if (tail
== bfd_abs_section_ptr
)
4076 /* Reverse the list: we must avoid placing stubs at the
4077 beginning of the section because the beginning of the text
4078 section may be required for an interrupt vector in bare metal
4080 #define NEXT_SEC PREV_SEC
4082 while (tail
!= NULL
)
4084 /* Pop from tail. */
4085 asection
*item
= tail
;
4086 tail
= PREV_SEC (item
);
4089 NEXT_SEC (item
) = head
;
4093 while (head
!= NULL
)
4097 bfd_vma stub_group_start
= head
->output_offset
;
4098 bfd_vma end_of_next
;
4101 while (NEXT_SEC (curr
) != NULL
)
4103 next
= NEXT_SEC (curr
);
4104 end_of_next
= next
->output_offset
+ next
->size
;
4105 if (end_of_next
- stub_group_start
>= stub_group_size
)
4106 /* End of NEXT is too far from start, so stop. */
4108 /* Add NEXT to the group. */
4112 /* OK, the size from the start to the start of CURR is less
4113 than stub_group_size and thus can be handled by one stub
4114 section. (Or the head section is itself larger than
4115 stub_group_size, in which case we may be toast.)
4116 We should really be keeping track of the total size of
4117 stubs added here, as stubs contribute to the final output
4121 next
= NEXT_SEC (head
);
4122 /* Set up this stub group. */
4123 htab
->stub_group
[head
->id
].link_sec
= curr
;
4125 while (head
!= curr
&& (head
= next
) != NULL
);
4127 /* But wait, there's more! Input sections up to stub_group_size
4128 bytes after the stub section can be handled by it too. */
4129 if (!stubs_always_after_branch
)
4131 stub_group_start
= curr
->output_offset
+ curr
->size
;
4133 while (next
!= NULL
)
4135 end_of_next
= next
->output_offset
+ next
->size
;
4136 if (end_of_next
- stub_group_start
>= stub_group_size
)
4137 /* End of NEXT is too far from stubs, so stop. */
4139 /* Add NEXT to the stub group. */
4141 next
= NEXT_SEC (head
);
4142 htab
->stub_group
[head
->id
].link_sec
= curr
;
4148 while (list
++ != htab
->input_list
+ htab
->top_index
);
4150 free (htab
->input_list
);
4156 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
4158 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
4159 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
4160 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
4161 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
4162 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
4163 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
4165 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
4166 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
4167 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
4168 #define AARCH64_ZR 0x1f
4170 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
4171 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
4173 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
4174 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
4175 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
4176 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
4177 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
4178 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
4179 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
4180 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
4181 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
4182 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
4183 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
4184 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
4185 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
4186 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
4187 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
4188 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
4189 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
4190 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
4192 /* Classify an INSN if it is indeed a load/store.
4194 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
4196 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
4199 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned. */
4202 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rt2
,
4203 bfd_boolean
*pair
, bfd_boolean
*load
)
4211 /* Bail out quickly if INSN doesn't fall into the load-store
4213 if (!AARCH64_LDST (insn
))
4218 if (AARCH64_LDST_EX (insn
))
4220 *rt
= AARCH64_RT (insn
);
4222 if (AARCH64_BIT (insn
, 21) == 1)
4225 *rt2
= AARCH64_RT2 (insn
);
4227 *load
= AARCH64_LD (insn
);
4230 else if (AARCH64_LDST_NAP (insn
)
4231 || AARCH64_LDSTP_PI (insn
)
4232 || AARCH64_LDSTP_O (insn
)
4233 || AARCH64_LDSTP_PRE (insn
))
4236 *rt
= AARCH64_RT (insn
);
4237 *rt2
= AARCH64_RT2 (insn
);
4238 *load
= AARCH64_LD (insn
);
4241 else if (AARCH64_LDST_PCREL (insn
)
4242 || AARCH64_LDST_UI (insn
)
4243 || AARCH64_LDST_PIIMM (insn
)
4244 || AARCH64_LDST_U (insn
)
4245 || AARCH64_LDST_PREIMM (insn
)
4246 || AARCH64_LDST_RO (insn
)
4247 || AARCH64_LDST_UIMM (insn
))
4249 *rt
= AARCH64_RT (insn
);
4251 if (AARCH64_LDST_PCREL (insn
))
4253 opc
= AARCH64_BITS (insn
, 22, 2);
4254 v
= AARCH64_BIT (insn
, 26);
4255 opc_v
= opc
| (v
<< 2);
4256 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
4257 || opc_v
== 5 || opc_v
== 7);
4260 else if (AARCH64_LDST_SIMD_M (insn
)
4261 || AARCH64_LDST_SIMD_M_PI (insn
))
4263 *rt
= AARCH64_RT (insn
);
4264 *load
= AARCH64_BIT (insn
, 22);
4265 opcode
= (insn
>> 12) & 0xf;
4292 else if (AARCH64_LDST_SIMD_S (insn
)
4293 || AARCH64_LDST_SIMD_S_PI (insn
))
4295 *rt
= AARCH64_RT (insn
);
4296 r
= (insn
>> 21) & 1;
4297 *load
= AARCH64_BIT (insn
, 22);
4298 opcode
= (insn
>> 13) & 0x7;
4310 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
4318 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
4330 /* Return TRUE if INSN is multiply-accumulate. */
4333 aarch64_mlxl_p (uint32_t insn
)
4335 uint32_t op31
= AARCH64_OP31 (insn
);
4337 if (AARCH64_MAC (insn
)
4338 && (op31
== 0 || op31
== 1 || op31
== 5)
4339 /* Exclude MUL instructions which are encoded as a multiple accumulate
4341 && AARCH64_RA (insn
) != AARCH64_ZR
)
4347 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
4348 it is possible for a 64-bit multiply-accumulate instruction to generate an
4349 incorrect result. The details are quite complex and hard to
4350 determine statically, since branches in the code may exist in some
4351 circumstances, but all cases end with a memory (load, store, or
4352 prefetch) instruction followed immediately by the multiply-accumulate
4353 operation. We employ a linker patching technique, by moving the potentially
4354 affected multiply-accumulate instruction into a patch region and replacing
4355 the original instruction with a branch to the patch. This function checks
4356 if INSN_1 is the memory operation followed by a multiply-accumulate
4357 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
4358 if INSN_1 and INSN_2 are safe. */
4361 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
4371 if (aarch64_mlxl_p (insn_2
)
4372 && aarch64_mem_op_p (insn_1
, &rt
, &rt2
, &pair
, &load
))
4374 /* Any SIMD memory op is independent of the subsequent MLA
4375 by definition of the erratum. */
4376 if (AARCH64_BIT (insn_1
, 26))
4379 /* If not SIMD, check for integer memory ops and MLA relationship. */
4380 rn
= AARCH64_RN (insn_2
);
4381 ra
= AARCH64_RA (insn_2
);
4382 rm
= AARCH64_RM (insn_2
);
4384 /* If this is a load and there's a true(RAW) dependency, we are safe
4385 and this is not an erratum sequence. */
4387 (rt
== rn
|| rt
== rm
|| rt
== ra
4388 || (pair
&& (rt2
== rn
|| rt2
== rm
|| rt2
== ra
))))
4391 /* We conservatively put out stubs for all other cases (including
4401 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes
)
4403 char *stub_name
= (char *) bfd_malloc
4404 (strlen ("__erratum_835769_veneer_") + 16);
4405 if (stub_name
!= NULL
)
4406 sprintf (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
4410 /* Scan for Cortex-A53 erratum 835769 sequence.
4412 Return TRUE else FALSE on abnormal termination. */
4415 _bfd_aarch64_erratum_835769_scan (bfd
*input_bfd
,
4416 struct bfd_link_info
*info
,
4417 unsigned int *num_fixes_p
)
4420 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4421 unsigned int num_fixes
= *num_fixes_p
;
4426 for (section
= input_bfd
->sections
;
4428 section
= section
->next
)
4430 bfd_byte
*contents
= NULL
;
4431 struct _aarch64_elf_section_data
*sec_data
;
4434 if (elf_section_type (section
) != SHT_PROGBITS
4435 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
4436 || (section
->flags
& SEC_EXCLUDE
) != 0
4437 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
4438 || (section
->output_section
== bfd_abs_section_ptr
))
4441 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
4442 contents
= elf_section_data (section
)->this_hdr
.contents
;
4443 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
4446 sec_data
= elf_aarch64_section_data (section
);
4448 if (sec_data
->mapcount
)
4449 qsort (sec_data
->map
, sec_data
->mapcount
,
4450 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
4452 for (span
= 0; span
< sec_data
->mapcount
; span
++)
4454 unsigned int span_start
= sec_data
->map
[span
].vma
;
4455 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
4456 ? sec_data
->map
[0].vma
+ section
->size
4457 : sec_data
->map
[span
+ 1].vma
);
4459 char span_type
= sec_data
->map
[span
].type
;
4461 if (span_type
== 'd')
4464 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
4466 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
4467 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
4469 if (aarch64_erratum_sequence (insn_1
, insn_2
))
4471 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4472 char *stub_name
= _bfd_aarch64_erratum_835769_stub_name (num_fixes
);
4476 stub_entry
= _bfd_aarch64_add_stub_entry_in_group (stub_name
,
4482 stub_entry
->stub_type
= aarch64_stub_erratum_835769_veneer
;
4483 stub_entry
->target_section
= section
;
4484 stub_entry
->target_value
= i
+ 4;
4485 stub_entry
->veneered_insn
= insn_2
;
4486 stub_entry
->output_name
= stub_name
;
4491 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
4495 *num_fixes_p
= num_fixes
;
4501 /* Test if instruction INSN is ADRP. */
4504 _bfd_aarch64_adrp_p (uint32_t insn
)
4506 return ((insn
& AARCH64_ADRP_OP_MASK
) == AARCH64_ADRP_OP
);
4510 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
4513 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1
, uint32_t insn_2
,
4521 return (aarch64_mem_op_p (insn_2
, &rt
, &rt2
, &pair
, &load
)
4524 && AARCH64_LDST_UIMM (insn_3
)
4525 && AARCH64_RN (insn_3
) == AARCH64_RD (insn_1
));
4529 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
4531 Return TRUE if section CONTENTS at offset I contains one of the
4532 erratum 843419 sequences, otherwise return FALSE. If a sequence is
4533 seen set P_VENEER_I to the offset of the final LOAD/STORE
4534 instruction in the sequence.
4538 _bfd_aarch64_erratum_843419_p (bfd_byte
*contents
, bfd_vma vma
,
4539 bfd_vma i
, bfd_vma span_end
,
4540 bfd_vma
*p_veneer_i
)
4542 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
4544 if (!_bfd_aarch64_adrp_p (insn_1
))
4547 if (span_end
< i
+ 12)
4550 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
4551 uint32_t insn_3
= bfd_getl32 (contents
+ i
+ 8);
4553 if ((vma
& 0xfff) != 0xff8 && (vma
& 0xfff) != 0xffc)
4556 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_3
))
4558 *p_veneer_i
= i
+ 8;
4562 if (span_end
< i
+ 16)
4565 uint32_t insn_4
= bfd_getl32 (contents
+ i
+ 12);
4567 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_4
))
4569 *p_veneer_i
= i
+ 12;
4577 /* Resize all stub sections. */
4580 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table
*htab
)
4584 /* OK, we've added some stubs. Find out the new size of the
4586 for (section
= htab
->stub_bfd
->sections
;
4587 section
!= NULL
; section
= section
->next
)
4589 /* Ignore non-stub sections. */
4590 if (!strstr (section
->name
, STUB_SUFFIX
))
4595 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
4597 for (section
= htab
->stub_bfd
->sections
;
4598 section
!= NULL
; section
= section
->next
)
4600 if (!strstr (section
->name
, STUB_SUFFIX
))
4603 /* Add space for a branch. Add 8 bytes to keep section 8 byte aligned,
4604 as long branch stubs contain a 64-bit address. */
4608 /* Ensure all stub sections have a size which is a multiple of
4609 4096. This is important in order to ensure that the insertion
4610 of stub sections does not in itself move existing code around
4611 in such a way that new errata sequences are created. We only do this
4612 when the ADRP workaround is enabled. If only the ADR workaround is
4613 enabled then the stubs workaround won't ever be used. */
4614 if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
4616 section
->size
= BFD_ALIGN (section
->size
, 0x1000);
4620 /* Construct an erratum 843419 workaround stub name. */
4623 _bfd_aarch64_erratum_843419_stub_name (asection
*input_section
,
4626 const bfd_size_type len
= 8 + 4 + 1 + 8 + 1 + 16 + 1;
4627 char *stub_name
= bfd_malloc (len
);
4629 if (stub_name
!= NULL
)
4630 snprintf (stub_name
, len
, "e843419@%04x_%08x_%" BFD_VMA_FMT
"x",
4631 input_section
->owner
->id
,
4637 /* Build a stub_entry structure describing an 843419 fixup.
4639 The stub_entry constructed is populated with the bit pattern INSN
4640 of the instruction located at OFFSET within input SECTION.
4642 Returns TRUE on success. */
4645 _bfd_aarch64_erratum_843419_fixup (uint32_t insn
,
4646 bfd_vma adrp_offset
,
4647 bfd_vma ldst_offset
,
4649 struct bfd_link_info
*info
)
4651 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4653 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4655 stub_name
= _bfd_aarch64_erratum_843419_stub_name (section
, ldst_offset
);
4656 if (stub_name
== NULL
)
4658 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
4666 /* We always place an 843419 workaround veneer in the stub section
4667 attached to the input section in which an erratum sequence has
4668 been found. This ensures that later in the link process (in
4669 elfNN_aarch64_write_section) when we copy the veneered
4670 instruction from the input section into the stub section the
4671 copied instruction will have had any relocations applied to it.
4672 If we placed workaround veneers in any other stub section then we
4673 could not assume that all relocations have been processed on the
4674 corresponding input section at the point we output the stub
4677 stub_entry
= _bfd_aarch64_add_stub_entry_after (stub_name
, section
, htab
);
4678 if (stub_entry
== NULL
)
4684 stub_entry
->adrp_offset
= adrp_offset
;
4685 stub_entry
->target_value
= ldst_offset
;
4686 stub_entry
->target_section
= section
;
4687 stub_entry
->stub_type
= aarch64_stub_erratum_843419_veneer
;
4688 stub_entry
->veneered_insn
= insn
;
4689 stub_entry
->output_name
= stub_name
;
4695 /* Scan an input section looking for the signature of erratum 843419.
4697 Scans input SECTION in INPUT_BFD looking for erratum 843419
4698 signatures, for each signature found a stub_entry is created
4699 describing the location of the erratum for subsequent fixup.
4701 Return TRUE on successful scan, FALSE on failure to scan.
4705 _bfd_aarch64_erratum_843419_scan (bfd
*input_bfd
, asection
*section
,
4706 struct bfd_link_info
*info
)
4708 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4713 if (elf_section_type (section
) != SHT_PROGBITS
4714 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
4715 || (section
->flags
& SEC_EXCLUDE
) != 0
4716 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
4717 || (section
->output_section
== bfd_abs_section_ptr
))
4722 bfd_byte
*contents
= NULL
;
4723 struct _aarch64_elf_section_data
*sec_data
;
4726 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
4727 contents
= elf_section_data (section
)->this_hdr
.contents
;
4728 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
4731 sec_data
= elf_aarch64_section_data (section
);
4733 if (sec_data
->mapcount
)
4734 qsort (sec_data
->map
, sec_data
->mapcount
,
4735 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
4737 for (span
= 0; span
< sec_data
->mapcount
; span
++)
4739 unsigned int span_start
= sec_data
->map
[span
].vma
;
4740 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
4741 ? sec_data
->map
[0].vma
+ section
->size
4742 : sec_data
->map
[span
+ 1].vma
);
4744 char span_type
= sec_data
->map
[span
].type
;
4746 if (span_type
== 'd')
4749 for (i
= span_start
; i
+ 8 < span_end
; i
+= 4)
4751 bfd_vma vma
= (section
->output_section
->vma
4752 + section
->output_offset
4756 if (_bfd_aarch64_erratum_843419_p
4757 (contents
, vma
, i
, span_end
, &veneer_i
))
4759 uint32_t insn
= bfd_getl32 (contents
+ veneer_i
);
4761 if (!_bfd_aarch64_erratum_843419_fixup (insn
, i
, veneer_i
,
4768 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
4777 section_start_symbol (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*section
,
4780 return section
->vma
== *(bfd_vma
*)valp
;
4783 /* Capability format functions. */
4786 exponent (uint64_t len
)
4788 #define CAP_MAX_EXPONENT 50
4789 /* Size is a 65 bit value, so there's an implicit 0 MSB. */
4790 unsigned zeroes
= __builtin_clzl (len
) + 1;
4792 /* All bits up to and including CAP_MW - 2 are zero. */
4793 if (CAP_MAX_EXPONENT
< zeroes
)
4794 return (unsigned) -1;
4796 return CAP_MAX_EXPONENT
- zeroes
;
4797 #undef CAP_MAX_EXPONENT
4800 #define ONES(x) ((1ULL << (x)) - 1)
4801 #define ALIGN_UP(x, a) (((x) + ONES (a)) & (~ONES (a)))
4804 c64_valid_cap_range (bfd_vma
*basep
, bfd_vma
*limitp
, unsigned *alignmentp
)
4806 bfd_vma base
= *basep
, size
= *limitp
- *basep
;
4811 if ((e
= exponent (size
)) == (unsigned) -1)
4814 size
= ALIGN_UP (size
, e
+ 3);
4816 e
= exponent (size
);
4818 size
= ALIGN_UP (size
, e
+ 3);
4820 base
= ALIGN_UP (base
, e
+ 3);
4823 if (base
== *basep
&& *limitp
== base
+ size
)
4827 *limitp
= base
+ size
;
4831 struct sec_change_queue
4834 struct sec_change_queue
*next
;
4837 /* Queue up the change, sorted in order of the output section vma. */
4840 queue_section_padding (struct sec_change_queue
**queue
, asection
*sec
)
4842 struct sec_change_queue
*q
= *queue
, *last_q
= NULL
, *n
;
4846 if (q
->sec
->vma
> sec
->vma
)
4852 n
= bfd_zmalloc (sizeof (struct sec_change_queue
));
4865 /* Check if the bounds covering all sections between LOW_SEC and HIGH_SEC will
4866 get rounded off in the Morello capability format and if it does, queue up a
4867 change to fix up the section layout. */
4869 record_section_change (asection
*sec
, struct sec_change_queue
**queue
)
4871 bfd_vma low
= sec
->vma
;
4872 bfd_vma high
= sec
->vma
+ sec
->size
;
4875 if (!c64_valid_cap_range (&low
, &high
, &alignment
)
4876 || sec
->alignment_power
< alignment
)
4877 queue_section_padding (queue
, sec
);
4880 /* Make sure that all capabilities that refer to sections have bounds that
4881 won't overlap with neighbouring sections. This is needed in two specific
4882 cases. The first case is that of PCC, which needs to span across all
4883 readonly sections as well as the GOT and PLT sections in the output binary.
4884 The second case is that of linker and ldscript defined symbols that indicate
4885 start and/or end of sections and/or zero-sized symbols.
4887 In both cases, overlap of capability bounds are avoided by aligning the base
4888 of the section and if necessary, adding a pad at the end of the section so
4889 that the section following it starts only after the pad. */
4891 static bfd_vma pcc_low
;
4892 static bfd_vma pcc_high
;
4894 elfNN_c64_resize_sections (bfd
*output_bfd
, struct bfd_link_info
*info
,
4895 void (*c64_pad_section
) (asection
*, bfd_vma
),
4896 void (*layout_sections_again
) (void))
4898 asection
*sec
, *pcc_low_sec
= NULL
, *pcc_high_sec
= NULL
;
4899 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4900 bfd_vma low
= (bfd_vma
) -1, high
= 0;
4903 htab
->layout_sections_again
= layout_sections_again
;
4905 if (!htab
->c64_output
)
4908 struct sec_change_queue
*queue
= NULL
;
4910 /* First, walk through all the relocations to find those referring to linker
4911 defined and ldscript defined symbols since we set their range to their
4913 for (input_bfd
= info
->input_bfds
;
4914 htab
->c64_rel
&& input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
4916 Elf_Internal_Shdr
*symtab_hdr
;
4918 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4919 if (symtab_hdr
->sh_info
== 0)
4922 for (sec
= input_bfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
4924 Elf_Internal_Rela
*irelaend
, *irela
;
4926 /* If there aren't any relocs, then there's nothing more to do. */
4927 if ((sec
->flags
& SEC_RELOC
) == 0 || sec
->reloc_count
== 0)
4930 irela
= _bfd_elf_link_read_relocs (input_bfd
, sec
, NULL
, NULL
,
4935 /* Now examine each relocation. */
4936 irelaend
= irela
+ sec
->reloc_count
;
4937 for (; irela
< irelaend
; irela
++)
4939 unsigned int r_indx
;
4940 struct elf_link_hash_entry
*h
;
4944 r_indx
= ELFNN_R_SYM (irela
->r_info
);
4946 /* Linker defined or linker script defined symbols are always in
4948 if (r_indx
< symtab_hdr
->sh_info
)
4951 e_indx
= r_indx
- symtab_hdr
->sh_info
;
4952 h
= elf_sym_hashes (input_bfd
)[e_indx
];
4954 /* XXX Does this ever happen? */
4958 os
= h
->root
.u
.def
.section
->output_section
;
4960 if (h
->root
.linker_def
)
4961 record_section_change (os
, &queue
);
4962 else if (h
->root
.ldscript_def
)
4964 const char *name
= h
->root
.root
.string
;
4965 size_t len
= strlen (name
);
4967 if (len
> 8 && name
[0] == '_' && name
[1] == '_'
4968 && (!strncmp (name
+ 2, "start_", 6)
4969 || !strcmp (name
+ len
- 6, "_start")))
4971 bfd_vma value
= os
->vma
+ os
->size
;
4973 os
= bfd_sections_find_if (info
->output_bfd
,
4974 section_start_symbol
, &value
);
4977 record_section_change (os
, &queue
);
4979 /* XXX We're overfitting here because the offset of H within
4980 the output section is not yet resolved and ldscript
4981 defined symbols do not have input section information. */
4983 record_section_change (os
, &queue
);
4989 /* Next, walk through output sections to find the PCC span and add a padding
4990 at the end to ensure that PCC bounds don't bleed into neighbouring
4991 sections. For now PCC needs to encompass all code sections, .got, .plt
4993 for (sec
= output_bfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
4995 /* XXX This is a good place to figure out if there are any readable or
4996 writable sections in the PCC range that are not in the list of
4997 sections we want the PCC to span and then warn the user of it. */
4999 #define NOT_OP_SECTION(s) ((s) == NULL || (s)->output_section != sec)
5001 if ((sec
->flags
& SEC_READONLY
) == 0
5002 && NOT_OP_SECTION (htab
->root
.sgotplt
)
5003 && NOT_OP_SECTION (htab
->root
.igotplt
)
5004 && NOT_OP_SECTION (htab
->root
.sgot
)
5005 && NOT_OP_SECTION (htab
->root
.splt
)
5006 && NOT_OP_SECTION (htab
->root
.iplt
)
5007 && (sec
->vma
< info
->relro_start
5008 || sec
->vma
>= info
->relro_end
))
5010 if ((sec
->flags
& SEC_ALLOC
) == 0)
5018 if (sec
->vma
+ sec
->size
> high
)
5020 high
= sec
->vma
+ sec
->size
;
5024 #undef NOT_OP_SECTION
5027 /* Sequentially add alignment and padding as required. We also need to
5028 account for the PCC-related alignment and padding here since its
5029 requirements could change based on the range of sections it encompasses
5030 and whether they need to be padded or aligned. */
5034 bfd_vma padding
= 0;
5036 low
= queue
->sec
->vma
;
5037 high
= queue
->sec
->vma
+ queue
->sec
->size
;
5039 if (!c64_valid_cap_range (&low
, &high
, &align
))
5041 padding
= high
- low
- queue
->sec
->size
;
5043 if (queue
->sec
!= pcc_high_sec
)
5045 c64_pad_section (queue
->sec
, padding
);
5049 if (queue
->sec
->alignment_power
< align
)
5050 queue
->sec
->alignment_power
= align
;
5052 /* If we have crossed all sections within the PCC range, set up alignment
5053 and padding for the PCC range. */
5054 if (pcc_high_sec
!= NULL
&& pcc_low_sec
!= NULL
5055 && (queue
->next
== NULL
5056 || queue
->next
->sec
->vma
> pcc_high_sec
->vma
))
5058 /* Layout sections since it affects the final range of PCC. */
5059 (*htab
->layout_sections_again
) ();
5061 pcc_low
= pcc_low_sec
->vma
;
5062 pcc_high
= pcc_high_sec
->vma
+ pcc_high_sec
->size
+ padding
;
5064 if (!c64_valid_cap_range (&pcc_low
, &pcc_high
, &align
))
5066 bfd_vma current_length
=
5067 (pcc_high_sec
->vma
+ pcc_high_sec
->size
) - pcc_low_sec
->vma
;
5068 bfd_vma desired_length
= (pcc_high
- pcc_low
);
5069 padding
= desired_length
- current_length
;
5070 c64_pad_section (pcc_high_sec
, padding
);
5072 if (pcc_low_sec
->alignment_power
< align
)
5073 pcc_low_sec
->alignment_power
= align
;
5076 (*htab
->layout_sections_again
) ();
5078 struct sec_change_queue
*queue_free
= queue
;
5080 queue
= queue
->next
;
5088 pcc_low
= pcc_low_sec
->vma
;
5089 pcc_high
= pcc_high_sec
->vma
+ pcc_high_sec
->size
;
5093 /* Determine and set the size of the stub section for a final link.
5095 The basic idea here is to examine all the relocations looking for
5096 PC-relative calls to a target that either needs a PE state change (A64 to
5097 C64 or vice versa) or in case of unconditional branches (B/BL), is
5101 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
5103 struct bfd_link_info
*info
,
5104 bfd_signed_vma group_size
,
5105 asection
* (*add_stub_section
) (const char *,
5107 void (*layout_sections_again
) (void))
5109 bfd_size_type stub_group_size
;
5110 bfd_boolean stubs_always_before_branch
;
5111 bfd_boolean stub_changed
= FALSE
;
5112 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
5113 unsigned int num_erratum_835769_fixes
= 0;
5115 /* Propagate mach to stub bfd, because it may not have been
5116 finalized when we created stub_bfd. */
5117 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
5118 bfd_get_mach (output_bfd
));
5120 /* Stash our params away. */
5121 htab
->stub_bfd
= stub_bfd
;
5122 htab
->add_stub_section
= add_stub_section
;
5123 htab
->layout_sections_again
= layout_sections_again
;
5124 stubs_always_before_branch
= group_size
< 0;
5126 stub_group_size
= -group_size
;
5128 stub_group_size
= group_size
;
5130 if (stub_group_size
== 1)
5132 /* Default values. */
5133 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
5134 stub_group_size
= 127 * 1024 * 1024;
5137 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
5139 (*htab
->layout_sections_again
) ();
5141 if (htab
->fix_erratum_835769
)
5145 for (input_bfd
= info
->input_bfds
;
5146 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
5148 if (!is_aarch64_elf (input_bfd
)
5149 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
5152 if (!_bfd_aarch64_erratum_835769_scan (input_bfd
, info
,
5153 &num_erratum_835769_fixes
))
5157 _bfd_aarch64_resize_stubs (htab
);
5158 (*htab
->layout_sections_again
) ();
5161 if (htab
->fix_erratum_843419
!= ERRAT_NONE
)
5165 for (input_bfd
= info
->input_bfds
;
5167 input_bfd
= input_bfd
->link
.next
)
5171 if (!is_aarch64_elf (input_bfd
)
5172 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
5175 for (section
= input_bfd
->sections
;
5177 section
= section
->next
)
5178 if (!_bfd_aarch64_erratum_843419_scan (input_bfd
, section
, info
))
5182 _bfd_aarch64_resize_stubs (htab
);
5183 (*htab
->layout_sections_again
) ();
5190 for (input_bfd
= info
->input_bfds
;
5191 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
5193 Elf_Internal_Shdr
*symtab_hdr
;
5196 if (!is_aarch64_elf (input_bfd
)
5197 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
5200 /* We'll need the symbol table in a second. */
5201 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
5202 if (symtab_hdr
->sh_info
== 0)
5205 /* Walk over each section attached to the input bfd. */
5206 for (section
= input_bfd
->sections
;
5207 section
!= NULL
; section
= section
->next
)
5209 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
5211 /* If there aren't any relocs, then there's nothing more
5213 if ((section
->flags
& SEC_RELOC
) == 0
5214 || section
->reloc_count
== 0
5215 || (section
->flags
& SEC_CODE
) == 0)
5218 /* If this section is a link-once section that will be
5219 discarded, then don't create any stubs. */
5220 if (section
->output_section
== NULL
5221 || section
->output_section
->owner
!= output_bfd
)
5224 /* Get the relocs. */
5226 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
5227 NULL
, info
->keep_memory
);
5228 if (internal_relocs
== NULL
)
5229 goto error_ret_free_local
;
5231 /* Now examine each relocation. */
5232 irela
= internal_relocs
;
5233 irelaend
= irela
+ section
->reloc_count
;
5234 for (; irela
< irelaend
; irela
++)
5236 unsigned int r_type
, r_indx
;
5237 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
5238 struct elf_aarch64_stub_hash_entry
*stub_entry
;
5241 bfd_vma destination
;
5242 struct elf_aarch64_link_hash_entry
*hash
;
5243 const char *sym_name
;
5245 const asection
*id_sec
;
5246 unsigned char st_type
;
5248 unsigned branch_to_c64
= FALSE
;
5251 r_type
= ELFNN_R_TYPE (irela
->r_info
);
5252 r_indx
= ELFNN_R_SYM (irela
->r_info
);
5254 if (r_type
>= (unsigned int) R_AARCH64_end
)
5256 bfd_set_error (bfd_error_bad_value
);
5257 error_ret_free_internal
:
5258 if (elf_section_data (section
)->relocs
== NULL
)
5259 free (internal_relocs
);
5260 goto error_ret_free_local
;
5263 /* Only look for stubs on unconditional branch and
5264 branch and link instructions. */
5265 if (!aarch64_branch_reloc_p (r_type
))
5268 /* Now determine the call target, its name, value,
5275 if (r_indx
< symtab_hdr
->sh_info
)
5277 /* It's a local symbol. */
5278 Elf_Internal_Sym
*sym
=
5279 bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
5282 goto error_ret_free_internal
;
5284 branch_to_c64
|= (sym
->st_target_internal
5285 & ST_BRANCH_TO_C64
);
5287 Elf_Internal_Shdr
*hdr
=
5288 elf_elfsections (input_bfd
)[sym
->st_shndx
];
5290 sym_sec
= hdr
->bfd_section
;
5292 /* This is an undefined symbol. It can never
5296 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
5297 sym_value
= sym
->st_value
;
5298 destination
= (sym_value
+ irela
->r_addend
5299 + sym_sec
->output_offset
5300 + sym_sec
->output_section
->vma
);
5301 st_type
= ELF_ST_TYPE (sym
->st_info
);
5303 = bfd_elf_string_from_elf_section (input_bfd
,
5304 symtab_hdr
->sh_link
,
5307 /* Get the interworking stub if needed. */
5308 stub_type
= aarch64_interwork_stub (r_type
,
5314 struct elf_aarch64_link_hash_table
*globals
=
5315 elf_aarch64_hash_table (info
);
5317 e_indx
= r_indx
- symtab_hdr
->sh_info
;
5318 hash
= ((struct elf_aarch64_link_hash_entry
*)
5319 elf_sym_hashes (input_bfd
)[e_indx
]);
5321 while (hash
->root
.root
.type
== bfd_link_hash_indirect
5322 || hash
->root
.root
.type
== bfd_link_hash_warning
)
5323 hash
= ((struct elf_aarch64_link_hash_entry
*)
5324 hash
->root
.root
.u
.i
.link
);
5326 /* Static executable. */
5327 if (globals
->root
.splt
== NULL
|| hash
== NULL
5328 || hash
->root
.plt
.offset
== (bfd_vma
) - 1)
5330 branch_to_c64
|= (hash
->root
.target_internal
5331 & ST_BRANCH_TO_C64
);
5332 stub_type
= aarch64_interwork_stub (r_type
,
5336 if (hash
->root
.root
.type
== bfd_link_hash_defined
5337 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
5339 sym_sec
= hash
->root
.root
.u
.def
.section
;
5340 sym_value
= hash
->root
.root
.u
.def
.value
;
5341 /* For a destination in a shared library,
5342 use the PLT stub as target address to
5343 decide whether a branch stub is
5345 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
5346 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
5348 sym_sec
= globals
->root
.splt
;
5349 sym_value
= hash
->root
.plt
.offset
;
5350 if (sym_sec
->output_section
!= NULL
)
5351 destination
= (sym_value
5352 + sym_sec
->output_offset
5354 sym_sec
->output_section
->vma
);
5356 else if (sym_sec
->output_section
!= NULL
)
5357 destination
= (sym_value
+ irela
->r_addend
5358 + sym_sec
->output_offset
5359 + sym_sec
->output_section
->vma
);
5361 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
5362 || (hash
->root
.root
.type
5363 == bfd_link_hash_undefweak
))
5365 /* For a shared library, use the PLT stub as
5366 target address to decide whether a long
5367 branch stub is needed.
5368 For absolute code, they cannot be handled. */
5370 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
5371 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
5373 sym_sec
= globals
->root
.splt
;
5374 sym_value
= hash
->root
.plt
.offset
;
5375 if (sym_sec
->output_section
!= NULL
)
5376 destination
= (sym_value
5377 + sym_sec
->output_offset
5379 sym_sec
->output_section
->vma
);
5386 bfd_set_error (bfd_error_bad_value
);
5387 goto error_ret_free_internal
;
5389 st_type
= ELF_ST_TYPE (hash
->root
.type
);
5390 sym_name
= hash
->root
.root
.root
.string
;
5393 /* Determine what (if any) linker stub is needed. */
5394 if (stub_type
== aarch64_stub_none
)
5395 stub_type
= aarch64_type_of_stub (section
, irela
, sym_sec
,
5396 st_type
, destination
);
5398 if (stub_type
== aarch64_stub_none
)
5401 /* Support for grouping stub sections. */
5402 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
5404 /* Get the name of this stub. */
5405 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
5408 goto error_ret_free_internal
;
5411 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
5412 stub_name
, FALSE
, FALSE
);
5413 if (stub_entry
!= NULL
)
5415 /* The proper stub has already been created. */
5417 /* Always update this stub's target since it may have
5418 changed after layout. */
5419 stub_entry
->target_value
= sym_value
+ irela
->r_addend
;
5421 /* Set LSB for A64 to C64 branch. */
5423 stub_entry
->target_value
|= 1;
5428 stub_entry
= _bfd_aarch64_add_stub_entry_in_group
5429 (stub_name
, section
, htab
);
5430 if (stub_entry
== NULL
)
5433 goto error_ret_free_internal
;
5436 stub_entry
->target_value
= sym_value
+ irela
->r_addend
;
5437 /* Set LSB for A64 to C64 branch. */
5439 stub_entry
->target_value
|= 1;
5441 stub_entry
->target_section
= sym_sec
;
5442 stub_entry
->stub_type
= stub_type
;
5443 stub_entry
->h
= hash
;
5444 stub_entry
->st_type
= st_type
;
5446 suffix
= aarch64_lookup_stub_type_suffix (stub_type
);
5448 if (sym_name
== NULL
)
5449 sym_name
= "unnamed";
5450 len
= (sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
)
5452 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
5453 if (stub_entry
->output_name
== NULL
)
5456 goto error_ret_free_internal
;
5459 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
5462 stub_changed
= TRUE
;
5465 /* We're done with the internal relocs, free them. */
5466 if (elf_section_data (section
)->relocs
== NULL
)
5467 free (internal_relocs
);
5474 _bfd_aarch64_resize_stubs (htab
);
5476 /* Ask the linker to do its stuff. */
5477 (*htab
->layout_sections_again
) ();
5478 stub_changed
= FALSE
;
5483 error_ret_free_local
:
5487 /* Build all the stubs associated with the current output file. The
5488 stubs are kept in a hash table attached to the main linker hash
5489 table. We also set up the .plt entries for statically linked PIC
5490 functions here. This function is called via aarch64_elf_finish in the
5494 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
5497 struct bfd_hash_table
*table
;
5498 struct elf_aarch64_link_hash_table
*htab
;
5500 htab
= elf_aarch64_hash_table (info
);
5502 for (stub_sec
= htab
->stub_bfd
->sections
;
5503 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
5507 /* Ignore non-stub sections. */
5508 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
5511 /* Allocate memory to hold the linker stubs. */
5512 size
= stub_sec
->size
;
5513 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
5514 if (stub_sec
->contents
== NULL
&& size
!= 0)
5518 /* Add a branch around the stub section, and a nop, to keep it 8 byte
5519 aligned, as long branch stubs contain a 64-bit address. */
5520 bfd_putl32 (0x14000000 | (size
>> 2), stub_sec
->contents
);
5521 bfd_putl32 (INSN_NOP
, stub_sec
->contents
+ 4);
5522 stub_sec
->size
+= 8;
5525 /* Build the stubs as directed by the stub hash table. */
5526 table
= &htab
->stub_hash_table
;
5528 bfd_error_type save_error
= bfd_get_error ();
5529 bfd_set_error (bfd_error_no_error
);
5530 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
5532 if (bfd_get_error () != bfd_error_no_error
)
5535 bfd_set_error (save_error
);
5541 /* Add an entry to the code/data map for section SEC. */
5544 elfNN_aarch64_section_map_add (bfd
*abfd
, asection
*sec
, char type
,
5547 struct _aarch64_elf_section_data
*sec_data
=
5548 elf_aarch64_section_data (sec
);
5549 unsigned int newidx
;
5551 /* The aarch64 section hook was not called for this section. */
5552 if (!sec_data
->elf
.is_target_section_data
)
5554 struct _aarch64_elf_section_data
*newdata
=
5555 bfd_zalloc (abfd
, sizeof (*newdata
));
5557 if (newdata
== NULL
)
5560 newdata
->elf
= sec_data
->elf
;
5561 newdata
->elf
.is_target_section_data
= TRUE
;
5563 sec
->used_by_bfd
= sec_data
= newdata
;
5566 if (sec_data
->map
== NULL
)
5568 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
5569 sec_data
->mapcount
= 0;
5570 sec_data
->mapsize
= 1;
5573 newidx
= sec_data
->mapcount
++;
5575 if (sec_data
->mapcount
> sec_data
->mapsize
)
5577 sec_data
->mapsize
*= 2;
5578 sec_data
->map
= bfd_realloc_or_free
5579 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
5584 sec_data
->map
[newidx
].vma
= vma
;
5585 sec_data
->map
[newidx
].type
= type
;
5590 /* Initialise maps of insn/data for input BFDs. */
5592 bfd_elfNN_aarch64_init_maps (bfd
*abfd
, struct bfd_link_info
*info
)
5594 Elf_Internal_Sym
*isymbuf
;
5595 Elf_Internal_Shdr
*hdr
;
5596 unsigned int i
, localsyms
;
5598 /* Make sure that we are dealing with an AArch64 elf binary. */
5599 if (!is_aarch64_elf (abfd
))
5602 if (elf_aarch64_tdata (abfd
)->secmaps_initialised
)
5605 if ((abfd
->flags
& DYNAMIC
) != 0)
5608 hdr
= &elf_symtab_hdr (abfd
);
5609 localsyms
= hdr
->sh_info
;
5611 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
5612 should contain the number of local symbols, which should come before any
5613 global symbols. Mapping symbols are always local. */
5614 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
5616 /* No internal symbols read? Skip this BFD. */
5617 if (isymbuf
== NULL
)
5620 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table ((info
));
5622 for (i
= 0; i
< localsyms
; i
++)
5624 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
5625 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
5628 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
5630 name
= bfd_elf_string_from_elf_section (abfd
,
5634 if (bfd_is_aarch64_special_symbol_name
5635 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
5637 elfNN_aarch64_section_map_add (abfd
, sec
, name
[1],
5639 if (!htab
->c64_output
&& name
[1] == 'c')
5640 htab
->c64_output
= TRUE
;
5644 elf_aarch64_tdata (abfd
)->secmaps_initialised
= TRUE
;
5648 setup_plt_values (struct bfd_link_info
*link_info
,
5649 aarch64_plt_type plt_type
)
5651 struct elf_aarch64_link_hash_table
*globals
;
5652 globals
= elf_aarch64_hash_table (link_info
);
5654 /* Set up plt stubs in case we need C64 PLT. Override BTI/PAC since they're
5655 not compatible. PLT stub sizes are the same as the default ones. */
5656 if (globals
->c64_rel
)
5658 if (plt_type
!= PLT_NORMAL
)
5660 (_("ignoring C64-incompatible extensions: %s"),
5661 (plt_type
== PLT_BTI_PAC
? "BTI, PAC"
5662 : plt_type
== PLT_BTI
? "BTI" : "PAC"));
5664 globals
->plt0_entry
= elfNN_c64_small_plt0_entry
;
5665 globals
->plt_entry
= elfNN_c64_small_plt_entry
;
5669 if (plt_type
== PLT_BTI_PAC
)
5671 globals
->plt0_entry
= elfNN_aarch64_small_plt0_bti_entry
;
5673 /* Only in ET_EXEC we need PLTn with BTI. */
5674 if (bfd_link_pde (link_info
))
5676 globals
->plt_entry_size
= PLT_BTI_PAC_SMALL_ENTRY_SIZE
;
5677 globals
->plt_entry
= elfNN_aarch64_small_plt_bti_pac_entry
;
5681 globals
->plt_entry_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
5682 globals
->plt_entry
= elfNN_aarch64_small_plt_pac_entry
;
5685 else if (plt_type
== PLT_BTI
)
5687 globals
->plt0_entry
= elfNN_aarch64_small_plt0_bti_entry
;
5689 /* Only in ET_EXEC we need PLTn with BTI. */
5690 if (bfd_link_pde (link_info
))
5692 globals
->plt_entry_size
= PLT_BTI_SMALL_ENTRY_SIZE
;
5693 globals
->plt_entry
= elfNN_aarch64_small_plt_bti_entry
;
5696 else if (plt_type
== PLT_PAC
)
5698 globals
->plt_entry_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
5699 globals
->plt_entry
= elfNN_aarch64_small_plt_pac_entry
;
5703 /* Set option values needed during linking. */
5705 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
5706 struct bfd_link_info
*link_info
,
5708 int no_wchar_warn
, int pic_veneer
,
5709 int fix_erratum_835769
,
5710 erratum_84319_opts fix_erratum_843419
,
5711 int no_apply_dynamic_relocs
,
5712 aarch64_bti_pac_info bp_info
)
5714 struct elf_aarch64_link_hash_table
*globals
;
5716 globals
= elf_aarch64_hash_table (link_info
);
5717 globals
->pic_veneer
= pic_veneer
;
5718 globals
->fix_erratum_835769
= fix_erratum_835769
;
5719 /* If the default options are used, then ERRAT_ADR will be set by default
5720 which will enable the ADRP->ADR workaround for the erratum 843419
5722 globals
->fix_erratum_843419
= fix_erratum_843419
;
5723 globals
->no_apply_dynamic_relocs
= no_apply_dynamic_relocs
;
5724 globals
->c64_rel
= 0;
5726 BFD_ASSERT (is_aarch64_elf (output_bfd
));
5727 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
5728 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
5730 switch (bp_info
.bti_type
)
5733 elf_aarch64_tdata (output_bfd
)->no_bti_warn
= 0;
5734 elf_aarch64_tdata (output_bfd
)->gnu_and_prop
5735 |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI
;
5741 elf_aarch64_tdata (output_bfd
)->plt_type
= bp_info
.plt_type
;
5742 elf_aarch64_tdata (output_bfd
)->secmaps_initialised
= FALSE
;
5746 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
5747 struct elf_aarch64_link_hash_table
5748 *globals
, struct bfd_link_info
*info
,
5749 bfd_vma value
, bfd
*output_bfd
,
5750 bfd_boolean
*unresolved_reloc_p
)
5752 bfd_vma off
= (bfd_vma
) - 1;
5753 asection
*basegot
= globals
->root
.sgot
;
5754 bfd_boolean dyn
= globals
->root
.dynamic_sections_created
;
5758 BFD_ASSERT (basegot
!= NULL
);
5759 off
= h
->got
.offset
;
5760 BFD_ASSERT (off
!= (bfd_vma
) - 1);
5761 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
5762 || (bfd_link_pic (info
)
5763 && SYMBOL_REFERENCES_LOCAL (info
, h
))
5764 || (ELF_ST_VISIBILITY (h
->other
)
5765 && h
->root
.type
== bfd_link_hash_undefweak
))
5767 /* This is actually a static link, or it is a -Bsymbolic link
5768 and the symbol is defined locally. We must initialize this
5769 entry in the global offset table. Since the offset must
5770 always be a multiple of 8 (4 in the case of ILP32), we use
5771 the least significant bit to record whether we have
5772 initialized it already.
5773 When doing a dynamic link, we create a .rel(a).got relocation
5774 entry to initialize the value. This is done in the
5775 finish_dynamic_symbol routine. */
5780 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
5785 *unresolved_reloc_p
= FALSE
;
5787 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
5793 /* Change R_TYPE to a more efficient access model where possible,
5794 return the new reloc type. */
5796 static bfd_reloc_code_real_type
5797 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
5798 struct bfd_link_info
*info
,
5799 struct elf_link_hash_entry
*h
,
5800 bfd_boolean morello_reloc
)
5802 bfd_boolean is_local
= h
== NULL
;
5806 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
5807 return (is_local
|| !bfd_link_pic (info
)
5808 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5811 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5812 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5814 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5815 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
5817 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5819 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5822 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5824 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5825 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
5827 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5829 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5830 : BFD_RELOC_AARCH64_NONE
);
5832 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
5834 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5835 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
);
5837 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
5839 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5840 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
);
5842 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
5843 return ((is_local
|| !bfd_link_pie (info
)
5844 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
));
5846 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5847 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5849 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5850 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
5852 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5853 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
5855 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5856 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
5858 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5861 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5863 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
5864 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
5866 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
5867 return ((is_local
|| !bfd_link_pie (info
))
5868 ? BFD_RELOC_AARCH64_NONE
: r_type
);
5870 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
5871 if (morello_reloc
&& !is_local
&& bfd_link_pie (info
))
5874 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5875 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5876 /* Instructions with these relocations will be fully resolved during the
5877 transition into either a NOP in the A64 case or movk and add in
5879 return BFD_RELOC_AARCH64_NONE
;
5881 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5882 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5883 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5884 return is_local
? BFD_RELOC_AARCH64_NONE
: r_type
;
5887 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
5889 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5890 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
;
5892 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
5894 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5895 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
;
5906 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
5910 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5911 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5912 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5913 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5914 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
5915 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5916 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5917 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
5918 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
5921 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
5922 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
5925 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5926 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5927 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5928 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
5929 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
5930 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5931 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5932 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5935 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
5936 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
5937 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
5938 return GOT_TLSDESC_GD
| GOT_CAP
;
5940 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5941 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
5942 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5943 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5944 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5945 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5946 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
5947 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5948 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5949 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
5950 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
5951 return GOT_TLSDESC_GD
;
5953 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5954 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5955 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5956 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5957 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
5958 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
5968 aarch64_can_relax_tls (bfd
*input_bfd
,
5969 struct bfd_link_info
*info
,
5970 const Elf_Internal_Rela
*rel
,
5971 struct elf_link_hash_entry
*h
,
5972 unsigned long r_symndx
)
5974 unsigned int symbol_got_type
;
5975 unsigned int reloc_got_type
;
5977 bfd_reloc_code_real_type bfd_r_type
5978 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
,
5979 ELFNN_R_TYPE (rel
->r_info
));
5981 if (! IS_AARCH64_TLS_RELAX_RELOC (bfd_r_type
))
5984 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
5985 reloc_got_type
= aarch64_reloc_got_type (bfd_r_type
);
5987 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
5990 if (!bfd_link_executable (info
))
5993 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
5999 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
6002 static bfd_reloc_code_real_type
6003 aarch64_tls_transition (bfd
*input_bfd
,
6004 struct bfd_link_info
*info
,
6005 const Elf_Internal_Rela
*rel
,
6006 struct elf_link_hash_entry
*h
,
6007 unsigned long r_symndx
)
6009 bfd_reloc_code_real_type bfd_r_type
6010 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
,
6011 ELFNN_R_TYPE (rel
->r_info
));
6013 if (! aarch64_can_relax_tls (input_bfd
, info
, rel
, h
, r_symndx
))
6016 bfd_boolean morello_reloc
= (bfd_r_type
== BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
6017 && (ELFNN_R_TYPE (rel
[1].r_info
)
6018 == MORELLO_R (TLSDESC_CALL
)));
6020 /* GD -> IE is not supported for Morello TLSDESC yet. We do however allow
6021 lowering of GD -> LE for static non-pie executables. XXX It ought to be
6022 safe to do this for A64 as well but it is not implemented yet. */
6023 if (h
!= NULL
&& morello_reloc
&& bfd_link_pie (info
))
6026 return aarch64_tls_transition_without_check (bfd_r_type
, info
, h
,
6030 /* Return the base VMA address which should be subtracted from real addresses
6031 when resolving R_AARCH64_TLS_DTPREL relocation. */
6034 dtpoff_base (struct bfd_link_info
*info
)
6036 /* If tls_sec is NULL, we should have signalled an error already. */
6037 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
6038 return elf_hash_table (info
)->tls_sec
->vma
;
6041 /* Return the base VMA address which should be subtracted from real addresses
6042 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
6045 tpoff_base (struct bfd_link_info
*info
)
6047 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
6049 /* If tls_sec is NULL, we should have signalled an error already. */
6050 BFD_ASSERT (htab
->tls_sec
!= NULL
);
6052 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE
,
6053 htab
->tls_sec
->alignment_power
);
6054 return htab
->tls_sec
->vma
- base
;
6058 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6059 unsigned long r_symndx
)
6061 /* Calculate the address of the GOT entry for symbol
6062 referred to in h. */
6064 return &h
->got
.offset
;
6068 struct elf_aarch64_local_symbol
*l
;
6070 l
= elf_aarch64_locals (input_bfd
);
6071 return &l
[r_symndx
].got_offset
;
6076 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6077 unsigned long r_symndx
)
6080 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
6085 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6086 unsigned long r_symndx
)
6089 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
6094 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6095 unsigned long r_symndx
)
6098 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
6104 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6105 unsigned long r_symndx
)
6107 /* Calculate the address of the GOT entry for symbol
6108 referred to in h. */
6111 struct elf_aarch64_link_hash_entry
*eh
;
6112 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6113 return &eh
->tlsdesc_got_jump_table_offset
;
6118 struct elf_aarch64_local_symbol
*l
;
6120 l
= elf_aarch64_locals (input_bfd
);
6121 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
6126 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6127 unsigned long r_symndx
)
6130 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
6135 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
6136 struct elf_link_hash_entry
*h
,
6137 unsigned long r_symndx
)
6140 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
6145 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6146 unsigned long r_symndx
)
6149 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
6154 /* Data for make_branch_to_erratum_835769_stub(). */
6156 struct erratum_835769_branch_to_stub_data
6158 struct bfd_link_info
*info
;
6159 asection
*output_section
;
6163 /* Helper to insert branches to erratum 835769 stubs in the right
6164 places for a particular section. */
6167 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
6170 struct elf_aarch64_stub_hash_entry
*stub_entry
;
6171 struct erratum_835769_branch_to_stub_data
*data
;
6173 unsigned long branch_insn
= 0;
6174 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
6175 bfd_signed_vma branch_offset
;
6176 unsigned int target
;
6179 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
6180 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
6182 if (stub_entry
->target_section
!= data
->output_section
6183 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
6186 contents
= data
->contents
;
6187 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
6188 + stub_entry
->target_section
->output_offset
6189 + stub_entry
->target_value
;
6190 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
6191 + stub_entry
->stub_sec
->output_offset
6192 + stub_entry
->stub_offset
;
6193 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
6195 abfd
= stub_entry
->target_section
->owner
;
6196 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
6198 (_("%pB: error: erratum 835769 stub out "
6199 "of range (input file too large)"), abfd
);
6201 target
= stub_entry
->target_value
;
6202 branch_insn
= 0x14000000;
6203 branch_offset
>>= 2;
6204 branch_offset
&= 0x3ffffff;
6205 branch_insn
|= branch_offset
;
6206 bfd_putl32 (branch_insn
, &contents
[target
]);
6213 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry
*gen_entry
,
6216 struct elf_aarch64_stub_hash_entry
*stub_entry
6217 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
6218 struct erratum_835769_branch_to_stub_data
*data
6219 = (struct erratum_835769_branch_to_stub_data
*) in_arg
;
6220 struct bfd_link_info
*info
;
6221 struct elf_aarch64_link_hash_table
*htab
;
6229 contents
= data
->contents
;
6230 section
= data
->output_section
;
6232 htab
= elf_aarch64_hash_table (info
);
6234 if (stub_entry
->target_section
!= section
6235 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
)
6238 BFD_ASSERT (((htab
->fix_erratum_843419
& ERRAT_ADRP
) && stub_entry
->stub_sec
)
6239 || (htab
->fix_erratum_843419
& ERRAT_ADR
));
6241 /* Only update the stub section if we have one. We should always have one if
6242 we're allowed to use the ADRP errata workaround, otherwise it is not
6244 if (stub_entry
->stub_sec
)
6246 insn
= bfd_getl32 (contents
+ stub_entry
->target_value
);
6248 stub_entry
->stub_sec
->contents
+ stub_entry
->stub_offset
);
6251 place
= (section
->output_section
->vma
+ section
->output_offset
6252 + stub_entry
->adrp_offset
);
6253 insn
= bfd_getl32 (contents
+ stub_entry
->adrp_offset
);
6255 if (!_bfd_aarch64_adrp_p (insn
))
6258 bfd_signed_vma imm
=
6259 (_bfd_aarch64_sign_extend
6260 ((bfd_vma
) _bfd_aarch64_decode_adrp_imm (insn
) << 12, 33)
6263 if ((htab
->fix_erratum_843419
& ERRAT_ADR
)
6264 && (imm
>= AARCH64_MIN_ADRP_IMM
&& imm
<= AARCH64_MAX_ADRP_IMM
))
6266 insn
= (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP
, imm
, 0)
6267 | AARCH64_RT (insn
));
6268 bfd_putl32 (insn
, contents
+ stub_entry
->adrp_offset
);
6269 /* Stub is not needed, don't map it out. */
6270 stub_entry
->stub_type
= aarch64_stub_none
;
6272 else if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
6274 bfd_vma veneered_insn_loc
;
6275 bfd_vma veneer_entry_loc
;
6276 bfd_signed_vma branch_offset
;
6277 uint32_t branch_insn
;
6279 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
6280 + stub_entry
->target_section
->output_offset
6281 + stub_entry
->target_value
;
6282 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
6283 + stub_entry
->stub_sec
->output_offset
6284 + stub_entry
->stub_offset
;
6285 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
6287 abfd
= stub_entry
->target_section
->owner
;
6288 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
6290 (_("%pB: error: erratum 843419 stub out "
6291 "of range (input file too large)"), abfd
);
6293 branch_insn
= 0x14000000;
6294 branch_offset
>>= 2;
6295 branch_offset
&= 0x3ffffff;
6296 branch_insn
|= branch_offset
;
6297 bfd_putl32 (branch_insn
, contents
+ stub_entry
->target_value
);
6301 abfd
= stub_entry
->target_section
->owner
;
6303 (_("%pB: error: erratum 843419 immediate 0x%" BFD_VMA_FMT
"x "
6304 "out of range for ADR (input file too large) and "
6305 "--fix-cortex-a53-843419=adr used. Run the linker with "
6306 "--fix-cortex-a53-843419=full instead"), abfd
, imm
);
6307 bfd_set_error (bfd_error_bad_value
);
6308 /* This function is called inside a hashtable traversal and the error
6309 handlers called above turn into non-fatal errors. Which means this
6310 case ld returns an exit code 0 and also produces a broken object file.
6311 To prevent this, issue a hard abort. */
6319 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
6320 struct bfd_link_info
*link_info
,
6325 struct elf_aarch64_link_hash_table
*globals
=
6326 elf_aarch64_hash_table (link_info
);
6328 if (globals
== NULL
)
6331 /* Fix code to point to erratum 835769 stubs. */
6332 if (globals
->fix_erratum_835769
)
6334 struct erratum_835769_branch_to_stub_data data
;
6336 data
.info
= link_info
;
6337 data
.output_section
= sec
;
6338 data
.contents
= contents
;
6339 bfd_hash_traverse (&globals
->stub_hash_table
,
6340 make_branch_to_erratum_835769_stub
, &data
);
6343 if (globals
->fix_erratum_843419
)
6345 struct erratum_835769_branch_to_stub_data data
;
6347 data
.info
= link_info
;
6348 data
.output_section
= sec
;
6349 data
.contents
= contents
;
6350 bfd_hash_traverse (&globals
->stub_hash_table
,
6351 _bfd_aarch64_erratum_843419_branch_to_stub
, &data
);
6357 /* Return TRUE if RELOC is a relocation against the base of GOT table. */
6360 aarch64_relocation_aginst_gp_p (bfd_reloc_code_real_type reloc
)
6362 return (reloc
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
6363 || reloc
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
6364 || reloc
== BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
6365 || reloc
== BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
6366 || reloc
== BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
);
6369 /* Build capability meta data, i.e. size and permissions for a capability. */
6372 cap_meta (size_t size
, const asection
*sec
, bfd_boolean
*guessed
)
6375 if (size
>= (1ULL << 56))
6376 return (bfd_vma
) -1;
6378 /* N.b. We are only ever using this function for Morello.
6379 Morello is little-endian.
6380 We are returning a 64bit sized integer.
6381 The format this metadata is supposed to fit is
6382 | 56 bit length | 8 bit permissions |
6383 This means that (in little endian layout) we need to put the 56 bit size
6384 in the *lower* bits of the uint64_t. */
6386 if (sec
->flags
& SEC_CODE
)
6388 else if (sec
->flags
& SEC_READONLY
6389 || sec
->flags
& SEC_ROM
)
6391 else if (sec
->flags
& SEC_ALLOC
)
6394 /* We should usually be able to derive a valid set of permissions
6395 from the section flags. We know that when a relocation is against an
6396 SHN_ABS symbol the section has no associated flags and we must guess.
6398 As it stands we don't know of any other instances where we do not have
6399 permission flags on a section. We choose to allow instances that we do
6400 not know of rather than abort on them so that if the guess is correct we
6401 don't hamper anyone progressing. */
6408 return size
| (flags
<< 56);
6411 enum c64_section_perm_type
{
6412 C64_SYM_UNKNOWN
= 0,
6415 C64_SYM_LDSCRIPT_DEF
,
6416 C64_SYM_LDSCRIPT_START
,
6419 static enum c64_section_perm_type
6420 c64_symbol_section_adjustment (struct elf_link_hash_entry
*h
, bfd_vma value
,
6421 asection
*sym_sec
, asection
**ret_sec
,
6422 struct bfd_link_info
*info
)
6425 return C64_SYM_UNKNOWN
;
6429 return C64_SYM_STANDARD
;
6431 /* Linker defined symbols are always at the start of the section they
6433 if (h
->root
.linker_def
)
6434 return C64_SYM_LINKER_DEF
;
6435 else if (h
->root
.ldscript_def
)
6437 const char *name
= h
->root
.root
.string
;
6438 size_t len
= strlen (name
);
6440 bfd_vma size
= sym_sec
->size
- (value
- sym_sec
->vma
);
6441 /* The special case: the symbol is at the end of the section.
6442 This could either mean that it is an end symbol or it is the
6443 start of the output section following the symbol. We try to
6444 guess if it is a start of the next section by reading its
6445 name. This is a compatibility hack, ideally linker scripts
6446 should be written such that start symbols are defined within
6447 the output section it intends to track. */
6449 && (len
> 8 && name
[0] == '_' && name
[1] == '_'
6450 && (!strncmp (name
+ 2, "start_", 6)
6451 || !strcmp (name
+ len
- 6, "_start"))))
6453 asection
*s
= bfd_sections_find_if (info
->output_bfd
,
6454 section_start_symbol
,
6459 return C64_SYM_LDSCRIPT_START
;
6462 return C64_SYM_LDSCRIPT_DEF
;
6464 return C64_SYM_STANDARD
;
6467 static bfd_reloc_status_type
6468 c64_fixup_frag (bfd
*input_bfd
, struct bfd_link_info
*info
,
6469 bfd_reloc_code_real_type bfd_r_type
, Elf_Internal_Sym
*sym
,
6470 struct elf_link_hash_entry
*h
, asection
*sym_sec
,
6471 asection
*reloc_sec
, bfd_byte
*frag_loc
, bfd_vma value
,
6472 bfd_signed_vma addend
, bfd_vma r_offset
)
6474 BFD_ASSERT (h
|| sym
);
6475 bfd_vma size
= sym
? sym
->st_size
: h
->size
;
6476 asection
*perm_sec
= sym_sec
;
6477 bfd_boolean bounds_ok
= FALSE
;
6479 const int aarch64_reloc_idx
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6480 const char *reloc_name
= elfNN_aarch64_howto_table
[aarch64_reloc_idx
].name
;
6481 const char *sym_name
;
6485 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
6486 sym_name
= (bfd_elf_string_from_elf_section (input_bfd
,
6487 symtab_hdr
->sh_link
,
6491 sym_name
= h
->root
.root
.string
;
6493 if (size
== 0 && sym_sec
)
6496 enum c64_section_perm_type type
6497 = c64_symbol_section_adjustment (h
, value
, sym_sec
, &perm_sec
, info
);
6501 case C64_SYM_STANDARD
:
6503 case C64_SYM_LINKER_DEF
:
6504 size
= perm_sec
->output_section
->size
;
6506 case C64_SYM_LDSCRIPT_DEF
:
6507 size
= perm_sec
->size
- (value
- perm_sec
->vma
);
6509 case C64_SYM_LDSCRIPT_START
:
6510 size
= perm_sec
->size
;
6517 /* Negative addends are not allowed for capability symbols. */
6518 if (addend
< 0 || (bfd_vma
) addend
> size
)
6519 return bfd_reloc_outofrange
;
6521 bfd_vma base
= value
, limit
= value
+ size
;
6524 if (!bounds_ok
&& !c64_valid_cap_range (&base
, &limit
, &align
))
6526 /* Just warn about this. It's not a requirement that bounds on
6527 objects should be precise, so there's no reason to error out on
6529 /* xgettext:c-format */
6531 (_("%pB: capability range for '%s' may exceed object bounds"),
6532 input_bfd
, sym_name
);
6535 if (perm_sec
&& perm_sec
->flags
& SEC_CODE
)
6537 /* Any symbol pointing into an executable section gets bounds according
6538 to PCC. In this case the relocation is set up so that the value is
6539 the base of the PCC, the addend is the offset from the PCC base to the
6540 VA that we want, and the size is the length of the PCC range.
6541 In this function we only use `value` to check the bounds make sense,
6542 which is somewhat superfluous when we're using pcc_high and pcc_low
6543 since we already enforced that in elfNN_c64_resize_sections. No harm
6544 in instead checking that the bounds on the object that were requested
6545 made sense even if they were overridden because this symbol points
6546 into an executable section.
6548 `size` on the other hand is part of the fragment that we output to and
6549 we need to change it in order to have functions that can access global
6550 data or jump to other functions. */
6551 size
= pcc_high
- pcc_low
;
6554 if (perm_sec
!= NULL
)
6556 bfd_boolean permissions_guessed
= FALSE
;
6557 bfd_vma frag
= cap_meta (size
, perm_sec
, &permissions_guessed
);
6559 if (frag
== (bfd_vma
) -1)
6560 return bfd_reloc_outofrange
;
6562 if (permissions_guessed
)
6564 _bfd_error_handler (_("%pB(%pA+%#" PRIx64
"): "
6565 "warning: relocation %s against symbol '%s' in "
6566 "section without permission flags '%s'. "
6567 "Assuming Read-Write."),
6568 input_bfd
, reloc_sec
, r_offset
, reloc_name
,
6569 sym_name
, perm_sec
->name
);
6572 bfd_put_64 (input_bfd
, frag
, frag_loc
);
6575 return bfd_reloc_continue
;
6578 /* Given either a local symbol SYM or global symbol H, do we need to adjust
6579 capability relocations against the symbol due to the fact that it points to
6582 c64_symbol_adjust (struct elf_link_hash_entry
*h
,
6583 bfd_vma value
, asection
*sym_sec
, struct bfd_link_info
*info
,
6584 bfd_vma
*adjust_addr
)
6587 enum c64_section_perm_type type
6588 = c64_symbol_section_adjustment (h
, value
, sym_sec
, &tmp_sec
, info
);
6590 if (type
== C64_SYM_UNKNOWN
)
6593 if (tmp_sec
->flags
& SEC_CODE
)
6595 *adjust_addr
= pcc_low
;
6602 /* Perform a relocation as part of a final link. The input relocation type
6603 should be TLS relaxed. */
6605 static bfd_reloc_status_type
6606 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
6609 asection
*input_section
,
6611 Elf_Internal_Rela
*rel
,
6613 struct bfd_link_info
*info
,
6615 struct elf_link_hash_entry
*h
,
6616 bfd_boolean
*unresolved_reloc_p
,
6617 bfd_boolean save_addend
,
6618 bfd_vma
*saved_addend
,
6619 Elf_Internal_Sym
*sym
)
6621 Elf_Internal_Shdr
*symtab_hdr
;
6622 unsigned int r_type
= howto
->type
;
6623 bfd_reloc_code_real_type bfd_r_type
6624 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
6625 unsigned long r_symndx
;
6626 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
6627 bfd_vma place
, off
, got_entry_addr
= 0;
6628 bfd_signed_vma signed_addend
;
6629 struct elf_aarch64_link_hash_table
*globals
;
6630 bfd_boolean weak_undef_p
;
6631 bfd_boolean relative_reloc
;
6633 bfd_vma orig_value
= value
;
6634 bfd_boolean resolved_to_zero
;
6635 bfd_boolean abs_symbol_p
;
6636 Elf_Internal_Sym
*isym
= NULL
;
6637 bfd_boolean c64_rtype
= FALSE
;
6638 bfd_boolean to_c64
= FALSE
;
6640 globals
= elf_aarch64_hash_table (info
);
6642 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
6644 BFD_ASSERT (is_aarch64_elf (input_bfd
));
6646 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6648 place
= input_section
->output_section
->vma
6649 + input_section
->output_offset
+ rel
->r_offset
;
6651 /* Get addend, accumulating the addend for consecutive relocs
6652 which refer to the same offset. */
6653 signed_addend
= saved_addend
? *saved_addend
: 0;
6654 signed_addend
+= rel
->r_addend
;
6656 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
6657 : bfd_is_und_section (sym_sec
));
6658 abs_symbol_p
= h
!= NULL
&& bfd_is_abs_symbol (&h
->root
);
6662 isym
= bfd_sym_from_r_symndx (&globals
->root
.sym_cache
, input_bfd
,
6664 BFD_ASSERT (isym
!= NULL
);
6665 to_c64
= (isym
->st_target_internal
& ST_BRANCH_TO_C64
) != 0;
6668 to_c64
= (h
->target_internal
& ST_BRANCH_TO_C64
) != 0;
6671 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
6672 it here if it is defined in a non-shared object. */
6674 && h
->type
== STT_GNU_IFUNC
6681 if ((input_section
->flags
& SEC_ALLOC
) == 0)
6683 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
6684 STT_GNU_IFUNC symbol as STT_FUNC. */
6685 if (elf_section_type (input_section
) == SHT_NOTE
)
6688 /* Dynamic relocs are not propagated for SEC_DEBUGGING
6689 sections because such sections are not SEC_ALLOC and
6690 thus ld.so will not process them. */
6691 if ((input_section
->flags
& SEC_DEBUGGING
) != 0)
6692 return bfd_reloc_ok
;
6694 if (h
->root
.root
.string
)
6695 name
= h
->root
.root
.string
;
6697 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
, NULL
);
6699 /* xgettext:c-format */
6700 (_("%pB(%pA+%#" PRIx64
"): "
6701 "unresolvable %s relocation against symbol `%s'"),
6702 input_bfd
, input_section
, (uint64_t) rel
->r_offset
,
6704 bfd_set_error (bfd_error_bad_value
);
6705 return bfd_reloc_notsupported
;
6707 else if (h
->plt
.offset
== (bfd_vma
) -1)
6708 goto bad_ifunc_reloc
;
6710 /* STT_GNU_IFUNC symbol must go through PLT. */
6711 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
6712 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
6718 if (h
->root
.root
.string
)
6719 name
= h
->root
.root
.string
;
6721 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
6724 /* xgettext:c-format */
6725 (_("%pB: relocation %s against STT_GNU_IFUNC "
6726 "symbol `%s' isn't handled by %s"), input_bfd
,
6727 howto
->name
, name
, __FUNCTION__
);
6728 bfd_set_error (bfd_error_bad_value
);
6729 return bfd_reloc_notsupported
;
6731 case BFD_RELOC_AARCH64_NN
:
6732 if (rel
->r_addend
!= 0)
6734 if (h
->root
.root
.string
)
6735 name
= h
->root
.root
.string
;
6737 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
6740 /* xgettext:c-format */
6741 (_("%pB: relocation %s against STT_GNU_IFUNC "
6742 "symbol `%s' has non-zero addend: %" PRId64
),
6743 input_bfd
, howto
->name
, name
, (int64_t) rel
->r_addend
);
6744 bfd_set_error (bfd_error_bad_value
);
6745 return bfd_reloc_notsupported
;
6748 /* Generate dynamic relocation only when there is a
6749 non-GOT reference in a shared object. */
6750 if (bfd_link_pic (info
) && h
->non_got_ref
)
6752 Elf_Internal_Rela outrel
;
6755 /* Need a dynamic relocation to get the real function
6757 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
6761 if (outrel
.r_offset
== (bfd_vma
) -1
6762 || outrel
.r_offset
== (bfd_vma
) -2)
6765 outrel
.r_offset
+= (input_section
->output_section
->vma
6766 + input_section
->output_offset
);
6768 if (h
->dynindx
== -1
6770 || bfd_link_executable (info
))
6772 /* This symbol is resolved locally. */
6773 outrel
.r_info
= (elf_aarch64_hash_entry (h
)->got_type
6775 ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE
))
6776 : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
)));
6777 outrel
.r_addend
= (h
->root
.u
.def
.value
6778 + h
->root
.u
.def
.section
->output_section
->vma
6779 + h
->root
.u
.def
.section
->output_offset
);
6783 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
6784 outrel
.r_addend
= 0;
6787 sreloc
= globals
->root
.irelifunc
;
6788 elf_append_rela (output_bfd
, sreloc
, &outrel
);
6790 /* If this reloc is against an external symbol, we
6791 do not want to fiddle with the addend. Otherwise,
6792 we need to include the symbol value so that it
6793 becomes an addend for the dynamic reloc. For an
6794 internal symbol, we have updated addend. */
6795 return bfd_reloc_ok
;
6798 case BFD_RELOC_MORELLO_CALL26
:
6799 case BFD_RELOC_MORELLO_JUMP26
:
6800 case BFD_RELOC_AARCH64_CALL26
:
6801 case BFD_RELOC_AARCH64_JUMP26
:
6802 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6806 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
6808 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6809 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
6810 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6811 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6812 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6813 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6814 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
6815 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
6816 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
6817 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6818 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
6819 base_got
= globals
->root
.sgot
;
6820 off
= h
->got
.offset
;
6822 if (base_got
== NULL
)
6825 if (off
== (bfd_vma
) -1)
6829 /* We can't use h->got.offset here to save state, or
6830 even just remember the offset, as finish_dynamic_symbol
6831 would use that as offset into .got. */
6833 if (globals
->root
.splt
!= NULL
)
6835 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
6836 globals
->plt_entry_size
);
6837 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE (globals
);
6838 base_got
= globals
->root
.sgotplt
;
6842 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
6843 off
= plt_index
* GOT_ENTRY_SIZE (globals
);
6844 base_got
= globals
->root
.igotplt
;
6847 if (h
->dynindx
== -1
6851 /* This references the local definition. We must
6852 initialize this entry in the global offset table.
6853 Since the offset must always be a multiple of 8,
6854 we use the least significant bit to record
6855 whether we have initialized it already.
6857 When doing a dynamic link, we create a .rela.got
6858 relocation entry to initialize the value. This
6859 is done in the finish_dynamic_symbol routine. */
6864 bfd_put_NN (output_bfd
, value
,
6865 base_got
->contents
+ off
);
6866 /* Note that this is harmless as -1 | 1 still is -1. */
6870 value
= (base_got
->output_section
->vma
6871 + base_got
->output_offset
+ off
);
6874 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
6876 unresolved_reloc_p
);
6878 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
6879 addend
= (globals
->root
.sgot
->output_section
->vma
6880 + globals
->root
.sgot
->output_offset
);
6882 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6884 addend
, weak_undef_p
);
6885 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
6886 case BFD_RELOC_AARCH64_ADD_LO12
:
6887 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6888 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
6894 resolved_to_zero
= (h
!= NULL
6895 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
6899 case BFD_RELOC_AARCH64_NONE
:
6900 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
6901 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
6902 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
6903 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
6904 *unresolved_reloc_p
= FALSE
;
6905 return bfd_reloc_ok
;
6907 case BFD_RELOC_AARCH64_NN
:
6909 /* When generating a shared object or relocatable executable, these
6910 relocations are copied into the output file to be resolved at
6912 if (((bfd_link_pic (info
)
6913 || globals
->root
.is_relocatable_executable
)
6914 && (input_section
->flags
& SEC_ALLOC
)
6916 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
6917 && !resolved_to_zero
)
6918 || h
->root
.type
!= bfd_link_hash_undefweak
))
6919 /* Or we are creating an executable, we may need to keep relocations
6920 for symbols satisfied by a dynamic library if we manage to avoid
6921 copy relocs for the symbol. */
6922 || (ELIMINATE_COPY_RELOCS
6923 && !bfd_link_pic (info
)
6925 && (input_section
->flags
& SEC_ALLOC
)
6930 || h
->root
.type
== bfd_link_hash_undefweak
6931 || h
->root
.type
== bfd_link_hash_undefined
)))
6933 Elf_Internal_Rela outrel
;
6935 bfd_boolean skip
, relocate
;
6938 *unresolved_reloc_p
= FALSE
;
6943 outrel
.r_addend
= signed_addend
;
6945 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
6947 if (outrel
.r_offset
== (bfd_vma
) - 1)
6949 else if (outrel
.r_offset
== (bfd_vma
) - 2)
6954 else if (abs_symbol_p
)
6956 /* Local absolute symbol. */
6957 skip
= (h
->forced_local
|| (h
->dynindx
== -1));
6961 outrel
.r_offset
+= (input_section
->output_section
->vma
6962 + input_section
->output_offset
);
6965 memset (&outrel
, 0, sizeof outrel
);
6968 && (!bfd_link_pic (info
)
6969 || !(bfd_link_pie (info
) || SYMBOLIC_BIND (info
, h
))
6970 || !h
->def_regular
))
6971 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
6976 /* On SVR4-ish systems, the dynamic loader cannot
6977 relocate the text and data segments independently,
6978 so the symbol does not matter. */
6980 relocate
= globals
->no_apply_dynamic_relocs
? FALSE
: TRUE
;
6981 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
6982 outrel
.r_addend
+= value
;
6985 sreloc
= elf_section_data (input_section
)->sreloc
;
6986 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
6987 return bfd_reloc_notsupported
;
6989 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
6990 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
6992 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
6994 /* Sanity to check that we have previously allocated
6995 sufficient space in the relocation section for the
6996 number of relocations we actually want to emit. */
7000 /* If this reloc is against an external symbol, we do not want to
7001 fiddle with the addend. Otherwise, we need to include the symbol
7002 value so that it becomes an addend for the dynamic reloc. */
7004 return bfd_reloc_ok
;
7006 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
7007 contents
, rel
->r_offset
, value
,
7011 value
+= signed_addend
;
7014 case BFD_RELOC_MORELLO_CALL26
:
7015 case BFD_RELOC_MORELLO_JUMP26
:
7016 case BFD_RELOC_AARCH64_CALL26
:
7017 case BFD_RELOC_AARCH64_JUMP26
:
7019 asection
*splt
= globals
->root
.splt
;
7020 bfd_boolean via_plt_p
=
7021 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
7023 /* A call to an undefined weak symbol is converted to a jump to
7024 the next instruction unless a PLT entry will be created.
7025 The jump to the next instruction is optimized as a NOP.
7026 Do the same for local undefined symbols. */
7027 if (weak_undef_p
&& ! via_plt_p
)
7029 bfd_putl32 (INSN_NOP
, hit_data
);
7030 return bfd_reloc_ok
;
7033 /* If the call goes through a PLT entry, make sure to
7034 check distance to the right destination address. */
7036 value
= (splt
->output_section
->vma
7037 + splt
->output_offset
+ h
->plt
.offset
);
7039 /* Check if a stub has to be inserted because the destination
7041 struct elf_aarch64_stub_hash_entry
*stub_entry
= NULL
;
7043 enum elf_aarch64_stub_type c64_stub
= aarch64_stub_none
;
7045 /* Figure out if we need an interworking stub and if yes, what
7048 c64_stub
= aarch64_interwork_stub (r_type
, to_c64
);
7050 /* If the branch destination is directed to plt stub, "value" will be
7051 the final destination, otherwise we should plus signed_addend, it may
7052 contain non-zero value, for example call to local function symbol
7053 which are turned into "sec_sym + sec_off", and sec_off is kept in
7055 if (c64_stub
!= aarch64_stub_none
7056 || (aarch64_branch_reloc_p (r_type
)
7057 && !aarch64_valid_branch_p ((via_plt_p
? value
7058 : value
+ signed_addend
), place
)))
7060 /* The target is out of reach, so redirect the branch to
7061 the local stub for this function. */
7062 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
, sym_sec
,
7067 if (stub_entry
!= NULL
)
7069 value
= (stub_entry
->stub_offset
7070 + stub_entry
->stub_sec
->output_offset
7071 + stub_entry
->stub_sec
->output_section
->vma
);
7073 /* We have redirected the destination to stub entry address,
7074 so ignore any addend record in the original rela entry. */
7078 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7080 signed_addend
, weak_undef_p
);
7081 *unresolved_reloc_p
= FALSE
;
7084 case BFD_RELOC_AARCH64_16_PCREL
:
7085 case BFD_RELOC_AARCH64_32_PCREL
:
7086 case BFD_RELOC_AARCH64_64_PCREL
:
7087 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
7088 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
7089 case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL
:
7090 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
7091 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
7092 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
7093 case BFD_RELOC_MORELLO_LD_LO17_PCREL
:
7094 case BFD_RELOC_AARCH64_MOVW_PREL_G0
:
7095 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC
:
7096 case BFD_RELOC_AARCH64_MOVW_PREL_G1
:
7097 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC
:
7098 case BFD_RELOC_AARCH64_MOVW_PREL_G2
:
7099 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC
:
7100 case BFD_RELOC_AARCH64_MOVW_PREL_G3
:
7101 if (bfd_link_pic (info
)
7102 && (input_section
->flags
& SEC_ALLOC
) != 0
7103 && (input_section
->flags
& SEC_READONLY
) != 0
7104 && !SYMBOL_REFERENCES_LOCAL (info
, h
))
7106 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7109 /* xgettext:c-format */
7110 (_("%pB: relocation %s against symbol `%s' which may bind "
7111 "externally can not be used when making a shared object; "
7112 "recompile with -fPIC"),
7113 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7114 h
->root
.root
.string
);
7115 bfd_set_error (bfd_error_bad_value
);
7116 return bfd_reloc_notsupported
;
7118 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7123 if (bfd_r_type
== BFD_RELOC_AARCH64_ADR_LO21_PCREL
&& isym
!= NULL
7124 && isym
->st_target_internal
& ST_BRANCH_TO_C64
)
7128 case BFD_RELOC_MORELLO_BRANCH19
:
7129 case BFD_RELOC_MORELLO_TSTBR14
:
7132 case BFD_RELOC_AARCH64_BRANCH19
:
7133 case BFD_RELOC_AARCH64_TSTBR14
:
7134 if (h
&& h
->root
.type
== bfd_link_hash_undefined
)
7137 /* xgettext:c-format */
7138 (_("%pB: conditional branch to undefined symbol `%s' "
7139 "not allowed"), input_bfd
, h
->root
.root
.string
);
7140 bfd_set_error (bfd_error_bad_value
);
7141 return bfd_reloc_notsupported
;
7144 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7146 if ((c64_rtype
&& !to_c64
) || (!c64_rtype
&& to_c64
))
7149 /* xgettext:c-format */
7150 (_("%pB: interworking not supported on relocation %s"),
7151 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
7152 return bfd_reloc_notsupported
;
7157 case BFD_RELOC_AARCH64_16
:
7159 case BFD_RELOC_AARCH64_32
:
7161 case BFD_RELOC_AARCH64_ADD_LO12
:
7162 case BFD_RELOC_AARCH64_LDST128_LO12
:
7163 case BFD_RELOC_AARCH64_LDST16_LO12
:
7164 case BFD_RELOC_AARCH64_LDST32_LO12
:
7165 case BFD_RELOC_AARCH64_LDST64_LO12
:
7166 case BFD_RELOC_AARCH64_LDST8_LO12
:
7167 case BFD_RELOC_AARCH64_MOVW_G0
:
7168 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
7169 case BFD_RELOC_AARCH64_MOVW_G0_S
:
7170 case BFD_RELOC_AARCH64_MOVW_G1
:
7171 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
7172 case BFD_RELOC_AARCH64_MOVW_G1_S
:
7173 case BFD_RELOC_AARCH64_MOVW_G2
:
7174 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
7175 case BFD_RELOC_AARCH64_MOVW_G2_S
:
7176 case BFD_RELOC_AARCH64_MOVW_G3
:
7177 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7179 signed_addend
, weak_undef_p
);
7180 if (bfd_r_type
== BFD_RELOC_AARCH64_ADD_LO12
&& isym
!= NULL
7181 && isym
->st_target_internal
& ST_BRANCH_TO_C64
)
7186 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
7187 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
7188 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
7189 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
7190 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
7191 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
7192 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
7193 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
7194 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
7195 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
7196 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
7197 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
7198 base_got
= globals
->root
.sgot
;
7200 bfd_boolean c64_reloc
=
7201 (bfd_r_type
== BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
7202 || bfd_r_type
== BFD_RELOC_MORELLO_ADR_GOT_PAGE
);
7204 if (signed_addend
!= 0)
7206 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7208 /* xgettext:c-format */
7209 (_("%pB: symbol plus addend can not be placed into the GOT "
7210 "for relocation %s"),
7211 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
7215 if (base_got
== NULL
)
7216 BFD_ASSERT (h
!= NULL
);
7218 relative_reloc
= FALSE
;
7224 /* If a symbol is not dynamic and is not undefined weak, bind it
7225 locally and generate a RELATIVE relocation under PIC mode.
7227 NOTE: one symbol may be referenced by several relocations, we
7228 should only generate one RELATIVE relocation for that symbol.
7229 Therefore, check GOT offset mark first.
7231 NOTE2: Symbol references via GOT in C64 static binaries without
7232 PIC should always have relative relocations, so we do that here
7234 if (((h
->dynindx
== -1
7236 && h
->root
.type
!= bfd_link_hash_undefweak
7237 && bfd_link_pic (info
))
7238 || (!bfd_link_pic (info
) && bfd_link_executable (info
)
7240 && !symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7241 relative_reloc
= TRUE
;
7244 && c64_symbol_adjust (h
, value
, sym_sec
, info
, &frag_value
))
7245 signed_addend
= (value
| h
->target_internal
) - frag_value
;
7247 frag_value
= value
| h
->target_internal
;
7249 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
7252 unresolved_reloc_p
);
7253 /* Record the GOT entry address which will be used when generating
7254 RELATIVE relocation. */
7256 got_entry_addr
= value
;
7258 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
7259 addend
= (globals
->root
.sgot
->output_section
->vma
7260 + globals
->root
.sgot
->output_offset
);
7261 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7263 addend
, weak_undef_p
);
7268 struct elf_aarch64_local_symbol
*locals
7269 = elf_aarch64_locals (input_bfd
);
7273 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7275 /* xgettext:c-format */
7276 (_("%pB: local symbol descriptor table be NULL when applying "
7277 "relocation %s against local symbol"),
7278 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
7282 got_entry_addr
= (base_got
->output_section
->vma
7283 + base_got
->output_offset
+ off
);
7285 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7290 && c64_symbol_adjust (h
, value
, sym_sec
, info
, &frag_value
))
7291 signed_addend
= (value
| sym
->st_target_internal
) - frag_value
;
7293 frag_value
= value
| sym
->st_target_internal
;
7295 bfd_put_64 (output_bfd
, frag_value
, base_got
->contents
+ off
);
7297 /* For local symbol, we have done absolute relocation in static
7298 linking stage. While for shared library, we need to update the
7299 content of GOT entry according to the shared object's runtime
7300 base address. So, we need to generate a R_AARCH64_RELATIVE reloc
7301 for dynamic linker. */
7302 if (bfd_link_pic (info
)
7303 || (!bfd_link_pic (info
) && bfd_link_executable (info
)
7305 relative_reloc
= TRUE
;
7307 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
7310 /* Update the relocation value to GOT entry addr as we have transformed
7311 the direct data access into indirect data access through GOT. */
7312 value
= got_entry_addr
;
7314 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
7315 addend
= base_got
->output_section
->vma
+ base_got
->output_offset
;
7317 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7319 addend
, weak_undef_p
);
7325 Elf_Internal_Rela outrel
;
7327 enum elf_aarch64_reloc_type rtype
= AARCH64_R (RELATIVE
);
7329 s
= globals
->root
.srelgot
;
7331 /* For a C64 relative relocation, also add size and permissions into
7335 bfd_reloc_status_type ret
;
7337 ret
= c64_fixup_frag (input_bfd
, info
, bfd_r_type
, sym
, h
,
7338 sym_sec
, s
, base_got
->contents
+ off
+ 8,
7339 orig_value
, 0, off
);
7341 if (ret
!= bfd_reloc_continue
)
7344 rtype
= MORELLO_R (RELATIVE
);
7346 if (bfd_link_executable (info
) && !bfd_link_pic (info
))
7347 s
= globals
->srelcaps
;
7349 outrel
.r_addend
= signed_addend
;
7352 outrel
.r_addend
= orig_value
;
7357 outrel
.r_offset
= got_entry_addr
;
7358 outrel
.r_info
= ELFNN_R_INFO (0, rtype
);
7359 elf_append_rela (output_bfd
, s
, &outrel
);
7363 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
7364 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
7365 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
7366 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
7367 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
7368 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
7369 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
7370 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
7371 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
7372 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
7373 if (globals
->root
.sgot
== NULL
)
7374 return bfd_reloc_notsupported
;
7376 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
7377 + globals
->root
.sgot
->output_section
->vma
7378 + globals
->root
.sgot
->output_offset
);
7380 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7383 *unresolved_reloc_p
= FALSE
;
7386 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
7387 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
7388 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
7389 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
7390 if (globals
->root
.sgot
== NULL
)
7391 return bfd_reloc_notsupported
;
7393 value
= symbol_got_offset (input_bfd
, h
, r_symndx
);
7394 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7397 *unresolved_reloc_p
= FALSE
;
7400 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
7401 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
7402 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
7403 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
7404 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
7405 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
7406 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
7407 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
7408 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
7409 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
7410 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
7411 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
7412 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
7413 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
7414 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
7415 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
7417 if (!(weak_undef_p
|| elf_hash_table (info
)->tls_sec
))
7419 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7421 /* xgettext:c-format */
7422 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
7423 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7424 h
->root
.root
.string
);
7425 bfd_set_error (bfd_error_bad_value
);
7426 return bfd_reloc_notsupported
;
7430 = weak_undef_p
? 0 : signed_addend
- dtpoff_base (info
);
7431 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7433 def_value
, weak_undef_p
);
7437 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
7438 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
7439 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
7440 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
:
7441 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
:
7442 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
:
7443 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
:
7444 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
:
7445 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
:
7446 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
:
7447 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
:
7448 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
7449 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
7450 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
7451 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
7452 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
7454 if (!(weak_undef_p
|| elf_hash_table (info
)->tls_sec
))
7456 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7458 /* xgettext:c-format */
7459 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
7460 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7461 h
->root
.root
.string
);
7462 bfd_set_error (bfd_error_bad_value
);
7463 return bfd_reloc_notsupported
;
7467 = weak_undef_p
? 0 : signed_addend
- tpoff_base (info
);
7468 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7470 def_value
, weak_undef_p
);
7471 *unresolved_reloc_p
= FALSE
;
7475 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
7476 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
7477 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
7478 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
7479 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
7480 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
7481 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
7482 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
7483 if (globals
->root
.sgot
== NULL
)
7484 return bfd_reloc_notsupported
;
7485 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
7486 + globals
->root
.sgotplt
->output_section
->vma
7487 + globals
->root
.sgotplt
->output_offset
7488 + globals
->sgotplt_jump_table_size
);
7490 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7493 *unresolved_reloc_p
= FALSE
;
7496 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
7497 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
7498 if (globals
->root
.sgot
== NULL
)
7499 return bfd_reloc_notsupported
;
7501 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
7502 + globals
->root
.sgotplt
->output_section
->vma
7503 + globals
->root
.sgotplt
->output_offset
7504 + globals
->sgotplt_jump_table_size
);
7506 value
-= (globals
->root
.sgot
->output_section
->vma
7507 + globals
->root
.sgot
->output_offset
);
7509 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7512 *unresolved_reloc_p
= FALSE
;
7515 case BFD_RELOC_MORELLO_CAPINIT
:
7517 Elf_Internal_Rela outrel
;
7519 if (input_section
->flags
& SEC_READONLY
)
7522 /* xgettext:c-format */
7523 (_("%pB: capability relocation section must be writable"),
7525 bfd_set_error (bfd_error_bad_value
);
7526 return bfd_reloc_notsupported
;
7529 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
7533 outrel
.r_offset
+= (input_section
->output_section
->vma
7534 + input_section
->output_offset
);
7536 /* Capability-aligned. */
7537 if (outrel
.r_offset
& 0xf)
7538 return bfd_reloc_overflow
;
7540 bfd_reloc_status_type ret
;
7542 ret
= c64_fixup_frag (input_bfd
, info
, bfd_r_type
, sym
, h
, sym_sec
,
7543 input_section
, hit_data
+ 8, value
,
7544 signed_addend
, rel
->r_offset
);
7546 if (ret
!= bfd_reloc_continue
)
7549 outrel
.r_addend
= signed_addend
;
7550 value
|= (h
!= NULL
? h
->target_internal
: sym
->st_target_internal
);
7552 /* Emit a dynamic relocation if we are building PIC. */
7555 && bfd_link_pic (info
)
7556 && !SYMBOL_REFERENCES_LOCAL (info
, h
))
7557 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
7559 outrel
.r_info
= ELFNN_R_INFO (0, MORELLO_R (RELATIVE
));
7561 /* Symbols without size information get bounds to the
7562 whole section: adjust the base of the capability to the
7563 start of the section and set the addend to obtain the
7564 correct address for the symbol. */
7566 if (c64_symbol_adjust (h
, value
, sym_sec
, info
, &new_value
))
7568 outrel
.r_addend
+= (value
- new_value
);
7572 asection
*s
= globals
->srelcaps
;
7574 elf_append_rela (output_bfd
, s
, &outrel
);
7575 *unresolved_reloc_p
= FALSE
;
7580 return bfd_reloc_notsupported
;
7584 *saved_addend
= value
;
7586 /* Only apply the final relocation in a sequence. */
7588 return bfd_reloc_continue
;
7590 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
7594 /* LP64 and ILP32 operates on x- and w-registers respectively.
7595 Next definitions take into account the difference between
7596 corresponding machine codes. R means x-register if the target
7597 arch is LP64, and w-register if the target is ILP32. */
7600 # define add_R0_R0 (0x91000000)
7601 # define add_R0_R0_R1 (0x8b000020)
7602 # define add_R0_R1 (0x91400020)
7603 # define ldr_R0 (0x58000000)
7604 # define ldr_R0_mask(i) (i & 0xffffffe0)
7605 # define ldr_R0_x0 (0xf9400000)
7606 # define ldr_hw_R0 (0xf2a00000)
7607 # define movk_R0 (0xf2800000)
7608 # define movz_R0 (0xd2a00000)
7609 # define movz_hw_R0 (0xd2c00000)
7610 #else /*ARCH_SIZE == 32 */
7611 # define add_R0_R0 (0x11000000)
7612 # define add_R0_R0_R1 (0x0b000020)
7613 # define add_R0_R1 (0x11400020)
7614 # define ldr_R0 (0x18000000)
7615 # define ldr_R0_mask(i) (i & 0xbfffffe0)
7616 # define ldr_R0_x0 (0xb9400000)
7617 # define ldr_hw_R0 (0x72a00000)
7618 # define movk_R0 (0x72800000)
7619 # define movz_R0 (0x52a00000)
7620 # define movz_hw_R0 (0x52c00000)
7623 /* Structure to hold payload for _bfd_aarch64_erratum_843419_clear_stub,
7624 it is used to identify the stub information to reset. */
7626 struct erratum_843419_branch_to_stub_clear_data
7628 bfd_vma adrp_offset
;
7629 asection
*output_section
;
7632 /* Clear the erratum information for GEN_ENTRY if the ADRP_OFFSET and
7633 section inside IN_ARG matches. The clearing is done by setting the
7634 stub_type to none. */
7637 _bfd_aarch64_erratum_843419_clear_stub (struct bfd_hash_entry
*gen_entry
,
7640 struct elf_aarch64_stub_hash_entry
*stub_entry
7641 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
7642 struct erratum_843419_branch_to_stub_clear_data
*data
7643 = (struct erratum_843419_branch_to_stub_clear_data
*) in_arg
;
7645 if (stub_entry
->target_section
!= data
->output_section
7646 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
7647 || stub_entry
->adrp_offset
!= data
->adrp_offset
)
7650 /* Change the stub type instead of removing the entry, removing from the hash
7651 table would be slower and we have already reserved the memory for the entry
7652 so there wouldn't be much gain. Changing the stub also keeps around a
7653 record of what was there before. */
7654 stub_entry
->stub_type
= aarch64_stub_none
;
7656 /* We're done and there could have been only one matching stub at that
7657 particular offset, so abort further traversal. */
7661 /* TLS Relaxations may relax an adrp sequence that matches the erratum 843419
7662 sequence. In this case the erratum no longer applies and we need to remove
7663 the entry from the pending stub generation. This clears matching adrp insn
7664 at ADRP_OFFSET in INPUT_SECTION in the stub table defined in GLOBALS. */
7667 clear_erratum_843419_entry (struct elf_aarch64_link_hash_table
*globals
,
7668 bfd_vma adrp_offset
, asection
*input_section
)
7670 if (globals
->fix_erratum_843419
& ERRAT_ADRP
)
7672 struct erratum_843419_branch_to_stub_clear_data data
;
7673 data
.adrp_offset
= adrp_offset
;
7674 data
.output_section
= input_section
;
7676 bfd_hash_traverse (&globals
->stub_hash_table
,
7677 _bfd_aarch64_erratum_843419_clear_stub
, &data
);
7681 #define BUILD_MOVZ(_reg, _imm) (movz_R0 \
7682 | ((((_imm) >> 16) & 0xffff) << 5) \
7684 #define BUILD_MOVK(_reg, _imm) (movk_R0 | (((_imm) & 0xffff) << 5) | (_reg))
7686 /* Handle TLS relaxations. Relaxing is possible for symbols that use
7687 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
7690 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
7691 is to then call final_link_relocate. Return other values in the
7694 static bfd_reloc_status_type
7695 elfNN_aarch64_tls_relax (bfd
*input_bfd
, struct bfd_link_info
*info
,
7696 asection
*input_section
,
7697 bfd_byte
*contents
, Elf_Internal_Rela
*rel
,
7698 struct elf_link_hash_entry
*h
, unsigned long r_symndx
)
7700 bfd_boolean is_local
= h
== NULL
;
7702 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
7704 bfd_vma sym_size
= 0;
7705 struct elf_aarch64_link_hash_table
*globals
= elf_aarch64_hash_table (info
);
7707 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
7715 Elf_Internal_Sym
*sym
;
7717 sym
= bfd_sym_from_r_symndx (&globals
->root
.sym_cache
, input_bfd
,
7719 BFD_ASSERT (sym
!= NULL
);
7720 sym_size
= sym
->st_size
;
7724 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
))
7726 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
7727 if (is_local
|| !bfd_link_pic (info
))
7729 /* GD->LE relaxation:
7730 nop => movz x1, objsize_hi16
7731 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var */
7732 bfd_putl32 (BUILD_MOVZ(1, sym_size
), contents
+ rel
->r_offset
- 4);
7733 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
7735 /* We have relaxed the adrp into a mov, we may have to clear any
7736 pending erratum fixes. */
7737 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
7738 return bfd_reloc_continue
;
7742 /* GD->IE relaxation: Not implemented. */
7743 return bfd_reloc_continue
;
7745 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
7746 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
7749 /* GD->LE relaxation:
7750 adrp x0, :tlsgd:var => movz R0, :tprel_g1:var
7752 adrp x0, :tlsdesc:var => movz R0, :tprel_g1:var
7754 Where R is x for LP64, and w for ILP32. */
7755 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
7756 /* We have relaxed the adrp into a mov, we may have to clear any
7757 pending erratum fixes. */
7758 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
7759 return bfd_reloc_continue
;
7763 /* GD->IE relaxation:
7764 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
7766 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
7768 return bfd_reloc_continue
;
7771 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
7775 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
7778 /* Tiny TLSDESC->LE relaxation:
7779 ldr x1, :tlsdesc:var => movz R0, #:tprel_g1:var
7780 adr x0, :tlsdesc:var => movk R0, #:tprel_g0_nc:var
7784 Where R is x for LP64, and w for ILP32. */
7785 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
7786 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
7788 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7789 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
7790 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7792 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
7793 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
+ 4);
7794 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
7795 return bfd_reloc_continue
;
7799 /* Tiny TLSDESC->IE relaxation:
7800 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
7801 adr x0, :tlsdesc:var => nop
7805 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
7806 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
7808 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7809 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7811 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
);
7812 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
7813 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
7814 return bfd_reloc_continue
;
7817 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
7820 /* Tiny GD->LE relaxation:
7821 adr x0, :tlsgd:var => mrs x1, tpidr_el0
7822 bl __tls_get_addr => add R0, R1, #:tprel_hi12:x, lsl #12
7823 nop => add R0, R0, #:tprel_lo12_nc:x
7825 Where R is x for LP64, and x for Ilp32. */
7827 /* First kill the tls_get_addr reloc on the bl instruction. */
7828 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
7830 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
7831 bfd_putl32 (add_R0_R1
, contents
+ rel
->r_offset
+ 4);
7832 bfd_putl32 (add_R0_R0
, contents
+ rel
->r_offset
+ 8);
7834 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7835 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
7836 rel
[1].r_offset
= rel
->r_offset
+ 8;
7838 /* Move the current relocation to the second instruction in
7841 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7842 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
7843 return bfd_reloc_continue
;
7847 /* Tiny GD->IE relaxation:
7848 adr x0, :tlsgd:var => ldr R0, :gottprel:var
7849 bl __tls_get_addr => mrs x1, tpidr_el0
7850 nop => add R0, R0, R1
7852 Where R is x for LP64, and w for Ilp32. */
7854 /* First kill the tls_get_addr reloc on the bl instruction. */
7855 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
7856 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7858 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
);
7859 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
7860 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 8);
7861 return bfd_reloc_continue
;
7865 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
7866 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSGD_MOVW_G0_NC
));
7867 BFD_ASSERT (rel
->r_offset
+ 12 == rel
[2].r_offset
);
7868 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (CALL26
));
7872 /* Large GD->LE relaxation:
7873 movz x0, #:tlsgd_g1:var => movz x0, #:tprel_g2:var, lsl #32
7874 movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
7875 add x0, gp, x0 => movk x0, #:tprel_g0_nc:var
7876 bl __tls_get_addr => mrs x1, tpidr_el0
7877 nop => add x0, x0, x1
7879 rel
[2].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7880 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
7881 rel
[2].r_offset
= rel
->r_offset
+ 8;
7883 bfd_putl32 (movz_hw_R0
, contents
+ rel
->r_offset
+ 0);
7884 bfd_putl32 (ldr_hw_R0
, contents
+ rel
->r_offset
+ 4);
7885 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
+ 8);
7886 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 12);
7887 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 16);
7891 /* Large GD->IE relaxation:
7892 movz x0, #:tlsgd_g1:var => movz x0, #:gottprel_g1:var, lsl #16
7893 movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
7894 add x0, gp, x0 => ldr x0, [gp, x0]
7895 bl __tls_get_addr => mrs x1, tpidr_el0
7896 nop => add x0, x0, x1
7898 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7899 bfd_putl32 (0xd2a80000, contents
+ rel
->r_offset
+ 0);
7900 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
+ 8);
7901 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 12);
7902 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 16);
7904 return bfd_reloc_continue
;
7906 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
7907 return bfd_reloc_continue
;
7910 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
7911 return bfd_reloc_continue
;
7913 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
7914 if (is_local
|| !bfd_link_pic (info
))
7916 /* GD->LE relaxation:
7917 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var */
7918 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
7919 return bfd_reloc_continue
;
7923 /* GD->IE relaxation: not implemented. */
7924 return bfd_reloc_continue
;
7926 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
7929 /* GD->LE relaxation:
7930 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
7932 Where R is x for lp64 mode, and w for ILP32 mode. */
7933 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
7934 return bfd_reloc_continue
;
7938 /* GD->IE relaxation:
7939 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr R0, [x0, #:gottprel_lo12:var]
7941 Where R is x for lp64 mode, and w for ILP32 mode. */
7942 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
7943 bfd_putl32 (ldr_R0_mask (insn
), contents
+ rel
->r_offset
);
7944 return bfd_reloc_continue
;
7947 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
7950 /* GD->LE relaxation
7951 add x0, #:tlsgd_lo12:var => movk R0, :tprel_g0_nc:var
7952 bl __tls_get_addr => mrs x1, tpidr_el0
7953 nop => add R0, R1, R0
7955 Where R is x for lp64 mode, and w for ILP32 mode. */
7957 /* First kill the tls_get_addr reloc on the bl instruction. */
7958 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
7959 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7961 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
7962 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
7963 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 8);
7964 return bfd_reloc_continue
;
7968 /* GD->IE relaxation
7969 ADD x0, #:tlsgd_lo12:var => ldr R0, [x0, #:gottprel_lo12:var]
7970 BL __tls_get_addr => mrs x1, tpidr_el0
7972 NOP => add R0, R1, R0
7974 Where R is x for lp64 mode, and w for ilp32 mode. */
7976 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
7978 /* Remove the relocation on the BL instruction. */
7979 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7981 /* We choose to fixup the BL and NOP instructions using the
7982 offset from the second relocation to allow flexibility in
7983 scheduling instructions between the ADD and BL. */
7984 bfd_putl32 (ldr_R0_x0
, contents
+ rel
->r_offset
);
7985 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
7986 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
[1].r_offset
+ 4);
7987 return bfd_reloc_continue
;
7990 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
7991 /* GD->LE relaxation:
7992 blr cd => add c0, c2, x0 */
7993 if (is_local
|| !bfd_link_pic (info
))
7995 bfd_putl32 (0xc2a06040, contents
+ rel
->r_offset
);
7996 return bfd_reloc_ok
;
8001 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
8002 /* GD->LE relaxation:
8003 ldr cd, [c0, #:tlsdesc_lo12:var] => movk x1, objsize_lo16 */
8004 if ((is_local
|| !bfd_link_pic (info
))
8005 && ELFNN_R_TYPE (rel
[1].r_info
) == MORELLO_R (TLSDESC_CALL
))
8007 bfd_putl32 (BUILD_MOVK(1, sym_size
), contents
+ rel
->r_offset
);
8008 return bfd_reloc_continue
;
8012 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
8013 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
8014 /* GD->IE/LE relaxation:
8015 add x0, x0, #:tlsdesc_lo12:var => nop
8019 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
8020 return bfd_reloc_ok
;
8022 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
8025 /* GD->LE relaxation:
8026 ldr xd, [gp, xn] => movk R0, #:tprel_g0_nc:var
8028 Where R is x for lp64 mode, and w for ILP32 mode. */
8029 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
8030 return bfd_reloc_continue
;
8034 /* GD->IE relaxation:
8035 ldr xd, [gp, xn] => ldr R0, [gp, xn]
8037 Where R is x for lp64 mode, and w for ILP32 mode. */
8038 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8039 bfd_putl32 (ldr_R0_mask (insn
), contents
+ rel
->r_offset
);
8040 return bfd_reloc_ok
;
8043 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
8044 /* GD->LE relaxation:
8045 movk xd, #:tlsdesc_off_g0_nc:var => movk R0, #:tprel_g1_nc:var, lsl #16
8047 movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
8049 Where R is x for lp64 mode, and w for ILP32 mode. */
8051 bfd_putl32 (ldr_hw_R0
, contents
+ rel
->r_offset
);
8052 return bfd_reloc_continue
;
8054 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
8057 /* GD->LE relaxation:
8058 movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
8060 Where R is x for lp64 mode, and w for ILP32 mode. */
8061 bfd_putl32 (movz_hw_R0
, contents
+ rel
->r_offset
);
8062 return bfd_reloc_continue
;
8066 /* GD->IE relaxation:
8067 movz xd, #:tlsdesc_off_g1:var => movz Rd, #:gottprel_g1:var, lsl #16
8069 Where R is x for lp64 mode, and w for ILP32 mode. */
8070 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8071 bfd_putl32 (movz_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
8072 return bfd_reloc_continue
;
8075 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
8076 /* IE->LE relaxation:
8077 adrp xd, :gottprel:var => movz Rd, :tprel_g1:var
8079 Where R is x for lp64 mode, and w for ILP32 mode. */
8082 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8083 bfd_putl32 (movz_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
8084 /* We have relaxed the adrp into a mov, we may have to clear any
8085 pending erratum fixes. */
8086 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
8088 return bfd_reloc_continue
;
8090 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
8091 /* IE->LE relaxation:
8092 ldr xd, [xm, #:gottprel_lo12:var] => movk Rd, :tprel_g0_nc:var
8094 Where R is x for lp64 mode, and w for ILP32 mode. */
8097 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8098 bfd_putl32 (movk_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
8100 return bfd_reloc_continue
;
8102 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
8103 /* LD->LE relaxation (tiny):
8104 adr x0, :tlsldm:x => mrs x0, tpidr_el0
8105 bl __tls_get_addr => add R0, R0, TCB_SIZE
8107 Where R is x for lp64 mode, and w for ilp32 mode. */
8110 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
8111 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
8112 /* No need of CALL26 relocation for tls_get_addr. */
8113 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
8114 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
+ 0);
8115 bfd_putl32 (add_R0_R0
| (TCB_SIZE
<< 10),
8116 contents
+ rel
->r_offset
+ 4);
8117 return bfd_reloc_ok
;
8119 return bfd_reloc_continue
;
8121 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
8122 /* LD->LE relaxation (small):
8123 adrp x0, :tlsldm:x => mrs x0, tpidr_el0
8127 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
);
8128 return bfd_reloc_ok
;
8130 return bfd_reloc_continue
;
8132 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
8133 /* LD->LE relaxation (small):
8134 add x0, #:tlsldm_lo12:x => add R0, R0, TCB_SIZE
8135 bl __tls_get_addr => nop
8137 Where R is x for lp64 mode, and w for ilp32 mode. */
8140 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
8141 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
8142 /* No need of CALL26 relocation for tls_get_addr. */
8143 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
8144 bfd_putl32 (add_R0_R0
| (TCB_SIZE
<< 10),
8145 contents
+ rel
->r_offset
+ 0);
8146 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
8147 return bfd_reloc_ok
;
8149 return bfd_reloc_continue
;
8152 return bfd_reloc_continue
;
8155 return bfd_reloc_ok
;
8158 /* Relocate an AArch64 ELF section. */
8161 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
8162 struct bfd_link_info
*info
,
8164 asection
*input_section
,
8166 Elf_Internal_Rela
*relocs
,
8167 Elf_Internal_Sym
*local_syms
,
8168 asection
**local_sections
)
8170 Elf_Internal_Shdr
*symtab_hdr
;
8171 struct elf_link_hash_entry
**sym_hashes
;
8172 Elf_Internal_Rela
*rel
;
8173 Elf_Internal_Rela
*relend
;
8175 struct elf_aarch64_link_hash_table
*globals
;
8176 bfd_boolean save_addend
= FALSE
;
8179 globals
= elf_aarch64_hash_table (info
);
8181 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
8182 sym_hashes
= elf_sym_hashes (input_bfd
);
8185 relend
= relocs
+ input_section
->reloc_count
;
8186 for (; rel
< relend
; rel
++)
8188 unsigned int r_type
;
8189 bfd_reloc_code_real_type bfd_r_type
;
8190 bfd_reloc_code_real_type relaxed_bfd_r_type
;
8191 reloc_howto_type
*howto
;
8192 unsigned long r_symndx
;
8193 Elf_Internal_Sym
*sym
;
8195 struct elf_link_hash_entry
*h
;
8197 bfd_reloc_status_type r
;
8200 bfd_boolean unresolved_reloc
= FALSE
;
8201 char *error_message
= NULL
;
8203 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
8204 r_type
= ELFNN_R_TYPE (rel
->r_info
);
8206 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (input_bfd
, r_type
);
8207 howto
= bfd_reloc
.howto
;
8210 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
8212 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
8218 if (r_symndx
< symtab_hdr
->sh_info
)
8220 sym
= local_syms
+ r_symndx
;
8221 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
8222 sec
= local_sections
[r_symndx
];
8224 /* An object file might have a reference to a local
8225 undefined symbol. This is a daft object file, but we
8226 should at least do something about it. */
8227 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
8228 && bfd_is_und_section (sec
)
8229 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
8230 (*info
->callbacks
->undefined_symbol
)
8231 (info
, bfd_elf_string_from_elf_section
8232 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
8233 input_bfd
, input_section
, rel
->r_offset
, TRUE
);
8235 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
8237 /* Relocate against local STT_GNU_IFUNC symbol. */
8238 if (!bfd_link_relocatable (info
)
8239 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
8241 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
8246 /* Set STT_GNU_IFUNC symbol value. */
8247 h
->root
.u
.def
.value
= sym
->st_value
;
8248 h
->root
.u
.def
.section
= sec
;
8253 bfd_boolean warned
, ignored
;
8255 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
8256 r_symndx
, symtab_hdr
, sym_hashes
,
8258 unresolved_reloc
, warned
, ignored
);
8263 if (sec
!= NULL
&& discarded_section (sec
))
8264 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
8265 rel
, 1, relend
, howto
, 0, contents
);
8267 if (bfd_link_relocatable (info
))
8271 name
= h
->root
.root
.string
;
8274 name
= (bfd_elf_string_from_elf_section
8275 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
8276 if (name
== NULL
|| *name
== '\0')
8277 name
= bfd_section_name (sec
);
8281 && r_type
!= R_AARCH64_NONE
8282 && r_type
!= R_AARCH64_NULL
8284 || h
->root
.type
== bfd_link_hash_defined
8285 || h
->root
.type
== bfd_link_hash_defweak
)
8286 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
8289 ((sym_type
== STT_TLS
8290 /* xgettext:c-format */
8291 ? _("%pB(%pA+%#" PRIx64
"): %s used with TLS symbol %s")
8292 /* xgettext:c-format */
8293 : _("%pB(%pA+%#" PRIx64
"): %s used with non-TLS symbol %s")),
8295 input_section
, (uint64_t) rel
->r_offset
, howto
->name
, name
);
8300 && IS_AARCH64_TLS_RELOC (bfd_r_type
)
8301 && h
->root
.type
== bfd_link_hash_undefweak
)
8302 /* We have already warned about these in aarch64_check_relocs,
8303 so just skip over them. */
8306 /* We relax only if we can see that there can be a valid transition
8307 from a reloc type to another.
8308 We call elfNN_aarch64_final_link_relocate unless we're completely
8309 done, i.e., the relaxation produced the final output we want. */
8311 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, rel
,
8313 if (relaxed_bfd_r_type
!= bfd_r_type
)
8315 bfd_r_type
= relaxed_bfd_r_type
;
8316 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
8317 BFD_ASSERT (howto
!= NULL
);
8318 r_type
= howto
->type
;
8319 r
= elfNN_aarch64_tls_relax (input_bfd
, info
, input_section
,
8320 contents
, rel
, h
, r_symndx
);
8321 unresolved_reloc
= 0;
8324 r
= bfd_reloc_continue
;
8326 /* There may be multiple consecutive relocations for the
8327 same offset. In that case we are supposed to treat the
8328 output of each relocation as the addend for the next. */
8329 if (rel
+ 1 < relend
8330 && rel
->r_offset
== rel
[1].r_offset
8331 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
8332 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
8335 save_addend
= FALSE
;
8337 if (r
== bfd_reloc_continue
)
8338 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
8339 input_section
, contents
, rel
,
8340 relocation
, info
, sec
,
8341 h
, &unresolved_reloc
,
8342 save_addend
, &addend
, sym
);
8344 bfd_boolean c64_rtype
= FALSE
;
8346 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
))
8348 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
8349 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
8350 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
8351 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
8352 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
8353 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
8354 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
8355 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
8356 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
8358 bfd_boolean need_relocs
= FALSE
;
8363 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
8364 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8367 (!bfd_link_executable (info
) || indx
!= 0) &&
8369 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8370 || h
->root
.type
!= bfd_link_hash_undefweak
);
8372 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
8376 Elf_Internal_Rela rela
;
8377 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
8379 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
8380 globals
->root
.sgot
->output_offset
+ off
;
8383 loc
= globals
->root
.srelgot
->contents
;
8384 loc
+= globals
->root
.srelgot
->reloc_count
++
8385 * RELOC_SIZE (htab
);
8386 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8388 bfd_reloc_code_real_type real_type
=
8389 elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
8391 if (real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
8392 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
8393 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
)
8395 /* For local dynamic, don't generate DTPREL in any case.
8396 Initialize the DTPREL slot into zero, so we get module
8397 base address when invoke runtime TLS resolver. */
8398 bfd_put_NN (output_bfd
, 0,
8399 globals
->root
.sgot
->contents
+ off
8400 + GOT_ENTRY_SIZE (globals
));
8404 bfd_put_NN (output_bfd
,
8405 relocation
- dtpoff_base (info
),
8406 globals
->root
.sgot
->contents
+ off
8407 + GOT_ENTRY_SIZE (globals
));
8411 /* This TLS symbol is global. We emit a
8412 relocation to fixup the tls offset at load
8415 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
8418 (globals
->root
.sgot
->output_section
->vma
8419 + globals
->root
.sgot
->output_offset
+ off
8420 + GOT_ENTRY_SIZE (globals
));
8422 loc
= globals
->root
.srelgot
->contents
;
8423 loc
+= globals
->root
.srelgot
->reloc_count
++
8424 * RELOC_SIZE (globals
);
8425 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8426 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8427 globals
->root
.sgot
->contents
+ off
8428 + GOT_ENTRY_SIZE (globals
));
8433 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
8434 globals
->root
.sgot
->contents
+ off
);
8435 bfd_put_NN (output_bfd
,
8436 relocation
- dtpoff_base (info
),
8437 globals
->root
.sgot
->contents
+ off
8438 + GOT_ENTRY_SIZE (globals
));
8441 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
8445 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
8446 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
8447 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
8448 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
8449 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
8450 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
8452 bfd_boolean need_relocs
= FALSE
;
8457 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
8459 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8462 (!bfd_link_executable (info
) || indx
!= 0) &&
8464 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8465 || h
->root
.type
!= bfd_link_hash_undefweak
);
8467 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
8471 Elf_Internal_Rela rela
;
8474 rela
.r_addend
= relocation
- dtpoff_base (info
);
8478 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
8479 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
8480 globals
->root
.sgot
->output_offset
+ off
;
8482 loc
= globals
->root
.srelgot
->contents
;
8483 loc
+= globals
->root
.srelgot
->reloc_count
++
8484 * RELOC_SIZE (htab
);
8486 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8488 bfd_put_NN (output_bfd
, rela
.r_addend
,
8489 globals
->root
.sgot
->contents
+ off
);
8492 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
8493 globals
->root
.sgot
->contents
+ off
);
8495 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
8499 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
8500 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
8504 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
8505 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
8506 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
8507 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
8508 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
8509 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
8510 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
8511 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
8513 bfd_boolean need_relocs
= FALSE
;
8514 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8515 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
8517 need_relocs
= (h
== NULL
8518 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8519 || h
->root
.type
!= bfd_link_hash_undefweak
);
8521 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
8522 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
8527 Elf_Internal_Rela rela
;
8529 rela
.r_info
= ELFNN_R_INFO (indx
,
8530 (c64_rtype
? MORELLO_R (TLSDESC
)
8531 : AARCH64_R (TLSDESC
)));
8534 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
8535 + globals
->root
.sgotplt
->output_offset
8536 + off
+ globals
->sgotplt_jump_table_size
);
8539 rela
.r_addend
= relocation
- dtpoff_base (info
);
8541 /* Allocate the next available slot in the PLT reloc
8542 section to hold our R_AARCH64_TLSDESC, the next
8543 available slot is determined from reloc_count,
8544 which we step. But note, reloc_count was
8545 artifically moved down while allocating slots for
8546 real PLT relocs such that all of the PLT relocs
8547 will fit above the initial reloc_count and the
8548 extra stuff will fit below. */
8549 loc
= globals
->root
.srelplt
->contents
;
8550 loc
+= globals
->root
.srelplt
->reloc_count
++
8551 * RELOC_SIZE (globals
);
8553 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8555 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8556 globals
->root
.sgotplt
->contents
+ off
+
8557 globals
->sgotplt_jump_table_size
);
8558 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8559 globals
->root
.sgotplt
->contents
+ off
+
8560 globals
->sgotplt_jump_table_size
+
8561 GOT_ENTRY_SIZE (globals
));
8564 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
8571 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
8572 because such sections are not SEC_ALLOC and thus ld.so will
8573 not process them. */
8574 if (unresolved_reloc
8575 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
8577 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
8578 +rel
->r_offset
) != (bfd_vma
) - 1)
8581 /* xgettext:c-format */
8582 (_("%pB(%pA+%#" PRIx64
"): "
8583 "unresolvable %s relocation against symbol `%s'"),
8584 input_bfd
, input_section
, (uint64_t) rel
->r_offset
, howto
->name
,
8585 h
->root
.root
.string
);
8589 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
8591 bfd_reloc_code_real_type real_r_type
8592 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
8596 case bfd_reloc_overflow
:
8597 (*info
->callbacks
->reloc_overflow
)
8598 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
8599 input_bfd
, input_section
, rel
->r_offset
);
8600 if (real_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
8601 || real_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
8603 (*info
->callbacks
->warning
)
8605 _("too many GOT entries for -fpic, "
8606 "please recompile with -fPIC"),
8607 name
, input_bfd
, input_section
, rel
->r_offset
);
8610 /* Overflow can occur when a variable is referenced with a type
8611 that has a larger alignment than the type with which it was
8613 file1.c: extern int foo; int a (void) { return foo; }
8614 file2.c: char bar, foo, baz;
8615 If the variable is placed into a data section at an offset
8616 that is incompatible with the larger alignment requirement
8617 overflow will occur. (Strictly speaking this is not overflow
8618 but rather an alignment problem, but the bfd_reloc_ error
8619 enum does not have a value to cover that situation).
8621 Try to catch this situation here and provide a more helpful
8622 error message to the user. */
8623 if (addend
& (((bfd_vma
) 1 << howto
->rightshift
) - 1)
8624 /* FIXME: Are we testing all of the appropriate reloc
8626 && (real_r_type
== BFD_RELOC_AARCH64_LD_LO19_PCREL
8627 || real_r_type
== BFD_RELOC_AARCH64_LDST16_LO12
8628 || real_r_type
== BFD_RELOC_AARCH64_LDST32_LO12
8629 || real_r_type
== BFD_RELOC_AARCH64_LDST64_LO12
8630 || real_r_type
== BFD_RELOC_AARCH64_LDST128_LO12
))
8632 info
->callbacks
->warning
8633 (info
, _("one possible cause of this error is that the \
8634 symbol is being referenced in the indicated code as if it had a larger \
8635 alignment than was declared where it was defined"),
8636 name
, input_bfd
, input_section
, rel
->r_offset
);
8639 if (real_r_type
== BFD_RELOC_MORELLO_CAPINIT
)
8640 info
->callbacks
->warning
8641 (info
, _("relocation offset must be capability aligned"),
8642 name
, input_bfd
, input_section
, rel
->r_offset
);
8645 case bfd_reloc_undefined
:
8646 (*info
->callbacks
->undefined_symbol
)
8647 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
);
8650 case bfd_reloc_outofrange
:
8651 error_message
= _("out of range");
8654 case bfd_reloc_notsupported
:
8655 error_message
= _("unsupported relocation");
8658 case bfd_reloc_dangerous
:
8659 /* error_message should already be set. */
8663 error_message
= _("unknown error");
8667 BFD_ASSERT (error_message
!= NULL
);
8668 (*info
->callbacks
->reloc_dangerous
)
8669 (info
, error_message
, input_bfd
, input_section
, rel
->r_offset
);
8681 /* Set the right machine number. */
8684 elfNN_aarch64_object_p (bfd
*abfd
)
8687 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
8689 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
8694 /* Function to keep AArch64 specific flags in the ELF header. */
8697 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
8699 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
8704 elf_elfheader (abfd
)->e_flags
= flags
;
8705 elf_flags_init (abfd
) = TRUE
;
8711 /* Merge backend specific data from an object file to the output
8712 object file when linking. */
8715 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
8717 bfd
*obfd
= info
->output_bfd
;
8720 bfd_boolean flags_compatible
= FALSE
;
8723 /* Check if we have the same endianess. */
8724 if (!_bfd_generic_verify_endian_match (ibfd
, info
))
8727 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
8730 /* The input BFD must have had its flags initialised. */
8731 /* The following seems bogus to me -- The flags are initialized in
8732 the assembler but I don't think an elf_flags_init field is
8733 written into the object. */
8734 /* BFD_ASSERT (elf_flags_init (ibfd)); */
8736 in_flags
= elf_elfheader (ibfd
)->e_flags
;
8737 out_flags
= elf_elfheader (obfd
)->e_flags
;
8739 if (!elf_flags_init (obfd
))
8741 elf_flags_init (obfd
) = TRUE
;
8743 /* If the input is the default architecture and had the default
8744 flags then do not bother setting the flags for the output
8745 architecture, instead allow future merges to do this. If no
8746 future merges ever set these flags then they will retain their
8747 uninitialised values, which surprise surprise, correspond
8748 to the default values. */
8749 if (bfd_get_arch_info (ibfd
)->the_default
8750 && elf_elfheader (ibfd
)->e_flags
== 0)
8753 elf_elfheader (obfd
)->e_flags
= in_flags
;
8755 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
8756 && bfd_get_arch_info (obfd
)->the_default
)
8757 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
8758 bfd_get_mach (ibfd
));
8763 /* Identical flags must be compatible. */
8764 if (in_flags
== out_flags
)
8767 /* Check to see if the input BFD actually contains any sections. If
8768 not, its flags may not have been initialised either, but it
8769 cannot actually cause any incompatiblity. Do not short-circuit
8770 dynamic objects; their section list may be emptied by
8771 elf_link_add_object_symbols.
8773 Also check to see if there are no code sections in the input.
8774 In this case there is no need to check for code specific flags.
8775 XXX - do we need to worry about floating-point format compatability
8778 We definitely need to check for data sections if one set of flags is
8779 targetting the PURECAP abi and another is not. Pointers being
8780 capabilities in data sections can not be glossed over. */
8781 if (!(ibfd
->flags
& DYNAMIC
))
8783 bfd_boolean null_input_bfd
= TRUE
;
8784 bfd_boolean only_data_sections
8785 = !(in_flags
& EF_AARCH64_CHERI_PURECAP
8786 || out_flags
& EF_AARCH64_CHERI_PURECAP
);
8788 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
8790 if ((bfd_section_flags (sec
)
8791 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
8792 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
8793 only_data_sections
= FALSE
;
8795 null_input_bfd
= FALSE
;
8799 if (null_input_bfd
|| only_data_sections
)
8803 return flags_compatible
;
8806 /* Display the flags field. */
8809 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
8811 FILE *file
= (FILE *) ptr
;
8812 unsigned long flags
;
8814 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
8816 /* Print normal ELF private data. */
8817 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
8819 flags
= elf_elfheader (abfd
)->e_flags
;
8820 /* Ignore init flag - it may not be set, despite the flags field
8821 containing valid data. */
8823 /* xgettext:c-format */
8824 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
8827 fprintf (file
, _("<Unrecognised flag bits set>"));
8834 /* Return true if we need copy relocation against EH. */
8837 need_copy_relocation_p (struct elf_aarch64_link_hash_entry
*eh
)
8839 struct elf_dyn_relocs
*p
;
8842 for (p
= eh
->root
.dyn_relocs
; p
!= NULL
; p
= p
->next
)
8844 /* If there is any pc-relative reference, we need to keep copy relocation
8845 to avoid propagating the relocation into runtime that current glibc
8846 does not support. */
8850 s
= p
->sec
->output_section
;
8851 /* Need copy relocation if it's against read-only section. */
8852 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
8859 /* Adjust a symbol defined by a dynamic object and referenced by a
8860 regular object. The current definition is in some section of the
8861 dynamic object, but we're not including those sections. We have to
8862 change the definition to something the rest of the link can
8866 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
8867 struct elf_link_hash_entry
*h
)
8869 struct elf_aarch64_link_hash_table
*htab
;
8872 /* If this is a function, put it in the procedure linkage table. We
8873 will fill in the contents of the procedure linkage table later,
8874 when we know the address of the .got section. */
8875 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
8877 if (h
->plt
.refcount
<= 0
8878 || (h
->type
!= STT_GNU_IFUNC
8879 && (SYMBOL_CALLS_LOCAL (info
, h
)
8880 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
8881 && h
->root
.type
== bfd_link_hash_undefweak
))))
8883 /* This case can occur if we saw a CALL26 reloc in
8884 an input file, but the symbol wasn't referred to
8885 by a dynamic object or all references were
8886 garbage collected. In which case we can end up
8888 h
->plt
.offset
= (bfd_vma
) - 1;
8895 /* Otherwise, reset to -1. */
8896 h
->plt
.offset
= (bfd_vma
) - 1;
8899 /* If this is a weak symbol, and there is a real definition, the
8900 processor independent code will have arranged for us to see the
8901 real definition first, and we can just use the same value. */
8902 if (h
->is_weakalias
)
8904 struct elf_link_hash_entry
*def
= weakdef (h
);
8905 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
8906 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
8907 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
8908 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
8909 h
->non_got_ref
= def
->non_got_ref
;
8913 /* If we are creating a shared library, we must presume that the
8914 only references to the symbol are via the global offset table.
8915 For such cases we need not do anything here; the relocations will
8916 be handled correctly by relocate_section. */
8917 if (bfd_link_pic (info
))
8920 /* If there are no references to this symbol that do not use the
8921 GOT, we don't need to generate a copy reloc. */
8922 if (!h
->non_got_ref
)
8925 /* If -z nocopyreloc was given, we won't generate them either. */
8926 if (info
->nocopyreloc
)
8932 if (ELIMINATE_COPY_RELOCS
)
8934 struct elf_aarch64_link_hash_entry
*eh
;
8935 /* If we don't find any dynamic relocs in read-only sections, then
8936 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
8937 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
8938 if (!need_copy_relocation_p (eh
))
8945 /* We must allocate the symbol in our .dynbss section, which will
8946 become part of the .bss section of the executable. There will be
8947 an entry for this symbol in the .dynsym section. The dynamic
8948 object will contain position independent code, so all references
8949 from the dynamic object to this symbol will go through the global
8950 offset table. The dynamic linker will use the .dynsym entry to
8951 determine the address it must put in the global offset table, so
8952 both the dynamic object and the regular object will refer to the
8953 same memory location for the variable. */
8955 htab
= elf_aarch64_hash_table (info
);
8957 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
8958 to copy the initial value out of the dynamic object and into the
8959 runtime process image. */
8960 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
8962 s
= htab
->root
.sdynrelro
;
8963 srel
= htab
->root
.sreldynrelro
;
8967 s
= htab
->root
.sdynbss
;
8968 srel
= htab
->root
.srelbss
;
8970 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
8972 srel
->size
+= RELOC_SIZE (htab
);
8976 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
8981 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
8983 struct elf_aarch64_local_symbol
*locals
;
8984 locals
= elf_aarch64_locals (abfd
);
8987 locals
= (struct elf_aarch64_local_symbol
*)
8988 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
8991 elf_aarch64_locals (abfd
) = locals
;
8996 /* Initialise the .got section to hold the global offset table. */
8999 aarch64_elf_init_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
9001 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
9003 struct elf_aarch64_link_hash_table
*globals
= elf_aarch64_hash_table (info
);
9004 unsigned int align
= bed
->s
->log_file_align
+ globals
->c64_rel
;
9006 if (globals
->root
.sgot
!= NULL
)
9008 bfd_set_section_alignment (globals
->root
.srelgot
,
9009 bed
->s
->log_file_align
);
9010 bfd_set_section_alignment (globals
->root
.sgot
, align
);
9011 globals
->root
.sgot
->size
+= GOT_ENTRY_SIZE (globals
);
9014 /* Track capability initialisation for static non-PIE binaries. */
9015 if (bfd_link_executable (info
) && !bfd_link_pic (info
)
9016 && globals
->srelcaps
== NULL
)
9017 globals
->srelcaps
= globals
->root
.srelgot
;
9019 if (globals
->root
.igotplt
!= NULL
)
9020 bfd_set_section_alignment (globals
->root
.igotplt
, align
);
9022 s
= globals
->root
.sgot
;
9024 if (globals
->root
.sgotplt
!= NULL
)
9026 bfd_set_section_alignment (globals
->root
.sgotplt
, align
);
9027 s
= globals
->root
.sgotplt
;
9030 /* The first bit of the global offset table is the header. */
9032 s
->size
+= bed
->got_header_size (info
);
9035 /* Create the .got section to hold the global offset table. */
9038 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
9040 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
9043 struct elf_link_hash_entry
*h
;
9044 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
9046 /* This function may be called more than once. */
9047 if (htab
->sgot
!= NULL
)
9050 flags
= bed
->dynamic_sec_flags
;
9052 s
= bfd_make_section_anyway_with_flags (abfd
,
9053 (bed
->rela_plts_and_copies_p
9054 ? ".rela.got" : ".rel.got"),
9055 (bed
->dynamic_sec_flags
9061 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
9066 if (bed
->want_got_sym
)
9068 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
9069 (or .got.plt) section. We don't do this in the linker script
9070 because we don't want to define the symbol if we are not creating
9071 a global offset table. */
9072 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
9073 "_GLOBAL_OFFSET_TABLE_");
9074 elf_hash_table (info
)->hgot
= h
;
9079 if (bed
->want_got_plt
)
9081 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
9090 /* Look through the relocs for a section during the first phase. */
9093 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
9094 asection
*sec
, const Elf_Internal_Rela
*relocs
)
9096 Elf_Internal_Shdr
*symtab_hdr
;
9097 struct elf_link_hash_entry
**sym_hashes
;
9098 const Elf_Internal_Rela
*rel
;
9099 const Elf_Internal_Rela
*rel_end
;
9102 struct elf_aarch64_link_hash_table
*htab
;
9104 if (bfd_link_relocatable (info
))
9107 BFD_ASSERT (is_aarch64_elf (abfd
));
9109 htab
= elf_aarch64_hash_table (info
);
9112 symtab_hdr
= &elf_symtab_hdr (abfd
);
9113 sym_hashes
= elf_sym_hashes (abfd
);
9115 bfd_elfNN_aarch64_init_maps (abfd
, info
);
9117 rel_end
= relocs
+ sec
->reloc_count
;
9118 for (rel
= relocs
; rel
< rel_end
; rel
++)
9120 struct elf_link_hash_entry
*h
;
9121 unsigned int r_symndx
, r_type
;
9122 bfd_reloc_code_real_type bfd_r_type
;
9123 Elf_Internal_Sym
*isym
;
9125 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
9126 r_type
= ELFNN_R_TYPE (rel
->r_info
);
9127 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_type (abfd
, r_type
);
9129 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
9131 /* xgettext:c-format */
9132 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
9136 if (r_symndx
< symtab_hdr
->sh_info
)
9138 /* A local symbol. */
9139 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
9144 /* Check relocation against local STT_GNU_IFUNC symbol. */
9145 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
9147 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
9152 /* Fake a STT_GNU_IFUNC symbol. */
9153 h
->type
= STT_GNU_IFUNC
;
9156 h
->forced_local
= 1;
9157 h
->root
.type
= bfd_link_hash_defined
;
9164 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
9165 while (h
->root
.type
== bfd_link_hash_indirect
9166 || h
->root
.type
== bfd_link_hash_warning
)
9167 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
9170 /* Ignore TLS relocations against weak undef symbols and warn about them.
9171 The behaviour of weak TLS variables is not well defined. Since making
9172 these well behaved is not a priority for Morello, we simply ignore
9173 TLS relocations against such symbols here to avoid the linker crashing
9174 on these and to enable making progress in other areas. */
9177 && IS_AARCH64_TLS_RELOC (bfd_r_type
)
9178 && h
->root
.type
== bfd_link_hash_undefweak
)
9180 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9181 _bfd_error_handler (_("%pB(%pA+%#" PRIx64
"): ignoring TLS relocation "
9182 "%s against undef weak symbol %s"),
9184 (uint64_t) rel
->r_offset
,
9185 elfNN_aarch64_howto_table
[howto_index
].name
,
9186 h
->root
.root
.string
);
9190 /* Could be done earlier, if h were already available. */
9191 bfd_r_type
= aarch64_tls_transition (abfd
, info
, rel
, h
, r_symndx
);
9195 /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
9196 This shows up in particular in an R_AARCH64_PREL64 in large model
9197 when calculating the pc-relative address to .got section which is
9198 used to initialize the gp register. */
9199 if (h
->root
.root
.string
9200 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
9202 if (htab
->root
.dynobj
== NULL
)
9203 htab
->root
.dynobj
= abfd
;
9205 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
9208 BFD_ASSERT (h
== htab
->root
.hgot
);
9211 /* Create the ifunc sections for static executables. If we
9212 never see an indirect function symbol nor we are building
9213 a static executable, those sections will be empty and
9214 won't appear in output. */
9220 case BFD_RELOC_MORELLO_CALL26
:
9221 case BFD_RELOC_MORELLO_JUMP26
:
9222 /* For dynamic symbols record caller information so that we can
9223 decide what kind of PLT stubs to emit. */
9225 elf_aarch64_hash_entry (h
)->got_type
= GOT_CAP
;
9228 case BFD_RELOC_AARCH64_ADD_LO12
:
9229 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
9230 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
9231 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
9232 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
9233 case BFD_RELOC_AARCH64_CALL26
:
9234 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
9235 case BFD_RELOC_AARCH64_JUMP26
:
9236 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
9237 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
9238 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
9239 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
9240 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
9241 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
9242 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
9243 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
9244 case BFD_RELOC_AARCH64_NN
:
9245 if (htab
->root
.dynobj
== NULL
)
9246 htab
->root
.dynobj
= abfd
;
9247 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
9252 /* It is referenced by a non-shared object. */
9258 case BFD_RELOC_AARCH64_16
:
9260 case BFD_RELOC_AARCH64_32
:
9262 if (bfd_link_pic (info
) && (sec
->flags
& SEC_ALLOC
) != 0)
9265 /* This is an absolute symbol. It represents a value instead
9267 && (bfd_is_abs_symbol (&h
->root
)
9268 /* This is an undefined symbol. */
9269 || h
->root
.type
== bfd_link_hash_undefined
))
9272 /* For local symbols, defined global symbols in a non-ABS section,
9273 it is assumed that the value is an address. */
9274 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9276 /* xgettext:c-format */
9277 (_("%pB: relocation %s against `%s' can not be used when making "
9279 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
9280 (h
) ? h
->root
.root
.string
: "a local symbol");
9281 bfd_set_error (bfd_error_bad_value
);
9287 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
9288 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
9289 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
9290 case BFD_RELOC_AARCH64_MOVW_G3
:
9291 if (bfd_link_pic (info
))
9293 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9295 /* xgettext:c-format */
9296 (_("%pB: relocation %s against `%s' can not be used when making "
9297 "a shared object; recompile with -fPIC"),
9298 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
9299 (h
) ? h
->root
.root
.string
: "a local symbol");
9300 bfd_set_error (bfd_error_bad_value
);
9305 case BFD_RELOC_AARCH64_16_PCREL
:
9306 case BFD_RELOC_AARCH64_32_PCREL
:
9307 case BFD_RELOC_AARCH64_64_PCREL
:
9308 case BFD_RELOC_AARCH64_ADD_LO12
:
9309 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
9310 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
9311 case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL
:
9312 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
9313 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
9314 case BFD_RELOC_AARCH64_LDST128_LO12
:
9315 case BFD_RELOC_AARCH64_LDST16_LO12
:
9316 case BFD_RELOC_AARCH64_LDST32_LO12
:
9317 case BFD_RELOC_AARCH64_LDST64_LO12
:
9318 case BFD_RELOC_AARCH64_LDST8_LO12
:
9319 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
9320 case BFD_RELOC_MORELLO_LD_LO17_PCREL
:
9321 if (h
== NULL
|| bfd_link_pic (info
))
9325 case BFD_RELOC_AARCH64_NN
:
9327 /* We don't need to handle relocs into sections not going into
9328 the "real" output. */
9329 if ((sec
->flags
& SEC_ALLOC
) == 0)
9334 if (!bfd_link_pic (info
))
9337 h
->plt
.refcount
+= 1;
9338 h
->pointer_equality_needed
= 1;
9341 /* No need to do anything if we're not creating a shared
9343 if (!(bfd_link_pic (info
)
9344 /* If on the other hand, we are creating an executable, we
9345 may need to keep relocations for symbols satisfied by a
9346 dynamic library if we manage to avoid copy relocs for the
9349 NOTE: Currently, there is no support of copy relocs
9350 elimination on pc-relative relocation types, because there is
9351 no dynamic relocation support for them in glibc. We still
9352 record the dynamic symbol reference for them. This is
9353 because one symbol may be referenced by both absolute
9354 relocation (for example, BFD_RELOC_AARCH64_NN) and
9355 pc-relative relocation. We need full symbol reference
9356 information to make correct decision later in
9357 elfNN_aarch64_adjust_dynamic_symbol. */
9358 || (ELIMINATE_COPY_RELOCS
9359 && !bfd_link_pic (info
)
9361 && (h
->root
.type
== bfd_link_hash_defweak
9362 || !h
->def_regular
))))
9366 struct elf_dyn_relocs
*p
;
9367 struct elf_dyn_relocs
**head
;
9368 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9370 /* We must copy these reloc types into the output file.
9371 Create a reloc section in dynobj and make room for
9375 if (htab
->root
.dynobj
== NULL
)
9376 htab
->root
.dynobj
= abfd
;
9378 sreloc
= _bfd_elf_make_dynamic_reloc_section
9379 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ TRUE
);
9385 /* If this is a global symbol, we count the number of
9386 relocations we need for this symbol. */
9389 head
= &h
->dyn_relocs
;
9393 /* Track dynamic relocs needed for local syms too.
9394 We really need local syms available to do this
9400 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
9405 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
9409 /* Beware of type punned pointers vs strict aliasing
9411 vpp
= &(elf_section_data (s
)->local_dynrel
);
9412 head
= (struct elf_dyn_relocs
**) vpp
;
9416 if (p
== NULL
|| p
->sec
!= sec
)
9418 size_t amt
= sizeof *p
;
9419 p
= ((struct elf_dyn_relocs
*)
9420 bfd_zalloc (htab
->root
.dynobj
, amt
));
9430 if (elfNN_aarch64_howto_table
[howto_index
].pc_relative
)
9435 /* RR: We probably want to keep a consistency check that
9436 there are no dangling GOT_PAGE relocs. */
9437 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
9438 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
9439 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
9440 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
9444 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
9445 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
9446 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
9447 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
9448 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
9449 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
9450 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
9451 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
9452 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
9453 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
9454 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
9455 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
9456 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
9457 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
9458 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
9459 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
9460 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
9461 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
9462 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
9463 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
9464 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
9465 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
9466 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
9467 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
9468 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
9469 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
9470 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
9471 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
9472 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
9473 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
9474 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
9477 unsigned old_got_type
;
9479 got_type
= aarch64_reloc_got_type (bfd_r_type
);
9483 h
->got
.refcount
+= 1;
9484 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
9488 struct elf_aarch64_local_symbol
*locals
;
9490 if (!elfNN_aarch64_allocate_local_symbols
9491 (abfd
, symtab_hdr
->sh_info
))
9494 locals
= elf_aarch64_locals (abfd
);
9495 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
9496 locals
[r_symndx
].got_refcount
+= 1;
9497 old_got_type
= locals
[r_symndx
].got_type
;
9500 /* If a variable is accessed with both general dynamic TLS
9501 methods, two slots may be created. */
9502 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
9503 got_type
|= old_got_type
;
9505 /* We will already have issued an error message if there
9506 is a TLS/non-TLS mismatch, based on the symbol type.
9507 So just combine any TLS types needed. */
9508 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
9509 && got_type
!= GOT_NORMAL
&& old_got_type
!= GOT_CAP
9510 && got_type
!= GOT_CAP
)
9511 got_type
|= old_got_type
;
9513 /* If the symbol is accessed by both IE and GD methods, we
9514 are able to relax. Turn off the GD flag, without
9515 messing up with any other kind of TLS types that may be
9517 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
9518 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
9520 /* Prefer the capability reference. */
9521 if ((old_got_type
& GOT_CAP
) && (got_type
& GOT_NORMAL
))
9523 got_type
&= ~GOT_NORMAL
;
9524 got_type
|= GOT_CAP
;
9527 if (old_got_type
!= got_type
)
9530 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
9533 struct elf_aarch64_local_symbol
*locals
;
9534 locals
= elf_aarch64_locals (abfd
);
9535 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
9536 locals
[r_symndx
].got_type
= got_type
;
9540 if (htab
->root
.dynobj
== NULL
)
9541 htab
->root
.dynobj
= abfd
;
9542 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
9547 case BFD_RELOC_MORELLO_CALL26
:
9548 case BFD_RELOC_MORELLO_JUMP26
:
9551 elf_aarch64_hash_entry (h
)->got_type
= GOT_CAP
;
9554 case BFD_RELOC_AARCH64_CALL26
:
9555 case BFD_RELOC_AARCH64_JUMP26
:
9558 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
, abfd
,
9563 asection
*s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
9568 if (c64_value_p (s
, isym
->st_value
))
9569 isym
->st_target_internal
|= ST_BRANCH_TO_C64
;
9571 /* If this is a local symbol then we resolve it
9572 directly without creating a PLT entry. */
9576 if (h
->root
.type
== bfd_link_hash_defined
9577 || h
->root
.type
== bfd_link_hash_defweak
)
9579 asection
*sym_sec
= h
->root
.u
.def
.section
;
9580 bfd_vma sym_value
= h
->root
.u
.def
.value
;
9582 if (sym_sec
!= NULL
&& c64_value_p (sym_sec
, sym_value
))
9583 h
->target_internal
|= ST_BRANCH_TO_C64
;
9587 if (h
->plt
.refcount
<= 0)
9588 h
->plt
.refcount
= 1;
9590 h
->plt
.refcount
+= 1;
9593 case BFD_RELOC_MORELLO_CAPINIT
:
9594 if (htab
->srelcaps
== NULL
)
9596 if (htab
->root
.dynobj
== NULL
)
9597 htab
->root
.dynobj
= abfd
;
9599 sreloc
= _bfd_elf_make_dynamic_reloc_section
9600 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
,
9601 abfd
, /*rela? */ TRUE
);
9606 htab
->srelcaps
= sreloc
;
9608 htab
->srelcaps
->size
+= RELOC_SIZE (htab
);
9620 /* Treat mapping symbols as special target symbols. */
9623 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
9626 return bfd_is_aarch64_special_symbol_name (sym
->name
,
9627 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
9630 /* If the ELF symbol SYM might be a function in SEC, return the
9631 function size and set *CODE_OFF to the function's entry point,
9632 otherwise return zero. */
9634 static bfd_size_type
9635 elfNN_aarch64_maybe_function_sym (const asymbol
*sym
, asection
*sec
,
9640 if ((sym
->flags
& (BSF_SECTION_SYM
| BSF_FILE
| BSF_OBJECT
9641 | BSF_THREAD_LOCAL
| BSF_RELC
| BSF_SRELC
)) != 0
9642 || sym
->section
!= sec
)
9645 if (!(sym
->flags
& BSF_SYNTHETIC
))
9646 switch (ELF_ST_TYPE (((elf_symbol_type
*) sym
)->internal_elf_sym
.st_info
))
9655 if ((sym
->flags
& BSF_LOCAL
)
9656 && bfd_is_aarch64_special_symbol_name (sym
->name
,
9657 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
))
9660 *code_off
= sym
->value
;
9662 if (!(sym
->flags
& BSF_SYNTHETIC
))
9663 size
= ((elf_symbol_type
*) sym
)->internal_elf_sym
.st_size
;
9670 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
9671 const char **filename_ptr
,
9672 const char **functionname_ptr
,
9673 unsigned int *line_ptr
)
9676 found
= _bfd_dwarf2_find_inliner_info
9677 (abfd
, filename_ptr
,
9678 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
9684 elfNN_aarch64_init_file_header (bfd
*abfd
, struct bfd_link_info
*link_info
)
9686 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
9688 if (!_bfd_elf_init_file_header (abfd
, link_info
))
9691 i_ehdrp
= elf_elfheader (abfd
);
9692 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
9696 static enum elf_reloc_type_class
9697 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
9698 const asection
*rel_sec ATTRIBUTE_UNUSED
,
9699 const Elf_Internal_Rela
*rela
)
9701 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
9703 if (htab
->root
.dynsym
!= NULL
9704 && htab
->root
.dynsym
->contents
!= NULL
)
9706 /* Check relocation against STT_GNU_IFUNC symbol if there are
9708 bfd
*abfd
= info
->output_bfd
;
9709 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
9710 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
9711 if (r_symndx
!= STN_UNDEF
)
9713 Elf_Internal_Sym sym
;
9714 if (!bed
->s
->swap_symbol_in (abfd
,
9715 (htab
->root
.dynsym
->contents
9716 + r_symndx
* bed
->s
->sizeof_sym
),
9719 /* xgettext:c-format */
9720 _bfd_error_handler (_("%pB symbol number %lu references"
9721 " nonexistent SHT_SYMTAB_SHNDX section"),
9723 /* Ideally an error class should be returned here. */
9725 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
9726 return reloc_class_ifunc
;
9730 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
9732 case AARCH64_R (IRELATIVE
):
9733 case MORELLO_R (IRELATIVE
):
9734 return reloc_class_ifunc
;
9735 case AARCH64_R (RELATIVE
):
9736 case MORELLO_R (RELATIVE
):
9737 return reloc_class_relative
;
9738 case AARCH64_R (JUMP_SLOT
):
9739 case MORELLO_R (JUMP_SLOT
):
9740 return reloc_class_plt
;
9741 case AARCH64_R (COPY
):
9742 return reloc_class_copy
;
9744 return reloc_class_normal
;
9748 /* Handle an AArch64 specific section when reading an object file. This is
9749 called when bfd_section_from_shdr finds a section with an unknown
9753 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
9754 Elf_Internal_Shdr
*hdr
,
9755 const char *name
, int shindex
)
9757 /* There ought to be a place to keep ELF backend specific flags, but
9758 at the moment there isn't one. We just keep track of the
9759 sections by their name, instead. Fortunately, the ABI gives
9760 names for all the AArch64 specific sections, so we will probably get
9762 switch (hdr
->sh_type
)
9764 case SHT_AARCH64_ATTRIBUTES
:
9771 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
9780 struct bfd_link_info
*info
;
9783 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
9784 asection
*, struct elf_link_hash_entry
*);
9785 } output_arch_syminfo
;
9787 enum map_symbol_type
9795 /* Output a single mapping symbol. */
9798 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
9799 enum map_symbol_type type
, bfd_vma offset
)
9801 static const char *names
[3] = { "$x", "$d", "$c" };
9802 Elf_Internal_Sym sym
;
9804 sym
.st_value
= (osi
->sec
->output_section
->vma
9805 + osi
->sec
->output_offset
+ offset
);
9808 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
9809 sym
.st_shndx
= osi
->sec_shndx
;
9810 sym
.st_target_internal
= 0;
9811 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
9814 /* Output a single local symbol for a generated stub. */
9817 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
9818 bfd_vma offset
, bfd_vma size
)
9820 Elf_Internal_Sym sym
;
9822 sym
.st_value
= (osi
->sec
->output_section
->vma
9823 + osi
->sec
->output_offset
+ offset
);
9826 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
9827 sym
.st_shndx
= osi
->sec_shndx
;
9828 sym
.st_target_internal
= 0;
9829 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
9833 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
9835 struct elf_aarch64_stub_hash_entry
*stub_entry
;
9839 output_arch_syminfo
*osi
;
9841 /* Massage our args to the form they really have. */
9842 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
9843 osi
= (output_arch_syminfo
*) in_arg
;
9845 stub_sec
= stub_entry
->stub_sec
;
9847 /* Ensure this stub is attached to the current section being
9849 if (stub_sec
!= osi
->sec
)
9852 addr
= (bfd_vma
) stub_entry
->stub_offset
;
9854 stub_name
= stub_entry
->output_name
;
9856 switch (stub_entry
->stub_type
)
9858 case aarch64_stub_adrp_branch
:
9859 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9860 sizeof (aarch64_adrp_branch_stub
)))
9862 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9865 case aarch64_stub_long_branch
:
9866 if (!elfNN_aarch64_output_stub_sym
9867 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
9869 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9871 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
9874 case aarch64_stub_erratum_835769_veneer
:
9875 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9876 sizeof (aarch64_erratum_835769_stub
)))
9878 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9881 case aarch64_stub_erratum_843419_veneer
:
9882 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9883 sizeof (aarch64_erratum_843419_stub
)))
9885 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9888 case aarch64_stub_branch_c64
:
9889 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9890 sizeof (aarch64_c64_branch_stub
)))
9892 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_C64
, addr
))
9895 case c64_stub_branch_aarch64
:
9896 case c64_stub_branch_c64
:
9897 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9898 sizeof (c64_aarch64_branch_stub
)))
9900 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_C64
, addr
))
9903 case aarch64_stub_none
:
9913 /* Output mapping symbols for linker generated sections. */
9916 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
9917 struct bfd_link_info
*info
,
9919 int (*func
) (void *, const char *,
9922 struct elf_link_hash_entry
9925 output_arch_syminfo osi
;
9926 struct elf_aarch64_link_hash_table
*htab
;
9928 htab
= elf_aarch64_hash_table (info
);
9934 /* Long calls stubs. */
9935 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
9939 for (stub_sec
= htab
->stub_bfd
->sections
;
9940 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
9942 /* Ignore non-stub sections. */
9943 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
9948 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
9949 (output_bfd
, osi
.sec
->output_section
);
9951 /* The first instruction in a stub is always a branch. */
9952 if (!elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0))
9955 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
9960 /* Finally, output mapping symbols for the PLT. */
9961 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
9964 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
9965 (output_bfd
, htab
->root
.splt
->output_section
);
9966 osi
.sec
= htab
->root
.splt
;
9968 elfNN_aarch64_output_map_sym (&osi
, (htab
->c64_rel
? AARCH64_MAP_C64
9969 : AARCH64_MAP_INSN
), 0);
9975 /* Allocate target specific section data. */
9978 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
9980 if (!sec
->used_by_bfd
)
9982 _aarch64_elf_section_data
*sdata
;
9983 size_t amt
= sizeof (*sdata
);
9985 sdata
= bfd_zalloc (abfd
, amt
);
9988 sdata
->elf
.is_target_section_data
= TRUE
;
9989 sec
->used_by_bfd
= sdata
;
9992 return _bfd_elf_new_section_hook (abfd
, sec
);
9996 /* Create dynamic sections. This is different from the ARM backend in that
9997 the got, plt, gotplt and their relocation sections are all created in the
9998 standard part of the bfd elf backend. */
10001 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
10002 struct bfd_link_info
*info
)
10004 /* We need to create .got section. */
10005 if (!aarch64_elf_create_got_section (dynobj
, info
))
10008 return _bfd_elf_create_dynamic_sections (dynobj
, info
);
10012 /* Allocate space in .plt, .got and associated reloc sections for
10016 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
10018 struct bfd_link_info
*info
;
10019 struct elf_aarch64_link_hash_table
*htab
;
10020 struct elf_aarch64_link_hash_entry
*eh
;
10021 struct elf_dyn_relocs
*p
;
10023 /* An example of a bfd_link_hash_indirect symbol is versioned
10024 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
10025 -> __gxx_personality_v0(bfd_link_hash_defined)
10027 There is no need to process bfd_link_hash_indirect symbols here
10028 because we will also be presented with the concrete instance of
10029 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
10030 called to copy all relevant data from the generic to the concrete
10031 symbol instance. */
10032 if (h
->root
.type
== bfd_link_hash_indirect
)
10035 if (h
->root
.type
== bfd_link_hash_warning
)
10036 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
10038 info
= (struct bfd_link_info
*) inf
;
10039 htab
= elf_aarch64_hash_table (info
);
10041 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
10042 here if it is defined and referenced in a non-shared object. */
10043 if (h
->type
== STT_GNU_IFUNC
10046 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
10048 /* Make sure this symbol is output as a dynamic symbol.
10049 Undefined weak syms won't yet be marked as dynamic. */
10050 if (h
->dynindx
== -1 && !h
->forced_local
10051 && h
->root
.type
== bfd_link_hash_undefweak
)
10053 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
10057 if (bfd_link_pic (info
) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
10059 asection
*s
= htab
->root
.splt
;
10061 /* If this is the first .plt entry, make room for the special
10064 s
->size
+= htab
->plt_header_size
;
10066 h
->plt
.offset
= s
->size
;
10068 /* If this symbol is not defined in a regular file, and we are
10069 not generating a shared library, then set the symbol to this
10070 location in the .plt. This is required to make function
10071 pointers compare as equal between the normal executable and
10072 the shared library. */
10073 if (!bfd_link_pic (info
) && !h
->def_regular
)
10075 h
->root
.u
.def
.section
= s
;
10076 h
->root
.u
.def
.value
= h
->plt
.offset
;
10079 /* Make room for this entry. For now we only create the
10080 small model PLT entries. We later need to find a way
10081 of relaxing into these from the large model PLT entries. */
10082 s
->size
+= htab
->plt_entry_size
;
10084 /* We also need to make an entry in the .got.plt section, which
10085 will be placed in the .got section by the linker script. */
10086 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE (htab
);
10088 /* We also need to make an entry in the .rela.plt section. */
10089 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
10091 /* We need to ensure that all GOT entries that serve the PLT
10092 are consecutive with the special GOT slots [0] [1] and
10093 [2]. Any addtional relocations, such as
10094 R_AARCH64_TLSDESC, must be placed after the PLT related
10095 entries. We abuse the reloc_count such that during
10096 sizing we adjust reloc_count to indicate the number of
10097 PLT related reserved entries. In subsequent phases when
10098 filling in the contents of the reloc entries, PLT related
10099 entries are placed by computing their PLT index (0
10100 .. reloc_count). While other none PLT relocs are placed
10101 at the slot indicated by reloc_count and reloc_count is
10104 htab
->root
.srelplt
->reloc_count
++;
10106 /* Mark the DSO in case R_<CLS>_JUMP_SLOT relocs against
10107 variant PCS symbols are present. */
10108 if (h
->other
& STO_AARCH64_VARIANT_PCS
)
10109 htab
->variant_pcs
= 1;
10114 h
->plt
.offset
= (bfd_vma
) - 1;
10120 h
->plt
.offset
= (bfd_vma
) - 1;
10124 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
10125 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
10127 if (h
->got
.refcount
> 0)
10130 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
10132 h
->got
.offset
= (bfd_vma
) - 1;
10134 dyn
= htab
->root
.dynamic_sections_created
;
10136 /* Make sure this symbol is output as a dynamic symbol.
10137 Undefined weak syms won't yet be marked as dynamic. */
10138 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
10139 && h
->root
.type
== bfd_link_hash_undefweak
)
10141 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
10145 if (got_type
== GOT_UNKNOWN
)
10148 else if (got_type
== GOT_NORMAL
10149 || got_type
== GOT_CAP
)
10151 h
->got
.offset
= htab
->root
.sgot
->size
;
10152 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10153 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
10154 || h
->root
.type
!= bfd_link_hash_undefweak
)
10155 && (bfd_link_pic (info
)
10156 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
))
10157 /* Undefined weak symbol in static PIE resolves to 0 without
10158 any dynamic relocations. */
10159 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10161 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
10163 else if (bfd_link_executable (info
) && !bfd_link_pic (info
))
10164 htab
->srelcaps
->size
+= RELOC_SIZE (htab
);
10169 if (got_type
& GOT_TLSDESC_GD
)
10171 eh
->tlsdesc_got_jump_table_offset
=
10172 (htab
->root
.sgotplt
->size
10173 - aarch64_compute_jump_table_size (htab
));
10174 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10175 h
->got
.offset
= (bfd_vma
) - 2;
10178 if (got_type
& GOT_TLS_GD
)
10180 h
->got
.offset
= htab
->root
.sgot
->size
;
10181 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10184 if (got_type
& GOT_TLS_IE
)
10186 h
->got
.offset
= htab
->root
.sgot
->size
;
10187 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10190 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
10191 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
10192 || h
->root
.type
!= bfd_link_hash_undefweak
)
10193 && (!bfd_link_executable (info
)
10195 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)
10196 /* On Morello support only TLSDESC_GD to TLSLE relaxation;
10197 for everything else we must emit a dynamic relocation. */
10198 || got_type
& GOT_CAP
))
10200 if (got_type
& GOT_TLSDESC_GD
)
10202 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
10203 /* Note reloc_count not incremented here! We have
10204 already adjusted reloc_count for this relocation
10207 /* TLSDESC PLT is now needed, but not yet determined. */
10208 htab
->root
.tlsdesc_plt
= (bfd_vma
) - 1;
10211 if (got_type
& GOT_TLS_GD
)
10212 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
10214 if (got_type
& GOT_TLS_IE
)
10215 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
10221 h
->got
.offset
= (bfd_vma
) - 1;
10224 if (h
->dyn_relocs
== NULL
)
10227 /* In the shared -Bsymbolic case, discard space allocated for
10228 dynamic pc-relative relocs against symbols which turn out to be
10229 defined in regular objects. For the normal shared case, discard
10230 space for pc-relative relocs that have become local due to symbol
10231 visibility changes. */
10233 if (bfd_link_pic (info
))
10235 /* Relocs that use pc_count are those that appear on a call
10236 insn, or certain REL relocs that can generated via assembly.
10237 We want calls to protected symbols to resolve directly to the
10238 function rather than going via the plt. If people want
10239 function pointer comparisons to work as expected then they
10240 should avoid writing weird assembly. */
10241 if (SYMBOL_CALLS_LOCAL (info
, h
))
10243 struct elf_dyn_relocs
**pp
;
10245 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
10247 p
->count
-= p
->pc_count
;
10256 /* Also discard relocs on undefined weak syms with non-default
10258 if (h
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
10260 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
10261 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10262 h
->dyn_relocs
= NULL
;
10264 /* Make sure undefined weak symbols are output as a dynamic
10266 else if (h
->dynindx
== -1
10267 && !h
->forced_local
10268 && h
->root
.type
== bfd_link_hash_undefweak
10269 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
10274 else if (ELIMINATE_COPY_RELOCS
)
10276 /* For the non-shared case, discard space for relocs against
10277 symbols which turn out to need copy relocs or are not
10280 if (!h
->non_got_ref
10281 && ((h
->def_dynamic
10282 && !h
->def_regular
)
10283 || (htab
->root
.dynamic_sections_created
10284 && (h
->root
.type
== bfd_link_hash_undefweak
10285 || h
->root
.type
== bfd_link_hash_undefined
))))
10287 /* Make sure this symbol is output as a dynamic symbol.
10288 Undefined weak syms won't yet be marked as dynamic. */
10289 if (h
->dynindx
== -1
10290 && !h
->forced_local
10291 && h
->root
.type
== bfd_link_hash_undefweak
10292 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
10295 /* If that succeeded, we know we'll be keeping all the
10297 if (h
->dynindx
!= -1)
10301 h
->dyn_relocs
= NULL
;
10306 /* Finally, allocate space. */
10307 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
10311 sreloc
= elf_section_data (p
->sec
)->sreloc
;
10313 BFD_ASSERT (sreloc
!= NULL
);
10315 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
10321 /* Allocate space in .plt, .got and associated reloc sections for
10322 ifunc dynamic relocs. */
10325 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
10328 struct bfd_link_info
*info
;
10329 struct elf_aarch64_link_hash_table
*htab
;
10331 /* An example of a bfd_link_hash_indirect symbol is versioned
10332 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
10333 -> __gxx_personality_v0(bfd_link_hash_defined)
10335 There is no need to process bfd_link_hash_indirect symbols here
10336 because we will also be presented with the concrete instance of
10337 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
10338 called to copy all relevant data from the generic to the concrete
10339 symbol instance. */
10340 if (h
->root
.type
== bfd_link_hash_indirect
)
10343 if (h
->root
.type
== bfd_link_hash_warning
)
10344 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
10346 info
= (struct bfd_link_info
*) inf
;
10347 htab
= elf_aarch64_hash_table (info
);
10349 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
10350 here if it is defined and referenced in a non-shared object. */
10351 if (h
->type
== STT_GNU_IFUNC
10353 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
10355 htab
->plt_entry_size
,
10356 htab
->plt_header_size
,
10357 GOT_ENTRY_SIZE (htab
),
10362 /* Allocate space in .plt, .got and associated reloc sections for
10363 local ifunc dynamic relocs. */
10366 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
10368 struct elf_link_hash_entry
*h
10369 = (struct elf_link_hash_entry
*) *slot
;
10371 if (h
->type
!= STT_GNU_IFUNC
10374 || !h
->forced_local
10375 || h
->root
.type
!= bfd_link_hash_defined
)
10378 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
10381 /* This is the most important function of all . Innocuosly named
10385 elfNN_aarch64_size_dynamic_sections (bfd
*output_bfd
,
10386 struct bfd_link_info
*info
)
10388 struct elf_aarch64_link_hash_table
*htab
;
10391 bfd_boolean relocs
;
10394 htab
= elf_aarch64_hash_table ((info
));
10395 dynobj
= htab
->root
.dynobj
;
10397 BFD_ASSERT (dynobj
!= NULL
);
10399 if (htab
->root
.dynamic_sections_created
)
10401 if (bfd_link_executable (info
) && !info
->nointerp
)
10403 s
= bfd_get_linker_section (dynobj
, ".interp");
10406 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
10407 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
10411 aarch64_elf_init_got_section (output_bfd
, info
);
10413 setup_plt_values (info
, elf_aarch64_tdata (output_bfd
)->plt_type
);
10415 /* Set up .got offsets for local syms, and space for local dynamic
10417 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
10419 struct elf_aarch64_local_symbol
*locals
= NULL
;
10420 Elf_Internal_Shdr
*symtab_hdr
;
10424 if (!is_aarch64_elf (ibfd
))
10427 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
10429 struct elf_dyn_relocs
*p
;
10431 for (p
= (struct elf_dyn_relocs
*)
10432 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
10434 if (!bfd_is_abs_section (p
->sec
)
10435 && bfd_is_abs_section (p
->sec
->output_section
))
10437 /* Input section has been discarded, either because
10438 it is a copy of a linkonce section or due to
10439 linker script /DISCARD/, so we'll be discarding
10442 else if (p
->count
!= 0)
10444 srel
= elf_section_data (p
->sec
)->sreloc
;
10445 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
10446 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
10447 info
->flags
|= DF_TEXTREL
;
10452 locals
= elf_aarch64_locals (ibfd
);
10456 symtab_hdr
= &elf_symtab_hdr (ibfd
);
10457 srel
= htab
->root
.srelgot
;
10458 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
10460 locals
[i
].got_offset
= (bfd_vma
) - 1;
10461 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
10462 if (locals
[i
].got_refcount
> 0)
10464 unsigned got_type
= locals
[i
].got_type
;
10465 if (got_type
& GOT_TLSDESC_GD
)
10467 locals
[i
].tlsdesc_got_jump_table_offset
=
10468 (htab
->root
.sgotplt
->size
10469 - aarch64_compute_jump_table_size (htab
));
10470 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10471 locals
[i
].got_offset
= (bfd_vma
) - 2;
10474 if (got_type
& GOT_TLS_GD
)
10476 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
10477 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10480 if (got_type
& GOT_TLS_IE
10481 || got_type
& GOT_NORMAL
10482 || got_type
& GOT_CAP
)
10484 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
10485 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10488 if (got_type
== GOT_UNKNOWN
)
10492 if (bfd_link_pic (info
))
10494 if (got_type
& GOT_TLSDESC_GD
)
10496 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
10497 /* Note RELOC_COUNT not incremented here! */
10498 htab
->root
.tlsdesc_plt
= (bfd_vma
) - 1;
10501 if (got_type
& GOT_TLS_GD
)
10502 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
10504 if (got_type
& GOT_TLS_IE
10505 || got_type
& GOT_NORMAL
10506 || got_type
& GOT_CAP
)
10507 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
10509 /* Static binary; put relocs into srelcaps. */
10510 else if (bfd_link_executable (info
) && (got_type
& GOT_CAP
))
10511 htab
->srelcaps
->size
+= RELOC_SIZE (htab
);
10515 locals
[i
].got_refcount
= (bfd_vma
) - 1;
10521 /* Allocate global sym .plt and .got entries, and space for global
10522 sym dynamic relocs. */
10523 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
10526 /* Allocate global ifunc sym .plt and .got entries, and space for global
10527 ifunc sym dynamic relocs. */
10528 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
10531 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
10532 htab_traverse (htab
->loc_hash_table
,
10533 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
10536 if (bfd_link_executable (info
)
10537 && !bfd_link_pic (info
)
10539 && htab
->srelcaps
->size
> 0)
10541 struct elf_link_hash_entry
*h
;
10543 h
= _bfd_elf_define_linkage_sym (output_bfd
, info
,
10545 "__rela_dyn_start");
10546 h
= _bfd_elf_define_linkage_sym (output_bfd
, info
,
10550 h
->root
.u
.def
.value
= htab
->srelcaps
->vma
+ htab
->srelcaps
->size
;
10553 /* For every jump slot reserved in the sgotplt, reloc_count is
10554 incremented. However, when we reserve space for TLS descriptors,
10555 it's not incremented, so in order to compute the space reserved
10556 for them, it suffices to multiply the reloc count by the jump
10559 if (htab
->root
.srelplt
)
10560 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
10562 if (htab
->root
.tlsdesc_plt
)
10564 if (htab
->root
.splt
->size
== 0)
10565 htab
->root
.splt
->size
+= htab
->plt_header_size
;
10567 /* If we're not using lazy TLS relocations, don't generate the
10568 GOT and PLT entry required. */
10569 if ((info
->flags
& DF_BIND_NOW
))
10570 htab
->root
.tlsdesc_plt
= 0;
10573 htab
->root
.tlsdesc_plt
= htab
->root
.splt
->size
;
10574 htab
->root
.splt
->size
+= htab
->tlsdesc_plt_entry_size
;
10576 htab
->root
.tlsdesc_got
= htab
->root
.sgot
->size
;
10577 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10581 /* Init mapping symbols information to use later to distingush between
10582 code and data while scanning for errata. */
10583 if (htab
->fix_erratum_835769
|| htab
->fix_erratum_843419
)
10584 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
10586 if (!is_aarch64_elf (ibfd
))
10588 bfd_elfNN_aarch64_init_maps (ibfd
, info
);
10591 /* We now have determined the sizes of the various dynamic sections.
10592 Allocate memory for them. */
10594 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
10596 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
10599 if (s
== htab
->root
.splt
10600 || s
== htab
->root
.sgot
10601 || s
== htab
->root
.sgotplt
10602 || s
== htab
->root
.iplt
10603 || s
== htab
->root
.igotplt
10604 || s
== htab
->root
.sdynbss
10605 || s
== htab
->root
.sdynrelro
)
10607 /* Strip this section if we don't need it; see the
10610 else if (CONST_STRNEQ (bfd_section_name (s
), ".rela"))
10612 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
10615 /* We use the reloc_count field as a counter if we need
10616 to copy relocs into the output file. */
10617 if (s
!= htab
->root
.srelplt
)
10618 s
->reloc_count
= 0;
10622 /* It's not one of our sections, so don't allocate space. */
10628 /* If we don't need this section, strip it from the
10629 output file. This is mostly to handle .rela.bss and
10630 .rela.plt. We must create both sections in
10631 create_dynamic_sections, because they must be created
10632 before the linker maps input sections to output
10633 sections. The linker does that before
10634 adjust_dynamic_symbol is called, and it is that
10635 function which decides whether anything needs to go
10636 into these sections. */
10637 s
->flags
|= SEC_EXCLUDE
;
10641 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
10644 /* Allocate memory for the section contents. We use bfd_zalloc
10645 here in case unused entries are not reclaimed before the
10646 section's contents are written out. This should not happen,
10647 but this way if it does, we get a R_AARCH64_NONE reloc instead
10649 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
10650 if (s
->contents
== NULL
)
10654 if (htab
->root
.dynamic_sections_created
)
10656 /* Add some entries to the .dynamic section. We fill in the
10657 values later, in elfNN_aarch64_finish_dynamic_sections, but we
10658 must add the entries now so that we get the correct size for
10659 the .dynamic section. The DT_DEBUG entry is filled in by the
10660 dynamic linker and used by the debugger. */
10661 #define add_dynamic_entry(TAG, VAL) \
10662 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
10664 if (!_bfd_elf_add_dynamic_tags (output_bfd
, info
, relocs
))
10667 if (htab
->root
.splt
->size
!= 0)
10669 if (htab
->variant_pcs
10670 && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS
, 0))
10673 if ((elf_aarch64_tdata (output_bfd
)->plt_type
== PLT_BTI_PAC
)
10674 && (!add_dynamic_entry (DT_AARCH64_BTI_PLT
, 0)
10675 || !add_dynamic_entry (DT_AARCH64_PAC_PLT
, 0)))
10678 else if ((elf_aarch64_tdata (output_bfd
)->plt_type
== PLT_BTI
)
10679 && !add_dynamic_entry (DT_AARCH64_BTI_PLT
, 0))
10682 else if ((elf_aarch64_tdata (output_bfd
)->plt_type
== PLT_PAC
)
10683 && !add_dynamic_entry (DT_AARCH64_PAC_PLT
, 0))
10687 #undef add_dynamic_entry
10693 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
10694 bfd_reloc_code_real_type r_type
,
10695 bfd_byte
*plt_entry
, bfd_vma value
)
10697 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
10699 /* FIXME: We should check the return value from this function call. */
10700 (void) _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
10704 aarch64_update_c64_plt_entry (bfd
*output_bfd
, bfd_byte
*plt_entry
,
10705 bfd_vma plt_base
, bfd_vma plt_got_ent
)
10707 /* Fill in the top 20 bits for this: ADRP c16, PLT_GOT + n * 16.
10708 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
10709 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_MORELLO_ADR_HI20_PCREL
,
10711 PG (plt_got_ent
) - PG (plt_base
));
10713 elf_aarch64_update_plt_entry (output_bfd
,
10714 BFD_RELOC_AARCH64_LDST128_LO12
,
10716 PG_OFFSET (plt_got_ent
));
10718 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
10720 PG_OFFSET (plt_got_ent
));
10724 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
10725 struct elf_aarch64_link_hash_table
10726 *htab
, bfd
*output_bfd
,
10727 struct bfd_link_info
*info
)
10729 bfd_byte
*plt_entry
;
10731 bfd_vma got_offset
;
10732 bfd_vma gotplt_entry_address
;
10733 bfd_vma plt_entry_address
;
10734 Elf_Internal_Rela rela
;
10736 asection
*plt
, *gotplt
, *relplt
;
10738 /* When building a static executable, use .iplt, .igot.plt and
10739 .rela.iplt sections for STT_GNU_IFUNC symbols. */
10740 if (htab
->root
.splt
!= NULL
)
10742 plt
= htab
->root
.splt
;
10743 gotplt
= htab
->root
.sgotplt
;
10744 relplt
= htab
->root
.srelplt
;
10748 plt
= htab
->root
.iplt
;
10749 gotplt
= htab
->root
.igotplt
;
10750 relplt
= htab
->root
.irelplt
;
10753 /* Get the index in the procedure linkage table which
10754 corresponds to this symbol. This is the index of this symbol
10755 in all the symbols for which we are making plt entries. The
10756 first entry in the procedure linkage table is reserved.
10758 Get the offset into the .got table of the entry that
10759 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
10760 bytes. The first three are reserved for the dynamic linker.
10762 For static executables, we don't reserve anything. */
10764 if (plt
== htab
->root
.splt
)
10766 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
10767 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE (htab
);
10771 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
10772 got_offset
= plt_index
* GOT_ENTRY_SIZE (htab
);
10775 plt_entry
= plt
->contents
+ h
->plt
.offset
;
10776 plt_entry_address
= plt
->output_section
->vma
10777 + plt
->output_offset
+ h
->plt
.offset
;
10778 gotplt_entry_address
= gotplt
->output_section
->vma
+
10779 gotplt
->output_offset
+ got_offset
;
10781 /* Copy in the boiler-plate for the PLTn entry. */
10782 memcpy (plt_entry
, htab
->plt_entry
, htab
->plt_entry_size
);
10785 aarch64_update_c64_plt_entry (output_bfd
, plt_entry
, plt_entry_address
,
10786 gotplt_entry_address
);
10790 /* First instruction in BTI enabled PLT stub is a BTI
10791 instruction so skip it. */
10792 if (elf_aarch64_tdata (output_bfd
)->plt_type
& PLT_BTI
10793 && elf_elfheader (output_bfd
)->e_type
== ET_EXEC
)
10794 plt_entry
= plt_entry
+ 4;
10796 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
10797 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
10798 elf_aarch64_update_plt_entry (output_bfd
,
10799 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
10801 PG (gotplt_entry_address
) -
10802 PG (plt_entry_address
));
10804 /* Fill in the lo12 bits for the load from the pltgot. */
10805 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
10807 PG_OFFSET (gotplt_entry_address
));
10809 /* Fill in the lo12 bits for the add from the pltgot entry. */
10810 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
10812 PG_OFFSET (gotplt_entry_address
));
10815 /* All the GOTPLT Entries are essentially initialized to PLT0. Set LSB if
10817 bfd_vma plt0
= ((plt
->output_section
->vma
+ plt
->output_offset
)
10819 bfd_put_NN (output_bfd
, plt0
, gotplt
->contents
+ got_offset
);
10821 rela
.r_offset
= gotplt_entry_address
;
10823 if (h
->dynindx
== -1
10824 || ((bfd_link_executable (info
)
10825 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
10827 && h
->type
== STT_GNU_IFUNC
))
10829 /* If an STT_GNU_IFUNC symbol is locally defined, generate
10830 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
10831 rela
.r_info
= (elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
10832 ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE
))
10833 : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
)));
10834 rela
.r_addend
= (h
->root
.u
.def
.value
10835 + h
->root
.u
.def
.section
->output_section
->vma
10836 + h
->root
.u
.def
.section
->output_offset
);
10840 /* Fill in the entry in the .rela.plt section. */
10841 rela
.r_info
= (elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
10842 ? ELFNN_R_INFO (h
->dynindx
, MORELLO_R (JUMP_SLOT
))
10843 : ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
)));
10847 /* Compute the relocation entry to used based on PLT index and do
10848 not adjust reloc_count. The reloc_count has already been adjusted
10849 to account for this entry. */
10850 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
10851 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
10854 /* Size sections even though they're not dynamic. We use it to setup
10855 _TLS_MODULE_BASE_, if needed. */
10858 elfNN_aarch64_always_size_sections (bfd
*output_bfd
,
10859 struct bfd_link_info
*info
)
10863 if (bfd_link_relocatable (info
))
10866 tls_sec
= elf_hash_table (info
)->tls_sec
;
10870 struct elf_link_hash_entry
*tlsbase
;
10872 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
10873 "_TLS_MODULE_BASE_", TRUE
, TRUE
, FALSE
);
10877 struct bfd_link_hash_entry
*h
= NULL
;
10878 const struct elf_backend_data
*bed
=
10879 get_elf_backend_data (output_bfd
);
10881 if (!(_bfd_generic_link_add_one_symbol
10882 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
10883 tls_sec
, 0, NULL
, FALSE
, bed
->collect
, &h
)))
10886 tlsbase
->type
= STT_TLS
;
10887 tlsbase
= (struct elf_link_hash_entry
*) h
;
10888 tlsbase
->def_regular
= 1;
10889 tlsbase
->other
= STV_HIDDEN
;
10890 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, TRUE
);
10897 /* Finish up dynamic symbol handling. We set the contents of various
10898 dynamic sections here. */
10901 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
10902 struct bfd_link_info
*info
,
10903 struct elf_link_hash_entry
*h
,
10904 Elf_Internal_Sym
*sym
)
10906 struct elf_aarch64_link_hash_table
*htab
;
10907 htab
= elf_aarch64_hash_table (info
);
10909 if (h
->plt
.offset
!= (bfd_vma
) - 1)
10911 asection
*plt
, *gotplt
, *relplt
;
10913 /* This symbol has an entry in the procedure linkage table. Set
10916 /* When building a static executable, use .iplt, .igot.plt and
10917 .rela.iplt sections for STT_GNU_IFUNC symbols. */
10918 if (htab
->root
.splt
!= NULL
)
10920 plt
= htab
->root
.splt
;
10921 gotplt
= htab
->root
.sgotplt
;
10922 relplt
= htab
->root
.srelplt
;
10926 plt
= htab
->root
.iplt
;
10927 gotplt
= htab
->root
.igotplt
;
10928 relplt
= htab
->root
.irelplt
;
10931 /* This symbol has an entry in the procedure linkage table. Set
10933 if ((h
->dynindx
== -1
10934 && !((h
->forced_local
|| bfd_link_executable (info
))
10936 && h
->type
== STT_GNU_IFUNC
))
10942 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
10943 if (!h
->def_regular
)
10945 /* Mark the symbol as undefined, rather than as defined in
10946 the .plt section. */
10947 sym
->st_shndx
= SHN_UNDEF
;
10948 /* If the symbol is weak we need to clear the value.
10949 Otherwise, the PLT entry would provide a definition for
10950 the symbol even if the symbol wasn't defined anywhere,
10951 and so the symbol would never be NULL. Leave the value if
10952 there were any relocations where pointer equality matters
10953 (this is a clue for the dynamic linker, to make function
10954 pointer comparisons work between an application and shared
10956 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
10961 bfd_boolean is_c64
= elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
;
10963 if (h
->got
.offset
!= (bfd_vma
) - 1
10964 && (elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
10965 || elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
)
10966 /* Undefined weak symbol in static PIE resolves to 0 without
10967 any dynamic relocations. */
10968 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10970 Elf_Internal_Rela rela
;
10973 /* This symbol has an entry in the global offset table. Set it
10975 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
10978 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
10979 + htab
->root
.sgot
->output_offset
10980 + (h
->got
.offset
& ~(bfd_vma
) 1));
10983 && h
->type
== STT_GNU_IFUNC
)
10985 if (bfd_link_pic (info
))
10987 /* Generate R_AARCH64_GLOB_DAT. */
10994 if (!h
->pointer_equality_needed
)
10997 /* For non-shared object, we can't use .got.plt, which
10998 contains the real function address if we need pointer
10999 equality. We load the GOT entry with the PLT entry. */
11000 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
11001 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
11002 + plt
->output_offset
11004 htab
->root
.sgot
->contents
11005 + (h
->got
.offset
& ~(bfd_vma
) 1));
11009 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
11011 if (!(h
->def_regular
|| ELF_COMMON_DEF_P (h
)))
11014 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
11017 rela
.r_info
= ELFNN_R_INFO (0, MORELLO_R (RELATIVE
));
11022 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
11023 rela
.r_addend
= (h
->root
.u
.def
.value
11024 + h
->root
.u
.def
.section
->output_section
->vma
11025 + h
->root
.u
.def
.section
->output_offset
);
11031 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
11032 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
11033 htab
->root
.sgot
->contents
+ h
->got
.offset
);
11034 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
11035 (is_c64
? MORELLO_R (GLOB_DAT
)
11036 : AARCH64_R (GLOB_DAT
)));
11040 loc
= htab
->root
.srelgot
->contents
;
11041 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
11042 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
11047 Elf_Internal_Rela rela
;
11051 /* This symbol needs a copy reloc. Set it up. */
11052 if (h
->dynindx
== -1
11053 || (h
->root
.type
!= bfd_link_hash_defined
11054 && h
->root
.type
!= bfd_link_hash_defweak
)
11055 || htab
->root
.srelbss
== NULL
)
11058 rela
.r_offset
= (h
->root
.u
.def
.value
11059 + h
->root
.u
.def
.section
->output_section
->vma
11060 + h
->root
.u
.def
.section
->output_offset
);
11061 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
11063 if (h
->root
.u
.def
.section
== htab
->root
.sdynrelro
)
11064 s
= htab
->root
.sreldynrelro
;
11066 s
= htab
->root
.srelbss
;
11067 loc
= s
->contents
+ s
->reloc_count
++ * RELOC_SIZE (htab
);
11068 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
11071 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
11072 be NULL for local symbols. */
11074 && (h
== elf_hash_table (info
)->hdynamic
11075 || h
== elf_hash_table (info
)->hgot
))
11076 sym
->st_shndx
= SHN_ABS
;
11081 /* Finish up local dynamic symbol handling. We set the contents of
11082 various dynamic sections here. */
11085 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
11087 struct elf_link_hash_entry
*h
11088 = (struct elf_link_hash_entry
*) *slot
;
11089 struct bfd_link_info
*info
11090 = (struct bfd_link_info
*) inf
;
11092 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
11097 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
11098 struct elf_aarch64_link_hash_table
11101 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
11102 small and large plts and at the minute just generates
11105 /* PLT0 of the small PLT looks like this in ELF64 -
11106 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
11107 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
11108 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
11110 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
11111 // GOTPLT entry for this.
11113 PLT0 will be slightly different in ELF32 due to different got entry
11115 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
11119 memcpy (htab
->root
.splt
->contents
, htab
->plt0_entry
,
11120 htab
->plt_header_size
);
11122 /* PR 26312: Explicitly set the sh_entsize to 0 so that
11123 consumers do not think that the section contains fixed
11125 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
= 0;
11127 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
11128 + htab
->root
.sgotplt
->output_offset
11129 + GOT_ENTRY_SIZE (htab
) * 2);
11131 plt_base
= htab
->root
.splt
->output_section
->vma
+
11132 htab
->root
.splt
->output_offset
;
11134 bfd_byte
*plt0_entry
= htab
->root
.splt
->contents
;
11138 aarch64_update_c64_plt_entry (output_bfd
, plt0_entry
+ 4,
11139 plt_base
+ 4, plt_got_2nd_ent
);
11143 /* First instruction in BTI enabled PLT stub is a BTI
11144 instruction so skip it. */
11145 if (elf_aarch64_tdata (output_bfd
)->plt_type
& PLT_BTI
)
11146 plt0_entry
= plt0_entry
+ 4;
11148 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
11149 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
11150 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
11152 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
11154 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
11156 PG_OFFSET (plt_got_2nd_ent
));
11158 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
11160 PG_OFFSET (plt_got_2nd_ent
));
11164 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
11165 struct bfd_link_info
*info
)
11167 struct elf_aarch64_link_hash_table
*htab
;
11171 htab
= elf_aarch64_hash_table (info
);
11172 dynobj
= htab
->root
.dynobj
;
11173 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
11175 if (htab
->root
.dynamic_sections_created
)
11177 ElfNN_External_Dyn
*dyncon
, *dynconend
;
11179 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
11182 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
11183 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
11184 for (; dyncon
< dynconend
; dyncon
++)
11186 Elf_Internal_Dyn dyn
;
11189 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
11197 s
= htab
->root
.sgotplt
;
11198 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
11202 s
= htab
->root
.srelplt
;
11203 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
11207 s
= htab
->root
.srelplt
;
11208 dyn
.d_un
.d_val
= s
->size
;
11211 case DT_TLSDESC_PLT
:
11212 s
= htab
->root
.splt
;
11213 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
11214 + htab
->root
.tlsdesc_plt
;
11217 case DT_TLSDESC_GOT
:
11218 s
= htab
->root
.sgot
;
11219 BFD_ASSERT (htab
->root
.tlsdesc_got
!= (bfd_vma
)-1);
11220 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
11221 + htab
->root
.tlsdesc_got
;
11225 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
11230 /* Fill in the special first entry in the procedure linkage table. */
11231 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
11233 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
11235 if (htab
->root
.tlsdesc_plt
&& !(info
->flags
& DF_BIND_NOW
))
11237 BFD_ASSERT (htab
->root
.tlsdesc_got
!= (bfd_vma
)-1);
11238 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
11239 htab
->root
.sgot
->contents
+ htab
->root
.tlsdesc_got
);
11241 const bfd_byte
*entry
= elfNN_aarch64_tlsdesc_small_plt_entry
;
11242 htab
->tlsdesc_plt_entry_size
= PLT_TLSDESC_ENTRY_SIZE
;
11244 unsigned adrp_rtype
= BFD_RELOC_AARCH64_ADR_HI21_PCREL
;
11245 unsigned ldr_rtype
= BFD_RELOC_AARCH64_LDSTNN_LO12
;
11247 aarch64_plt_type type
= elf_aarch64_tdata (output_bfd
)->plt_type
;
11250 entry
= elfNN_aarch64_tlsdesc_small_plt_c64_entry
;
11251 adrp_rtype
= BFD_RELOC_MORELLO_ADR_HI20_PCREL
;
11252 ldr_rtype
= BFD_RELOC_AARCH64_LDST128_LO12
;
11254 else if (type
== PLT_BTI
|| type
== PLT_BTI_PAC
)
11256 entry
= elfNN_aarch64_tlsdesc_small_plt_bti_entry
;
11259 memcpy (htab
->root
.splt
->contents
+ htab
->root
.tlsdesc_plt
,
11260 entry
, htab
->tlsdesc_plt_entry_size
);
11263 bfd_vma adrp1_addr
=
11264 htab
->root
.splt
->output_section
->vma
11265 + htab
->root
.splt
->output_offset
11266 + htab
->root
.tlsdesc_plt
+ 4;
11268 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
11271 htab
->root
.sgot
->output_section
->vma
11272 + htab
->root
.sgot
->output_offset
;
11274 bfd_vma pltgot_addr
=
11275 htab
->root
.sgotplt
->output_section
->vma
11276 + htab
->root
.sgotplt
->output_offset
;
11278 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->root
.tlsdesc_got
;
11280 bfd_byte
*plt_entry
=
11281 htab
->root
.splt
->contents
+ htab
->root
.tlsdesc_plt
;
11283 /* First instruction in BTI enabled PLT stub is a BTI
11284 instruction so skip it. */
11285 if (type
& PLT_BTI
)
11287 plt_entry
= plt_entry
+ 4;
11288 adrp1_addr
= adrp1_addr
+ 4;
11289 adrp2_addr
= adrp2_addr
+ 4;
11292 /* adrp x2, DT_TLSDESC_GOT */
11293 elf_aarch64_update_plt_entry (output_bfd
,
11296 (PG (dt_tlsdesc_got
)
11297 - PG (adrp1_addr
)));
11300 elf_aarch64_update_plt_entry (output_bfd
,
11304 - PG (adrp2_addr
)));
11306 /* ldr x2, [x2, #0] */
11307 elf_aarch64_update_plt_entry (output_bfd
,
11310 PG_OFFSET (dt_tlsdesc_got
));
11312 /* add x3, x3, 0 */
11313 elf_aarch64_update_plt_entry (output_bfd
,
11314 BFD_RELOC_AARCH64_ADD_LO12
,
11316 PG_OFFSET (pltgot_addr
));
11321 if (htab
->root
.sgotplt
)
11323 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
11326 (_("discarded output section: `%pA'"), htab
->root
.sgotplt
);
11330 /* Fill in the first three entries in the global offset table. */
11331 if (htab
->root
.sgotplt
->size
> 0)
11333 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
11335 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
11336 bfd_put_NN (output_bfd
,
11338 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE (htab
));
11339 bfd_put_NN (output_bfd
,
11341 (htab
->root
.sgotplt
->contents
11342 + GOT_ENTRY_SIZE (htab
) * 2));
11345 if (htab
->root
.sgot
)
11347 if (htab
->root
.sgot
->size
> 0)
11350 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
11351 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
11355 elf_section_data (htab
->root
.sgotplt
->output_section
)->
11356 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE (htab
);
11359 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
11360 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
11361 = GOT_ENTRY_SIZE (htab
);
11363 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
11364 htab_traverse (htab
->loc_hash_table
,
11365 elfNN_aarch64_finish_local_dynamic_symbol
,
11371 /* Check if BTI enabled PLTs are needed. Returns the type needed. */
11372 static aarch64_plt_type
11373 get_plt_type (bfd
*abfd
)
11375 aarch64_plt_type ret
= PLT_NORMAL
;
11376 bfd_byte
*contents
, *extdyn
, *extdynend
;
11377 asection
*sec
= bfd_get_section_by_name (abfd
, ".dynamic");
11378 if (!sec
|| !bfd_malloc_and_get_section (abfd
, sec
, &contents
))
11381 extdynend
= contents
+ sec
->size
;
11382 for (; extdyn
< extdynend
; extdyn
+= sizeof (ElfNN_External_Dyn
))
11384 Elf_Internal_Dyn dyn
;
11385 bfd_elfNN_swap_dyn_in (abfd
, extdyn
, &dyn
);
11387 /* Let's check the processor specific dynamic array tags. */
11388 bfd_vma tag
= dyn
.d_tag
;
11389 if (tag
< DT_LOPROC
|| tag
> DT_HIPROC
)
11394 case DT_AARCH64_BTI_PLT
:
11398 case DT_AARCH64_PAC_PLT
:
11410 elfNN_aarch64_get_synthetic_symtab (bfd
*abfd
,
11417 elf_aarch64_tdata (abfd
)->plt_type
= get_plt_type (abfd
);
11418 return _bfd_elf_get_synthetic_symtab (abfd
, symcount
, syms
,
11419 dynsymcount
, dynsyms
, ret
);
11422 /* Return address for Ith PLT stub in section PLT, for relocation REL
11423 or (bfd_vma) -1 if it should not be included. */
11426 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
11427 const arelent
*rel ATTRIBUTE_UNUSED
)
11429 size_t plt0_size
= PLT_ENTRY_SIZE
;
11430 size_t pltn_size
= PLT_SMALL_ENTRY_SIZE
;
11432 if (elf_aarch64_tdata (plt
->owner
)->plt_type
== PLT_BTI_PAC
)
11434 if (elf_elfheader (plt
->owner
)->e_type
== ET_EXEC
)
11435 pltn_size
= PLT_BTI_PAC_SMALL_ENTRY_SIZE
;
11437 pltn_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
11439 else if (elf_aarch64_tdata (plt
->owner
)->plt_type
== PLT_BTI
)
11441 if (elf_elfheader (plt
->owner
)->e_type
== ET_EXEC
)
11442 pltn_size
= PLT_BTI_SMALL_ENTRY_SIZE
;
11444 else if (elf_aarch64_tdata (plt
->owner
)->plt_type
== PLT_PAC
)
11446 pltn_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
11449 return plt
->vma
+ plt0_size
+ i
* pltn_size
;
11452 /* Returns TRUE if NAME is an AArch64 mapping symbol.
11453 The ARM ELF standard defines $x (for A64 code) and $d (for data).
11454 It also allows a period initiated suffix to be added to the symbol, ie:
11455 "$[adtx]\.[:sym_char]+". */
11458 is_aarch64_mapping_symbol (const char * name
)
11460 return name
!= NULL
/* Paranoia. */
11461 && name
[0] == '$' /* Note: if objcopy --prefix-symbols has been used then
11462 the mapping symbols could have acquired a prefix.
11463 We do not support this here, since such symbols no
11464 longer conform to the ARM ELF ABI. */
11465 && (name
[1] == 'd' || name
[1] == 'x' || name
[1] == 'c')
11466 && (name
[2] == 0 || name
[2] == '.');
11467 /* FIXME: Strictly speaking the symbol is only a valid mapping symbol if
11468 any characters that follow the period are legal characters for the body
11469 of a symbol's name. For now we just assume that this is the case. */
11472 /* Make sure that mapping symbols in object files are not removed via the
11473 "strip --strip-unneeded" tool. These symbols might needed in order to
11474 correctly generate linked files. Once an object file has been linked,
11475 it should be safe to remove them. */
11478 elfNN_aarch64_backend_symbol_processing (bfd
*abfd
, asymbol
*sym
)
11480 if (((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
11481 && sym
->section
!= bfd_abs_section_ptr
11482 && is_aarch64_mapping_symbol (sym
->name
))
11483 sym
->flags
|= BSF_KEEP
;
11486 /* Implement elf_backend_setup_gnu_properties for AArch64. It serves as a
11487 wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account
11488 for the effect of GNU properties of the output_bfd. */
11490 elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info
*info
)
11492 uint32_t prop
= elf_aarch64_tdata (info
->output_bfd
)->gnu_and_prop
;
11493 bfd
*pbfd
= _bfd_aarch64_elf_link_setup_gnu_properties (info
, &prop
);
11494 elf_aarch64_tdata (info
->output_bfd
)->gnu_and_prop
= prop
;
11495 elf_aarch64_tdata (info
->output_bfd
)->plt_type
11496 |= (prop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
) ? PLT_BTI
: 0;
11500 /* Implement elf_backend_merge_gnu_properties for AArch64. It serves as a
11501 wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account
11502 for the effect of GNU properties of the output_bfd. */
11504 elfNN_aarch64_merge_gnu_properties (struct bfd_link_info
*info
,
11505 bfd
*abfd
, bfd
*bbfd
,
11506 elf_property
*aprop
,
11507 elf_property
*bprop
)
11510 = elf_aarch64_tdata (info
->output_bfd
)->gnu_and_prop
;
11512 /* If output has been marked with BTI using command line argument, give out
11513 warning if necessary. */
11514 /* Properties are merged per type, hence only check for warnings when merging
11515 GNU_PROPERTY_AARCH64_FEATURE_1_AND. */
11516 if (((aprop
&& aprop
->pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
)
11517 || (bprop
&& bprop
->pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
))
11518 && (prop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
)
11519 && (!elf_aarch64_tdata (info
->output_bfd
)->no_bti_warn
))
11521 if ((aprop
&& !(aprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
11524 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
11525 "all inputs do not have BTI in NOTE section."),
11528 if ((bprop
&& !(bprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
11531 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
11532 "all inputs do not have BTI in NOTE section."),
11537 return _bfd_aarch64_elf_merge_gnu_properties (info
, abfd
, aprop
,
11541 /* Demangle c64 function symbols as we read them in. */
11544 aarch64_elfNN_swap_symbol_in (bfd
* abfd
,
11547 Elf_Internal_Sym
*dst
)
11549 if (!bfd_elfNN_swap_symbol_in (abfd
, psrc
, pshn
, dst
))
11552 dst
->st_target_internal
= 0;
11554 if (ELF_ST_TYPE (dst
->st_info
) == STT_FUNC
11555 || ELF_ST_TYPE (dst
->st_info
) == STT_GNU_IFUNC
)
11557 dst
->st_target_internal
= dst
->st_value
& ST_BRANCH_TO_C64
;
11558 dst
->st_value
&= ~(bfd_vma
) ST_BRANCH_TO_C64
;
11565 /* Mangle c64 function symbols as we write them out. */
11568 aarch64_elfNN_swap_symbol_out (bfd
*abfd
,
11569 const Elf_Internal_Sym
*src
,
11573 Elf_Internal_Sym newsym
= *src
;
11575 if ((ELF_ST_TYPE (newsym
.st_info
) == STT_FUNC
11576 || ELF_ST_TYPE (newsym
.st_info
) == STT_GNU_IFUNC
)
11577 && newsym
.st_shndx
!= SHN_UNDEF
)
11578 newsym
.st_value
|= newsym
.st_target_internal
;
11580 bfd_elfNN_swap_symbol_out (abfd
, &newsym
, cdst
, shndx
);
11583 /* Define the size of a GOT element for the generic mid-end. */
11586 elfNN_aarch64_got_elt_size (bfd
*abfd ATTRIBUTE_UNUSED
,
11587 struct bfd_link_info
*info
,
11588 struct elf_link_hash_entry
*h ATTRIBUTE_UNUSED
,
11589 bfd
*ibfd ATTRIBUTE_UNUSED
,
11590 unsigned long symndx ATTRIBUTE_UNUSED
)
11592 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
11594 return GOT_ENTRY_SIZE (htab
);
11597 /* Define the size of a GOT header, which is the minimum size of the GOT section
11598 when one is needed. */
11601 elfNN_aarch64_got_header_size (struct bfd_link_info
*info
)
11603 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
11605 return GOT_ENTRY_SIZE (htab
) * GOT_RESERVED_HEADER_SLOTS
;
11608 /* Identify the 'C' in the CIE augmentation string. */
11611 elf64_aarch64_eh_frame_augmentation_char (const char aug
)
11616 /* We use this so we can override certain functions
11617 (though currently we don't). */
11619 const struct elf_size_info elfNN_aarch64_size_info
=
11621 sizeof (ElfNN_External_Ehdr
),
11622 sizeof (ElfNN_External_Phdr
),
11623 sizeof (ElfNN_External_Shdr
),
11624 sizeof (ElfNN_External_Rel
),
11625 sizeof (ElfNN_External_Rela
),
11626 sizeof (ElfNN_External_Sym
),
11627 sizeof (ElfNN_External_Dyn
),
11628 sizeof (Elf_External_Note
),
11629 4, /* Hash table entry size. */
11630 1, /* Internal relocs per external relocs. */
11631 ARCH_SIZE
, /* Arch size. */
11632 LOG_FILE_ALIGN
, /* Log_file_align. */
11633 ELFCLASSNN
, EV_CURRENT
,
11634 bfd_elfNN_write_out_phdrs
,
11635 bfd_elfNN_write_shdrs_and_ehdr
,
11636 bfd_elfNN_checksum_contents
,
11637 bfd_elfNN_write_relocs
,
11638 aarch64_elfNN_swap_symbol_in
,
11639 aarch64_elfNN_swap_symbol_out
,
11640 bfd_elfNN_slurp_reloc_table
,
11641 bfd_elfNN_slurp_symbol_table
,
11642 bfd_elfNN_swap_dyn_in
,
11643 bfd_elfNN_swap_dyn_out
,
11644 bfd_elfNN_swap_reloc_in
,
11645 bfd_elfNN_swap_reloc_out
,
11646 bfd_elfNN_swap_reloca_in
,
11647 bfd_elfNN_swap_reloca_out
11650 #define ELF_ARCH bfd_arch_aarch64
11651 #define ELF_MACHINE_CODE EM_AARCH64
11652 #define ELF_MAXPAGESIZE 0x10000
11653 #define ELF_MINPAGESIZE 0x1000
11654 #define ELF_COMMONPAGESIZE 0x1000
11656 #define bfd_elfNN_bfd_is_target_special_symbol \
11657 elfNN_aarch64_is_target_special_symbol
11659 #define bfd_elfNN_bfd_link_hash_table_create \
11660 elfNN_aarch64_link_hash_table_create
11662 #define bfd_elfNN_bfd_merge_private_bfd_data \
11663 elfNN_aarch64_merge_private_bfd_data
11665 #define bfd_elfNN_bfd_print_private_bfd_data \
11666 elfNN_aarch64_print_private_bfd_data
11668 #define bfd_elfNN_bfd_reloc_type_lookup \
11669 elfNN_aarch64_reloc_type_lookup
11671 #define bfd_elfNN_bfd_reloc_name_lookup \
11672 elfNN_aarch64_reloc_name_lookup
11674 #define bfd_elfNN_bfd_set_private_flags \
11675 elfNN_aarch64_set_private_flags
11677 #define bfd_elfNN_find_inliner_info \
11678 elfNN_aarch64_find_inliner_info
11680 #define bfd_elfNN_get_synthetic_symtab \
11681 elfNN_aarch64_get_synthetic_symtab
11683 #define bfd_elfNN_mkobject \
11684 elfNN_aarch64_mkobject
11686 #define bfd_elfNN_new_section_hook \
11687 elfNN_aarch64_new_section_hook
11689 #define elf_backend_adjust_dynamic_symbol \
11690 elfNN_aarch64_adjust_dynamic_symbol
11692 #define elf_backend_always_size_sections \
11693 elfNN_aarch64_always_size_sections
11695 #define elf_backend_check_relocs \
11696 elfNN_aarch64_check_relocs
11698 #define elf_backend_copy_indirect_symbol \
11699 elfNN_aarch64_copy_indirect_symbol
11701 #define elf_backend_merge_symbol_attribute \
11702 elfNN_aarch64_merge_symbol_attribute
11704 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
11705 to them in our hash. */
11706 #define elf_backend_create_dynamic_sections \
11707 elfNN_aarch64_create_dynamic_sections
11709 #define elf_backend_init_index_section \
11710 _bfd_elf_init_2_index_sections
11712 #define elf_backend_finish_dynamic_sections \
11713 elfNN_aarch64_finish_dynamic_sections
11715 #define elf_backend_finish_dynamic_symbol \
11716 elfNN_aarch64_finish_dynamic_symbol
11718 #define elf_backend_object_p \
11719 elfNN_aarch64_object_p
11721 #define elf_backend_output_arch_local_syms \
11722 elfNN_aarch64_output_arch_local_syms
11724 #define elf_backend_maybe_function_sym \
11725 elfNN_aarch64_maybe_function_sym
11727 #define elf_backend_plt_sym_val \
11728 elfNN_aarch64_plt_sym_val
11730 #define elf_backend_init_file_header \
11731 elfNN_aarch64_init_file_header
11733 #define elf_backend_relocate_section \
11734 elfNN_aarch64_relocate_section
11736 #define elf_backend_reloc_type_class \
11737 elfNN_aarch64_reloc_type_class
11739 #define elf_backend_section_from_shdr \
11740 elfNN_aarch64_section_from_shdr
11742 #define elf_backend_size_dynamic_sections \
11743 elfNN_aarch64_size_dynamic_sections
11745 #define elf_backend_size_info \
11746 elfNN_aarch64_size_info
11748 #define elf_backend_write_section \
11749 elfNN_aarch64_write_section
11751 #define elf_backend_symbol_processing \
11752 elfNN_aarch64_backend_symbol_processing
11754 #define elf_backend_setup_gnu_properties \
11755 elfNN_aarch64_link_setup_gnu_properties
11757 #define elf_backend_merge_gnu_properties \
11758 elfNN_aarch64_merge_gnu_properties
11760 #define elf_backend_got_header_size \
11761 elfNN_aarch64_got_header_size
11763 #define elf_backend_got_elt_size \
11764 elfNN_aarch64_got_elt_size
11766 #define elf_backend_eh_frame_augmentation_char \
11767 elf64_aarch64_eh_frame_augmentation_char
11769 #define elf_backend_can_refcount 1
11770 #define elf_backend_can_gc_sections 1
11771 #define elf_backend_plt_readonly 1
11772 #define elf_backend_want_got_plt 1
11773 #define elf_backend_want_plt_sym 0
11774 #define elf_backend_want_dynrelro 1
11775 #define elf_backend_may_use_rel_p 0
11776 #define elf_backend_may_use_rela_p 1
11777 #define elf_backend_default_use_rela_p 1
11778 #define elf_backend_rela_normal 1
11779 #define elf_backend_dtrel_excludes_plt 1
11780 #define elf_backend_default_execstack 0
11781 #define elf_backend_extern_protected_data 1
11782 #define elf_backend_hash_symbol elf_aarch64_hash_symbol
11784 #undef elf_backend_obj_attrs_section
11785 #define elf_backend_obj_attrs_section ".ARM.attributes"
11787 #include "elfNN-target.h"
11789 /* CloudABI support. */
11791 #undef TARGET_LITTLE_SYM
11792 #define TARGET_LITTLE_SYM aarch64_elfNN_le_cloudabi_vec
11793 #undef TARGET_LITTLE_NAME
11794 #define TARGET_LITTLE_NAME "elfNN-littleaarch64-cloudabi"
11795 #undef TARGET_BIG_SYM
11796 #define TARGET_BIG_SYM aarch64_elfNN_be_cloudabi_vec
11797 #undef TARGET_BIG_NAME
11798 #define TARGET_BIG_NAME "elfNN-bigaarch64-cloudabi"
11801 #define ELF_OSABI ELFOSABI_CLOUDABI
11804 #define elfNN_bed elfNN_aarch64_cloudabi_bed
11806 #include "elfNN-target.h"