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(cur_bfd) \
2933 elf_elfheader(cur_bfd)->e_flags & EF_AARCH64_CHERI_PURECAP ? 32 : (ARCH_SIZE/8)*2
2935 struct elf_aarch64_local_symbol
2937 unsigned int got_type
;
2938 bfd_signed_vma got_refcount
;
2941 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2942 offset is from the end of the jump table and reserved entries
2945 The magic value (bfd_vma) -1 indicates that an offset has not be
2947 bfd_vma tlsdesc_got_jump_table_offset
;
2950 struct elf_aarch64_obj_tdata
2952 struct elf_obj_tdata root
;
2954 /* local symbol descriptors */
2955 struct elf_aarch64_local_symbol
*locals
;
2957 /* Zero to warn when linking objects with incompatible enum sizes. */
2958 int no_enum_size_warning
;
2960 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
2961 int no_wchar_size_warning
;
2963 /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties. */
2964 uint32_t gnu_and_prop
;
2966 /* Zero to warn when linking objects with incompatible
2967 GNU_PROPERTY_AARCH64_FEATURE_1_BTI. */
2970 /* PLT type based on security. */
2971 aarch64_plt_type plt_type
;
2973 /* Flag to check if section maps have been initialised for all sections in
2975 bfd_boolean secmaps_initialised
;
2978 #define elf_aarch64_tdata(bfd) \
2979 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
2981 #define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
2983 #define is_aarch64_elf(bfd) \
2984 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2985 && elf_tdata (bfd) != NULL \
2986 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2989 elfNN_aarch64_mkobject (bfd
*abfd
)
2991 return bfd_elf_allocate_object (abfd
, sizeof (struct elf_aarch64_obj_tdata
),
2995 #define elf_aarch64_hash_entry(ent) \
2996 ((struct elf_aarch64_link_hash_entry *)(ent))
2998 #define GOT_UNKNOWN 0
2999 #define GOT_NORMAL 1
3000 #define GOT_TLS_GD 2
3001 #define GOT_TLS_IE 4
3002 #define GOT_TLSDESC_GD 8
3005 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
3007 /* AArch64 ELF linker hash entry. */
3008 struct elf_aarch64_link_hash_entry
3010 struct elf_link_hash_entry root
;
3012 /* Since PLT entries have variable size, we need to record the
3013 index into .got.plt instead of recomputing it from the PLT
3015 bfd_signed_vma plt_got_offset
;
3017 /* Bit mask representing the type of GOT entry(s) if any required by
3019 unsigned int got_type
;
3021 /* A pointer to the most recently used stub hash entry against this
3023 struct elf_aarch64_stub_hash_entry
*stub_cache
;
3025 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
3026 is from the end of the jump table and reserved entries within the PLTGOT.
3028 The magic value (bfd_vma) -1 indicates that an offset has not
3030 bfd_vma tlsdesc_got_jump_table_offset
;
3034 elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry
*h
,
3036 unsigned long r_symndx
)
3039 return elf_aarch64_hash_entry (h
)->got_type
;
3041 if (! elf_aarch64_locals (abfd
))
3044 return elf_aarch64_locals (abfd
)[r_symndx
].got_type
;
3047 /* Get the AArch64 elf linker hash table from a link_info structure. */
3048 #define elf_aarch64_hash_table(info) \
3049 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
3051 #define aarch64_stub_hash_lookup(table, string, create, copy) \
3052 ((struct elf_aarch64_stub_hash_entry *) \
3053 bfd_hash_lookup ((table), (string), (create), (copy)))
3055 /* AArch64 ELF linker hash table. */
3056 struct elf_aarch64_link_hash_table
3058 /* The main hash table. */
3059 struct elf_link_hash_table root
;
3061 /* Nonzero to force PIC branch veneers. */
3064 /* Fix erratum 835769. */
3065 int fix_erratum_835769
;
3067 /* Fix erratum 843419. */
3068 erratum_84319_opts fix_erratum_843419
;
3070 /* Don't apply link-time values for dynamic relocations. */
3071 int no_apply_dynamic_relocs
;
3073 /* The number of bytes in the initial entry in the PLT. */
3074 bfd_size_type plt_header_size
;
3076 /* The bytes of the initial PLT entry. */
3077 const bfd_byte
*plt0_entry
;
3079 /* The number of bytes in the subsequent PLT entries. */
3080 bfd_size_type plt_entry_size
;
3082 /* The bytes of the subsequent PLT entry. */
3083 const bfd_byte
*plt_entry
;
3085 /* For convenience in allocate_dynrelocs. */
3088 /* The amount of space used by the reserved portion of the sgotplt
3089 section, plus whatever space is used by the jump slots. */
3090 bfd_vma sgotplt_jump_table_size
;
3092 /* The stub hash table. */
3093 struct bfd_hash_table stub_hash_table
;
3095 /* Linker stub bfd. */
3098 /* Linker call-backs. */
3099 asection
*(*add_stub_section
) (const char *, asection
*);
3100 void (*layout_sections_again
) (void);
3102 /* Array to keep track of which stub sections have been created, and
3103 information on stub grouping. */
3106 /* This is the section to which stubs in the group will be
3109 /* The stub section. */
3113 /* Assorted information used by elfNN_aarch64_size_stubs. */
3114 unsigned int bfd_count
;
3115 unsigned int top_index
;
3116 asection
**input_list
;
3118 /* JUMP_SLOT relocs for variant PCS symbols may be present. */
3121 /* The number of bytes in the PLT enty for the TLS descriptor. */
3122 bfd_size_type tlsdesc_plt_entry_size
;
3124 /* Used by local STT_GNU_IFUNC symbols. */
3125 htab_t loc_hash_table
;
3126 void * loc_hash_memory
;
3128 /* Used for capability relocations. */
3131 bfd_boolean c64_output
;
3134 /* Create an entry in an AArch64 ELF linker hash table. */
3136 static struct bfd_hash_entry
*
3137 elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry
*entry
,
3138 struct bfd_hash_table
*table
,
3141 struct elf_aarch64_link_hash_entry
*ret
=
3142 (struct elf_aarch64_link_hash_entry
*) entry
;
3144 /* Allocate the structure if it has not already been allocated by a
3147 ret
= bfd_hash_allocate (table
,
3148 sizeof (struct elf_aarch64_link_hash_entry
));
3150 return (struct bfd_hash_entry
*) ret
;
3152 /* Call the allocation method of the superclass. */
3153 ret
= ((struct elf_aarch64_link_hash_entry
*)
3154 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
3158 ret
->got_type
= GOT_UNKNOWN
;
3159 ret
->plt_got_offset
= (bfd_vma
) - 1;
3160 ret
->stub_cache
= NULL
;
3161 ret
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
3164 return (struct bfd_hash_entry
*) ret
;
3167 /* Initialize an entry in the stub hash table. */
3169 static struct bfd_hash_entry
*
3170 stub_hash_newfunc (struct bfd_hash_entry
*entry
,
3171 struct bfd_hash_table
*table
, const char *string
)
3173 /* Allocate the structure if it has not already been allocated by a
3177 entry
= bfd_hash_allocate (table
,
3179 elf_aarch64_stub_hash_entry
));
3184 /* Call the allocation method of the superclass. */
3185 entry
= bfd_hash_newfunc (entry
, table
, string
);
3188 struct elf_aarch64_stub_hash_entry
*eh
;
3190 /* Initialize the local fields. */
3191 eh
= (struct elf_aarch64_stub_hash_entry
*) entry
;
3192 eh
->adrp_offset
= 0;
3193 eh
->stub_sec
= NULL
;
3194 eh
->stub_offset
= 0;
3195 eh
->target_value
= 0;
3196 eh
->target_section
= NULL
;
3197 eh
->stub_type
= aarch64_stub_none
;
3205 /* Compute a hash of a local hash entry. We use elf_link_hash_entry
3206 for local symbol so that we can handle local STT_GNU_IFUNC symbols
3207 as global symbol. We reuse indx and dynstr_index for local symbol
3208 hash since they aren't used by global symbols in this backend. */
3211 elfNN_aarch64_local_htab_hash (const void *ptr
)
3213 struct elf_link_hash_entry
*h
3214 = (struct elf_link_hash_entry
*) ptr
;
3215 return ELF_LOCAL_SYMBOL_HASH (h
->indx
, h
->dynstr_index
);
3218 /* Compare local hash entries. */
3221 elfNN_aarch64_local_htab_eq (const void *ptr1
, const void *ptr2
)
3223 struct elf_link_hash_entry
*h1
3224 = (struct elf_link_hash_entry
*) ptr1
;
3225 struct elf_link_hash_entry
*h2
3226 = (struct elf_link_hash_entry
*) ptr2
;
3228 return h1
->indx
== h2
->indx
&& h1
->dynstr_index
== h2
->dynstr_index
;
3231 /* Find and/or create a hash entry for local symbol. */
3233 static struct elf_link_hash_entry
*
3234 elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table
*htab
,
3235 bfd
*abfd
, const Elf_Internal_Rela
*rel
,
3238 struct elf_aarch64_link_hash_entry e
, *ret
;
3239 asection
*sec
= abfd
->sections
;
3240 hashval_t h
= ELF_LOCAL_SYMBOL_HASH (sec
->id
,
3241 ELFNN_R_SYM (rel
->r_info
));
3244 e
.root
.indx
= sec
->id
;
3245 e
.root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
3246 slot
= htab_find_slot_with_hash (htab
->loc_hash_table
, &e
, h
,
3247 create
? INSERT
: NO_INSERT
);
3254 ret
= (struct elf_aarch64_link_hash_entry
*) *slot
;
3258 ret
= (struct elf_aarch64_link_hash_entry
*)
3259 objalloc_alloc ((struct objalloc
*) htab
->loc_hash_memory
,
3260 sizeof (struct elf_aarch64_link_hash_entry
));
3263 memset (ret
, 0, sizeof (*ret
));
3264 ret
->root
.indx
= sec
->id
;
3265 ret
->root
.dynstr_index
= ELFNN_R_SYM (rel
->r_info
);
3266 ret
->root
.dynindx
= -1;
3272 /* Copy the extra info we tack onto an elf_link_hash_entry. */
3275 elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info
*info
,
3276 struct elf_link_hash_entry
*dir
,
3277 struct elf_link_hash_entry
*ind
)
3279 struct elf_aarch64_link_hash_entry
*edir
, *eind
;
3281 edir
= (struct elf_aarch64_link_hash_entry
*) dir
;
3282 eind
= (struct elf_aarch64_link_hash_entry
*) ind
;
3284 if (ind
->root
.type
== bfd_link_hash_indirect
)
3286 /* Copy over PLT info. */
3287 if (dir
->got
.refcount
<= 0)
3289 edir
->got_type
= eind
->got_type
;
3290 eind
->got_type
= GOT_UNKNOWN
;
3294 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
3297 /* Merge non-visibility st_other attributes. */
3300 elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry
*h
,
3301 const Elf_Internal_Sym
*isym
,
3302 bfd_boolean definition ATTRIBUTE_UNUSED
,
3303 bfd_boolean dynamic ATTRIBUTE_UNUSED
)
3305 unsigned int isym_sto
= isym
->st_other
& ~ELF_ST_VISIBILITY (-1);
3306 unsigned int h_sto
= h
->other
& ~ELF_ST_VISIBILITY (-1);
3308 if (isym_sto
== h_sto
)
3311 if (isym_sto
& ~STO_AARCH64_VARIANT_PCS
)
3312 /* Not fatal, this callback cannot fail. */
3313 _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"),
3314 h
->root
.root
.string
, isym_sto
);
3316 /* Note: Ideally we would warn about any attribute mismatch, but
3317 this api does not allow that without substantial changes. */
3318 if (isym_sto
& STO_AARCH64_VARIANT_PCS
)
3319 h
->other
|= STO_AARCH64_VARIANT_PCS
;
3322 /* Destroy an AArch64 elf linker hash table. */
3325 elfNN_aarch64_link_hash_table_free (bfd
*obfd
)
3327 struct elf_aarch64_link_hash_table
*ret
3328 = (struct elf_aarch64_link_hash_table
*) obfd
->link
.hash
;
3330 if (ret
->loc_hash_table
)
3331 htab_delete (ret
->loc_hash_table
);
3332 if (ret
->loc_hash_memory
)
3333 objalloc_free ((struct objalloc
*) ret
->loc_hash_memory
);
3335 bfd_hash_table_free (&ret
->stub_hash_table
);
3336 _bfd_elf_link_hash_table_free (obfd
);
3339 /* Create an AArch64 elf linker hash table. */
3341 static struct bfd_link_hash_table
*
3342 elfNN_aarch64_link_hash_table_create (bfd
*abfd
)
3344 struct elf_aarch64_link_hash_table
*ret
;
3345 size_t amt
= sizeof (struct elf_aarch64_link_hash_table
);
3347 ret
= bfd_zmalloc (amt
);
3351 if (!_bfd_elf_link_hash_table_init
3352 (&ret
->root
, abfd
, elfNN_aarch64_link_hash_newfunc
,
3353 sizeof (struct elf_aarch64_link_hash_entry
), AARCH64_ELF_DATA
))
3359 ret
->plt_header_size
= PLT_ENTRY_SIZE
;
3360 ret
->plt0_entry
= elfNN_aarch64_small_plt0_entry
;
3361 ret
->plt_entry_size
= PLT_SMALL_ENTRY_SIZE
;
3362 ret
->plt_entry
= elfNN_aarch64_small_plt_entry
;
3363 ret
->tlsdesc_plt_entry_size
= PLT_TLSDESC_ENTRY_SIZE
;
3365 ret
->root
.tlsdesc_got
= (bfd_vma
) - 1;
3367 if (!bfd_hash_table_init (&ret
->stub_hash_table
, stub_hash_newfunc
,
3368 sizeof (struct elf_aarch64_stub_hash_entry
)))
3370 _bfd_elf_link_hash_table_free (abfd
);
3374 ret
->loc_hash_table
= htab_try_create (1024,
3375 elfNN_aarch64_local_htab_hash
,
3376 elfNN_aarch64_local_htab_eq
,
3378 ret
->loc_hash_memory
= objalloc_create ();
3379 if (!ret
->loc_hash_table
|| !ret
->loc_hash_memory
)
3381 elfNN_aarch64_link_hash_table_free (abfd
);
3384 ret
->root
.root
.hash_table_free
= elfNN_aarch64_link_hash_table_free
;
3386 return &ret
->root
.root
;
3389 /* Perform relocation R_TYPE. Returns TRUE upon success, FALSE otherwise. */
3392 aarch64_relocate (unsigned int r_type
, bfd
*input_bfd
, asection
*input_section
,
3393 bfd_vma offset
, bfd_vma value
)
3395 reloc_howto_type
*howto
;
3398 howto
= elfNN_aarch64_howto_from_type (input_bfd
, r_type
);
3399 place
= (input_section
->output_section
->vma
+ input_section
->output_offset
3402 r_type
= elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
3403 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, r_type
, place
,
3405 return _bfd_aarch64_elf_put_addend (input_bfd
,
3406 input_section
->contents
+ offset
, r_type
,
3407 howto
, value
) == bfd_reloc_ok
;
3410 /* Return interworking stub for a relocation. */
3412 static enum elf_aarch64_stub_type
3413 aarch64_interwork_stub (unsigned int r_type
,
3414 bfd_boolean branch_to_c64
)
3418 case MORELLO_R (JUMP26
):
3419 case MORELLO_R (CALL26
):
3421 return c64_stub_branch_aarch64
;
3423 case AARCH64_R (JUMP26
):
3424 case AARCH64_R (CALL26
):
3426 return aarch64_stub_branch_c64
;
3432 return aarch64_stub_none
;
3435 static enum elf_aarch64_stub_type
3436 aarch64_select_branch_stub (bfd_vma value
, bfd_vma place
)
3438 if (aarch64_valid_for_adrp_p (value
, place
))
3439 return aarch64_stub_adrp_branch
;
3440 return aarch64_stub_long_branch
;
3443 /* Determine the type of stub needed, if any, for a call. */
3445 static enum elf_aarch64_stub_type
3446 aarch64_type_of_stub (asection
*input_sec
,
3447 const Elf_Internal_Rela
*rel
,
3449 unsigned char st_type
,
3450 bfd_vma destination
)
3453 bfd_signed_vma branch_offset
;
3454 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
3455 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
3457 if (st_type
!= STT_FUNC
3458 && (sym_sec
== input_sec
))
3461 /* Determine where the call point is. */
3462 location
= (input_sec
->output_offset
3463 + input_sec
->output_section
->vma
+ rel
->r_offset
);
3465 branch_offset
= (bfd_signed_vma
) (destination
- location
);
3467 /* For A64 <-> C64 branches we only come here for jumps to PLT. Treat them
3468 as regular branches and leave the interworking to PLT. */
3469 if (branch_offset
> AARCH64_MAX_FWD_BRANCH_OFFSET
3470 || branch_offset
< AARCH64_MAX_BWD_BRANCH_OFFSET
)
3474 /* We don't want to redirect any old unconditional jump in this way,
3475 only one which is being used for a sibcall, where it is
3476 acceptable for the IP0 and IP1 registers to be clobbered. */
3477 case AARCH64_R (CALL26
):
3478 case AARCH64_R (JUMP26
):
3479 return aarch64_stub_long_branch
;
3480 case MORELLO_R (CALL26
):
3481 case MORELLO_R (JUMP26
):
3482 return c64_stub_branch_c64
;
3488 return aarch64_stub_none
;
3491 /* Return a string to add as suffix to a veneer name. */
3494 aarch64_lookup_stub_type_suffix (enum elf_aarch64_stub_type stub_type
)
3498 case aarch64_stub_branch_c64
:
3500 case c64_stub_branch_aarch64
:
3508 /* Build a name for an entry in the stub hash table. */
3511 elfNN_aarch64_stub_name (const asection
*input_section
,
3512 const asection
*sym_sec
,
3513 const struct elf_aarch64_link_hash_entry
*hash
,
3514 const Elf_Internal_Rela
*rel
,
3515 enum elf_aarch64_stub_type stub_type
)
3519 const char *suffix
= aarch64_lookup_stub_type_suffix (stub_type
);;
3523 len
= 8 + 1 + strlen (hash
->root
.root
.root
.string
) + 1 + 16 + 1;
3524 stub_name
= bfd_malloc (len
);
3525 if (stub_name
!= NULL
)
3526 snprintf (stub_name
, len
, "%08x_%s%s+%" BFD_VMA_FMT
"x",
3527 (unsigned int) input_section
->id
,
3528 hash
->root
.root
.root
.string
,
3529 suffix
, rel
->r_addend
);
3533 len
= 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
3534 stub_name
= bfd_malloc (len
);
3535 if (stub_name
!= NULL
)
3536 snprintf (stub_name
, len
, "%08x_%x:%x%s+%" BFD_VMA_FMT
"x",
3537 (unsigned int) input_section
->id
,
3538 (unsigned int) sym_sec
->id
,
3539 (unsigned int) ELFNN_R_SYM (rel
->r_info
),
3540 suffix
, rel
->r_addend
);
3546 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
3547 executable PLT slots where the executable never takes the address of those
3548 functions, the function symbols are not added to the hash table. */
3551 elf_aarch64_hash_symbol (struct elf_link_hash_entry
*h
)
3553 if (h
->plt
.offset
!= (bfd_vma
) -1
3555 && !h
->pointer_equality_needed
)
3558 return _bfd_elf_hash_symbol (h
);
3561 /* Look up an entry in the stub hash. Stub entries are cached because
3562 creating the stub name takes a bit of time. */
3564 static struct elf_aarch64_stub_hash_entry
*
3565 elfNN_aarch64_get_stub_entry (const asection
*input_section
,
3566 const asection
*sym_sec
,
3567 struct elf_link_hash_entry
*hash
,
3568 const Elf_Internal_Rela
*rel
,
3569 struct elf_aarch64_link_hash_table
*htab
,
3570 enum elf_aarch64_stub_type stub_type
)
3572 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3573 struct elf_aarch64_link_hash_entry
*h
=
3574 (struct elf_aarch64_link_hash_entry
*) hash
;
3575 const asection
*id_sec
;
3577 if ((input_section
->flags
& SEC_CODE
) == 0)
3580 /* If this input section is part of a group of sections sharing one
3581 stub section, then use the id of the first section in the group.
3582 Stub names need to include a section id, as there may well be
3583 more than one stub used to reach say, printf, and we need to
3584 distinguish between them. */
3585 id_sec
= htab
->stub_group
[input_section
->id
].link_sec
;
3587 if (h
!= NULL
&& h
->stub_cache
!= NULL
3588 && h
->stub_cache
->h
== h
&& h
->stub_cache
->id_sec
== id_sec
)
3590 stub_entry
= h
->stub_cache
;
3596 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, h
, rel
, stub_type
);
3597 if (stub_name
== NULL
)
3600 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
3601 stub_name
, FALSE
, FALSE
);
3603 h
->stub_cache
= stub_entry
;
3612 /* Create a stub section. */
3615 _bfd_aarch64_create_stub_section (asection
*section
,
3616 struct elf_aarch64_link_hash_table
*htab
)
3622 namelen
= strlen (section
->name
);
3623 len
= namelen
+ sizeof (STUB_SUFFIX
);
3624 s_name
= bfd_alloc (htab
->stub_bfd
, len
);
3628 memcpy (s_name
, section
->name
, namelen
);
3629 memcpy (s_name
+ namelen
, STUB_SUFFIX
, sizeof (STUB_SUFFIX
));
3630 return (*htab
->add_stub_section
) (s_name
, section
);
3634 /* Find or create a stub section for a link section.
3636 Fix or create the stub section used to collect stubs attached to
3637 the specified link section. */
3640 _bfd_aarch64_get_stub_for_link_section (asection
*link_section
,
3641 struct elf_aarch64_link_hash_table
*htab
)
3643 if (htab
->stub_group
[link_section
->id
].stub_sec
== NULL
)
3644 htab
->stub_group
[link_section
->id
].stub_sec
3645 = _bfd_aarch64_create_stub_section (link_section
, htab
);
3646 return htab
->stub_group
[link_section
->id
].stub_sec
;
3650 /* Find or create a stub section in the stub group for an input
3654 _bfd_aarch64_create_or_find_stub_sec (asection
*section
,
3655 struct elf_aarch64_link_hash_table
*htab
)
3657 asection
*link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3658 return _bfd_aarch64_get_stub_for_link_section (link_sec
, htab
);
3662 /* Add a new stub entry in the stub group associated with an input
3663 section to the stub hash. Not all fields of the new stub entry are
3666 static struct elf_aarch64_stub_hash_entry
*
3667 _bfd_aarch64_add_stub_entry_in_group (const char *stub_name
,
3669 struct elf_aarch64_link_hash_table
*htab
)
3673 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3675 link_sec
= htab
->stub_group
[section
->id
].link_sec
;
3676 stub_sec
= _bfd_aarch64_create_or_find_stub_sec (section
, htab
);
3678 /* Enter this entry into the linker stub hash table. */
3679 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3681 if (stub_entry
== NULL
)
3683 /* xgettext:c-format */
3684 _bfd_error_handler (_("%pB: cannot create stub entry %s"),
3685 section
->owner
, stub_name
);
3689 stub_entry
->stub_sec
= stub_sec
;
3690 stub_entry
->stub_offset
= 0;
3691 stub_entry
->id_sec
= link_sec
;
3696 /* Add a new stub entry in the final stub section to the stub hash.
3697 Not all fields of the new stub entry are initialised. */
3699 static struct elf_aarch64_stub_hash_entry
*
3700 _bfd_aarch64_add_stub_entry_after (const char *stub_name
,
3701 asection
*link_section
,
3702 struct elf_aarch64_link_hash_table
*htab
)
3705 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3708 /* Only create the actual stub if we will end up needing it. */
3709 if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
3710 stub_sec
= _bfd_aarch64_get_stub_for_link_section (link_section
, htab
);
3711 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
3713 if (stub_entry
== NULL
)
3715 _bfd_error_handler (_("cannot create stub entry %s"), stub_name
);
3719 stub_entry
->stub_sec
= stub_sec
;
3720 stub_entry
->stub_offset
= 0;
3721 stub_entry
->id_sec
= link_section
;
3728 aarch64_build_one_stub (struct bfd_hash_entry
*gen_entry
,
3731 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3736 bfd_vma veneered_insn_loc
;
3737 bfd_vma veneer_entry_loc
;
3738 bfd_signed_vma branch_offset
= 0;
3739 unsigned int template_size
;
3740 const uint32_t *template;
3742 struct bfd_link_info
*info
;
3744 /* Massage our args to the form they really have. */
3745 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
3747 info
= (struct bfd_link_info
*) in_arg
;
3749 /* Fail if the target section could not be assigned to an output
3750 section. The user should fix his linker script. */
3751 if (stub_entry
->target_section
->output_section
== NULL
3752 && info
->non_contiguous_regions
)
3753 info
->callbacks
->einfo (_("%F%P: Could not assign '%pA' to an output section. "
3755 "--enable-non-contiguous-regions.\n"),
3756 stub_entry
->target_section
);
3758 stub_sec
= stub_entry
->stub_sec
;
3760 /* Make a note of the offset within the stubs for this entry. */
3761 stub_entry
->stub_offset
= stub_sec
->size
;
3762 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
3764 stub_bfd
= stub_sec
->owner
;
3766 /* This is the address of the stub destination. */
3767 sym_value
= (stub_entry
->target_value
3768 + stub_entry
->target_section
->output_offset
3769 + stub_entry
->target_section
->output_section
->vma
);
3771 bfd_vma place
= (stub_entry
->stub_offset
+ stub_sec
->output_section
->vma
3772 + stub_sec
->output_offset
);
3774 if (stub_entry
->stub_type
== aarch64_stub_long_branch
)
3776 /* See if we can relax the stub. */
3777 if (aarch64_valid_for_adrp_p (sym_value
, place
))
3778 stub_entry
->stub_type
= aarch64_select_branch_stub (sym_value
, place
);
3781 if ((stub_entry
->stub_type
== aarch64_stub_branch_c64
3782 || stub_entry
->stub_type
== c64_stub_branch_aarch64
3783 || stub_entry
->stub_type
== c64_stub_branch_c64
)
3784 && !c64_valid_for_adrp_p (sym_value
, place
))
3787 (_("%s: stub target out of range for %s branch"),
3788 stub_entry
->output_name
,
3789 (stub_entry
->stub_type
== aarch64_stub_branch_c64
3790 ? "A64 to C64" : "C64 to A64"));
3791 bfd_set_error (bfd_error_bad_value
);
3795 switch (stub_entry
->stub_type
)
3797 case aarch64_stub_adrp_branch
:
3798 template = aarch64_adrp_branch_stub
;
3799 template_size
= sizeof (aarch64_adrp_branch_stub
);
3801 case aarch64_stub_long_branch
:
3802 template = aarch64_long_branch_stub
;
3803 template_size
= sizeof (aarch64_long_branch_stub
);
3805 case aarch64_stub_erratum_835769_veneer
:
3806 template = aarch64_erratum_835769_stub
;
3807 template_size
= sizeof (aarch64_erratum_835769_stub
);
3809 case aarch64_stub_erratum_843419_veneer
:
3810 template = aarch64_erratum_843419_stub
;
3811 template_size
= sizeof (aarch64_erratum_843419_stub
);
3813 case aarch64_stub_branch_c64
:
3814 template = aarch64_c64_branch_stub
;
3815 template_size
= sizeof (aarch64_c64_branch_stub
);
3817 case c64_stub_branch_aarch64
:
3818 case c64_stub_branch_c64
:
3819 template = c64_aarch64_branch_stub
;
3820 template_size
= sizeof (c64_aarch64_branch_stub
);
3826 for (i
= 0; i
< (template_size
/ sizeof template[0]); i
++)
3828 bfd_putl32 (template[i
], loc
);
3832 template_size
= (template_size
+ 7) & ~7;
3833 stub_sec
->size
+= template_size
;
3835 bfd_vma stub_offset
= stub_entry
->stub_offset
;
3837 switch (stub_entry
->stub_type
)
3839 case aarch64_stub_adrp_branch
:
3840 if (!aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21
), stub_bfd
, stub_sec
,
3841 stub_entry
->stub_offset
, sym_value
))
3842 /* The stub would not have been relaxed if the offset was out
3846 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
3847 stub_entry
->stub_offset
+ 4, sym_value
))
3851 case aarch64_stub_long_branch
:
3852 /* We want the value relative to the address 12 bytes back from the
3854 if (!aarch64_relocate (AARCH64_R (PRELNN
), stub_bfd
, stub_sec
,
3855 stub_entry
->stub_offset
+ 16, sym_value
+ 12))
3859 case aarch64_stub_erratum_835769_veneer
:
3860 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
3861 + stub_entry
->target_section
->output_offset
3862 + stub_entry
->target_value
;
3863 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
3864 + stub_entry
->stub_sec
->output_offset
3865 + stub_entry
->stub_offset
;
3866 branch_offset
= veneered_insn_loc
- veneer_entry_loc
;
3867 branch_offset
>>= 2;
3868 branch_offset
&= 0x3ffffff;
3869 bfd_putl32 (stub_entry
->veneered_insn
,
3870 stub_sec
->contents
+ stub_entry
->stub_offset
);
3871 bfd_putl32 (template[1] | branch_offset
,
3872 stub_sec
->contents
+ stub_entry
->stub_offset
+ 4);
3875 case aarch64_stub_erratum_843419_veneer
:
3876 if (!aarch64_relocate (AARCH64_R (JUMP26
), stub_bfd
, stub_sec
,
3877 stub_entry
->stub_offset
+ 4, sym_value
+ 4))
3881 case aarch64_stub_branch_c64
:
3884 case c64_stub_branch_aarch64
:
3885 case c64_stub_branch_c64
:
3886 if (!aarch64_relocate (R_MORELLO_ADR_PREL_PG_HI20
, stub_bfd
, stub_sec
,
3887 stub_offset
, sym_value
))
3888 /* We fail early if offset is out of range. */
3891 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC
), stub_bfd
, stub_sec
,
3892 stub_offset
+ 4, sym_value
))
3903 /* As above, but don't actually build the stub. Just bump offset so
3904 we know stub section sizes. */
3907 aarch64_size_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
3909 struct elf_aarch64_stub_hash_entry
*stub_entry
;
3910 struct elf_aarch64_link_hash_table
*htab
;
3913 /* Massage our args to the form they really have. */
3914 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
3915 htab
= (struct elf_aarch64_link_hash_table
*) in_arg
;
3917 switch (stub_entry
->stub_type
)
3919 case aarch64_stub_adrp_branch
:
3920 size
= sizeof (aarch64_adrp_branch_stub
);
3922 case aarch64_stub_long_branch
:
3923 size
= sizeof (aarch64_long_branch_stub
);
3925 case aarch64_stub_erratum_835769_veneer
:
3926 size
= sizeof (aarch64_erratum_835769_stub
);
3928 case aarch64_stub_erratum_843419_veneer
:
3930 if (htab
->fix_erratum_843419
== ERRAT_ADR
)
3932 size
= sizeof (aarch64_erratum_843419_stub
);
3935 case aarch64_stub_branch_c64
:
3936 size
= sizeof (aarch64_c64_branch_stub
);
3938 case c64_stub_branch_aarch64
:
3939 case c64_stub_branch_c64
:
3940 size
= sizeof (c64_aarch64_branch_stub
);
3946 size
= (size
+ 7) & ~7;
3947 stub_entry
->stub_sec
->size
+= size
;
3951 /* External entry points for sizing and building linker stubs. */
3953 /* Set up various things so that we can make a list of input sections
3954 for each output section included in the link. Returns -1 on error,
3955 0 when no stubs will be needed, and 1 on success. */
3958 elfNN_aarch64_setup_section_lists (bfd
*output_bfd
,
3959 struct bfd_link_info
*info
)
3962 unsigned int bfd_count
;
3963 unsigned int top_id
, top_index
;
3965 asection
**input_list
, **list
;
3967 struct elf_aarch64_link_hash_table
*htab
=
3968 elf_aarch64_hash_table (info
);
3970 if (!is_elf_hash_table (htab
))
3973 /* Count the number of input BFDs and find the top input section id. */
3974 for (input_bfd
= info
->input_bfds
, bfd_count
= 0, top_id
= 0;
3975 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
3978 for (section
= input_bfd
->sections
;
3979 section
!= NULL
; section
= section
->next
)
3981 if (top_id
< section
->id
)
3982 top_id
= section
->id
;
3985 htab
->bfd_count
= bfd_count
;
3987 amt
= sizeof (struct map_stub
) * (top_id
+ 1);
3988 htab
->stub_group
= bfd_zmalloc (amt
);
3989 if (htab
->stub_group
== NULL
)
3992 /* We can't use output_bfd->section_count here to find the top output
3993 section index as some sections may have been removed, and
3994 _bfd_strip_section_from_output doesn't renumber the indices. */
3995 for (section
= output_bfd
->sections
, top_index
= 0;
3996 section
!= NULL
; section
= section
->next
)
3998 if (top_index
< section
->index
)
3999 top_index
= section
->index
;
4002 htab
->top_index
= top_index
;
4003 amt
= sizeof (asection
*) * (top_index
+ 1);
4004 input_list
= bfd_malloc (amt
);
4005 htab
->input_list
= input_list
;
4006 if (input_list
== NULL
)
4009 /* For sections we aren't interested in, mark their entries with a
4010 value we can check later. */
4011 list
= input_list
+ top_index
;
4013 *list
= bfd_abs_section_ptr
;
4014 while (list
-- != input_list
);
4016 for (section
= output_bfd
->sections
;
4017 section
!= NULL
; section
= section
->next
)
4019 if ((section
->flags
& SEC_CODE
) != 0)
4020 input_list
[section
->index
] = NULL
;
4026 /* Used by elfNN_aarch64_next_input_section and group_sections. */
4027 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
4029 /* The linker repeatedly calls this function for each input section,
4030 in the order that input sections are linked into output sections.
4031 Build lists of input sections to determine groupings between which
4032 we may insert linker stubs. */
4035 elfNN_aarch64_next_input_section (struct bfd_link_info
*info
, asection
*isec
)
4037 struct elf_aarch64_link_hash_table
*htab
=
4038 elf_aarch64_hash_table (info
);
4040 if (isec
->output_section
->index
<= htab
->top_index
)
4042 asection
**list
= htab
->input_list
+ isec
->output_section
->index
;
4044 if (*list
!= bfd_abs_section_ptr
&& (isec
->flags
& SEC_CODE
) != 0)
4046 /* Steal the link_sec pointer for our list. */
4047 /* This happens to make the list in reverse order,
4048 which is what we want. */
4049 PREV_SEC (isec
) = *list
;
4055 /* See whether we can group stub sections together. Grouping stub
4056 sections may result in fewer stubs. More importantly, we need to
4057 put all .init* and .fini* stubs at the beginning of the .init or
4058 .fini output sections respectively, because glibc splits the
4059 _init and _fini functions into multiple parts. Putting a stub in
4060 the middle of a function is not a good idea. */
4063 group_sections (struct elf_aarch64_link_hash_table
*htab
,
4064 bfd_size_type stub_group_size
,
4065 bfd_boolean stubs_always_after_branch
)
4067 asection
**list
= htab
->input_list
;
4071 asection
*tail
= *list
;
4074 if (tail
== bfd_abs_section_ptr
)
4077 /* Reverse the list: we must avoid placing stubs at the
4078 beginning of the section because the beginning of the text
4079 section may be required for an interrupt vector in bare metal
4081 #define NEXT_SEC PREV_SEC
4083 while (tail
!= NULL
)
4085 /* Pop from tail. */
4086 asection
*item
= tail
;
4087 tail
= PREV_SEC (item
);
4090 NEXT_SEC (item
) = head
;
4094 while (head
!= NULL
)
4098 bfd_vma stub_group_start
= head
->output_offset
;
4099 bfd_vma end_of_next
;
4102 while (NEXT_SEC (curr
) != NULL
)
4104 next
= NEXT_SEC (curr
);
4105 end_of_next
= next
->output_offset
+ next
->size
;
4106 if (end_of_next
- stub_group_start
>= stub_group_size
)
4107 /* End of NEXT is too far from start, so stop. */
4109 /* Add NEXT to the group. */
4113 /* OK, the size from the start to the start of CURR is less
4114 than stub_group_size and thus can be handled by one stub
4115 section. (Or the head section is itself larger than
4116 stub_group_size, in which case we may be toast.)
4117 We should really be keeping track of the total size of
4118 stubs added here, as stubs contribute to the final output
4122 next
= NEXT_SEC (head
);
4123 /* Set up this stub group. */
4124 htab
->stub_group
[head
->id
].link_sec
= curr
;
4126 while (head
!= curr
&& (head
= next
) != NULL
);
4128 /* But wait, there's more! Input sections up to stub_group_size
4129 bytes after the stub section can be handled by it too. */
4130 if (!stubs_always_after_branch
)
4132 stub_group_start
= curr
->output_offset
+ curr
->size
;
4134 while (next
!= NULL
)
4136 end_of_next
= next
->output_offset
+ next
->size
;
4137 if (end_of_next
- stub_group_start
>= stub_group_size
)
4138 /* End of NEXT is too far from stubs, so stop. */
4140 /* Add NEXT to the stub group. */
4142 next
= NEXT_SEC (head
);
4143 htab
->stub_group
[head
->id
].link_sec
= curr
;
4149 while (list
++ != htab
->input_list
+ htab
->top_index
);
4151 free (htab
->input_list
);
4157 #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
4159 #define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
4160 #define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
4161 #define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
4162 #define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
4163 #define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
4164 #define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
4166 #define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
4167 #define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
4168 #define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
4169 #define AARCH64_ZR 0x1f
4171 /* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
4172 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
4174 #define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
4175 #define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
4176 #define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
4177 #define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
4178 #define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
4179 #define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
4180 #define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
4181 #define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
4182 #define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
4183 #define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
4184 #define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
4185 #define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
4186 #define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
4187 #define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
4188 #define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
4189 #define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
4190 #define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
4191 #define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
4193 /* Classify an INSN if it is indeed a load/store.
4195 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
4197 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
4200 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned. */
4203 aarch64_mem_op_p (uint32_t insn
, unsigned int *rt
, unsigned int *rt2
,
4204 bfd_boolean
*pair
, bfd_boolean
*load
)
4212 /* Bail out quickly if INSN doesn't fall into the load-store
4214 if (!AARCH64_LDST (insn
))
4219 if (AARCH64_LDST_EX (insn
))
4221 *rt
= AARCH64_RT (insn
);
4223 if (AARCH64_BIT (insn
, 21) == 1)
4226 *rt2
= AARCH64_RT2 (insn
);
4228 *load
= AARCH64_LD (insn
);
4231 else if (AARCH64_LDST_NAP (insn
)
4232 || AARCH64_LDSTP_PI (insn
)
4233 || AARCH64_LDSTP_O (insn
)
4234 || AARCH64_LDSTP_PRE (insn
))
4237 *rt
= AARCH64_RT (insn
);
4238 *rt2
= AARCH64_RT2 (insn
);
4239 *load
= AARCH64_LD (insn
);
4242 else if (AARCH64_LDST_PCREL (insn
)
4243 || AARCH64_LDST_UI (insn
)
4244 || AARCH64_LDST_PIIMM (insn
)
4245 || AARCH64_LDST_U (insn
)
4246 || AARCH64_LDST_PREIMM (insn
)
4247 || AARCH64_LDST_RO (insn
)
4248 || AARCH64_LDST_UIMM (insn
))
4250 *rt
= AARCH64_RT (insn
);
4252 if (AARCH64_LDST_PCREL (insn
))
4254 opc
= AARCH64_BITS (insn
, 22, 2);
4255 v
= AARCH64_BIT (insn
, 26);
4256 opc_v
= opc
| (v
<< 2);
4257 *load
= (opc_v
== 1 || opc_v
== 2 || opc_v
== 3
4258 || opc_v
== 5 || opc_v
== 7);
4261 else if (AARCH64_LDST_SIMD_M (insn
)
4262 || AARCH64_LDST_SIMD_M_PI (insn
))
4264 *rt
= AARCH64_RT (insn
);
4265 *load
= AARCH64_BIT (insn
, 22);
4266 opcode
= (insn
>> 12) & 0xf;
4293 else if (AARCH64_LDST_SIMD_S (insn
)
4294 || AARCH64_LDST_SIMD_S_PI (insn
))
4296 *rt
= AARCH64_RT (insn
);
4297 r
= (insn
>> 21) & 1;
4298 *load
= AARCH64_BIT (insn
, 22);
4299 opcode
= (insn
>> 13) & 0x7;
4311 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
4319 *rt2
= *rt
+ (r
== 0 ? 2 : 3);
4331 /* Return TRUE if INSN is multiply-accumulate. */
4334 aarch64_mlxl_p (uint32_t insn
)
4336 uint32_t op31
= AARCH64_OP31 (insn
);
4338 if (AARCH64_MAC (insn
)
4339 && (op31
== 0 || op31
== 1 || op31
== 5)
4340 /* Exclude MUL instructions which are encoded as a multiple accumulate
4342 && AARCH64_RA (insn
) != AARCH64_ZR
)
4348 /* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
4349 it is possible for a 64-bit multiply-accumulate instruction to generate an
4350 incorrect result. The details are quite complex and hard to
4351 determine statically, since branches in the code may exist in some
4352 circumstances, but all cases end with a memory (load, store, or
4353 prefetch) instruction followed immediately by the multiply-accumulate
4354 operation. We employ a linker patching technique, by moving the potentially
4355 affected multiply-accumulate instruction into a patch region and replacing
4356 the original instruction with a branch to the patch. This function checks
4357 if INSN_1 is the memory operation followed by a multiply-accumulate
4358 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
4359 if INSN_1 and INSN_2 are safe. */
4362 aarch64_erratum_sequence (uint32_t insn_1
, uint32_t insn_2
)
4372 if (aarch64_mlxl_p (insn_2
)
4373 && aarch64_mem_op_p (insn_1
, &rt
, &rt2
, &pair
, &load
))
4375 /* Any SIMD memory op is independent of the subsequent MLA
4376 by definition of the erratum. */
4377 if (AARCH64_BIT (insn_1
, 26))
4380 /* If not SIMD, check for integer memory ops and MLA relationship. */
4381 rn
= AARCH64_RN (insn_2
);
4382 ra
= AARCH64_RA (insn_2
);
4383 rm
= AARCH64_RM (insn_2
);
4385 /* If this is a load and there's a true(RAW) dependency, we are safe
4386 and this is not an erratum sequence. */
4388 (rt
== rn
|| rt
== rm
|| rt
== ra
4389 || (pair
&& (rt2
== rn
|| rt2
== rm
|| rt2
== ra
))))
4392 /* We conservatively put out stubs for all other cases (including
4402 _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes
)
4404 char *stub_name
= (char *) bfd_malloc
4405 (strlen ("__erratum_835769_veneer_") + 16);
4406 if (stub_name
!= NULL
)
4407 sprintf (stub_name
,"__erratum_835769_veneer_%d", num_fixes
);
4411 /* Scan for Cortex-A53 erratum 835769 sequence.
4413 Return TRUE else FALSE on abnormal termination. */
4416 _bfd_aarch64_erratum_835769_scan (bfd
*input_bfd
,
4417 struct bfd_link_info
*info
,
4418 unsigned int *num_fixes_p
)
4421 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4422 unsigned int num_fixes
= *num_fixes_p
;
4427 for (section
= input_bfd
->sections
;
4429 section
= section
->next
)
4431 bfd_byte
*contents
= NULL
;
4432 struct _aarch64_elf_section_data
*sec_data
;
4435 if (elf_section_type (section
) != SHT_PROGBITS
4436 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
4437 || (section
->flags
& SEC_EXCLUDE
) != 0
4438 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
4439 || (section
->output_section
== bfd_abs_section_ptr
))
4442 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
4443 contents
= elf_section_data (section
)->this_hdr
.contents
;
4444 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
4447 sec_data
= elf_aarch64_section_data (section
);
4449 if (sec_data
->mapcount
)
4450 qsort (sec_data
->map
, sec_data
->mapcount
,
4451 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
4453 for (span
= 0; span
< sec_data
->mapcount
; span
++)
4455 unsigned int span_start
= sec_data
->map
[span
].vma
;
4456 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
4457 ? sec_data
->map
[0].vma
+ section
->size
4458 : sec_data
->map
[span
+ 1].vma
);
4460 char span_type
= sec_data
->map
[span
].type
;
4462 if (span_type
== 'd')
4465 for (i
= span_start
; i
+ 4 < span_end
; i
+= 4)
4467 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
4468 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
4470 if (aarch64_erratum_sequence (insn_1
, insn_2
))
4472 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4473 char *stub_name
= _bfd_aarch64_erratum_835769_stub_name (num_fixes
);
4477 stub_entry
= _bfd_aarch64_add_stub_entry_in_group (stub_name
,
4483 stub_entry
->stub_type
= aarch64_stub_erratum_835769_veneer
;
4484 stub_entry
->target_section
= section
;
4485 stub_entry
->target_value
= i
+ 4;
4486 stub_entry
->veneered_insn
= insn_2
;
4487 stub_entry
->output_name
= stub_name
;
4492 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
4496 *num_fixes_p
= num_fixes
;
4502 /* Test if instruction INSN is ADRP. */
4505 _bfd_aarch64_adrp_p (uint32_t insn
)
4507 return ((insn
& AARCH64_ADRP_OP_MASK
) == AARCH64_ADRP_OP
);
4511 /* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
4514 _bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1
, uint32_t insn_2
,
4522 return (aarch64_mem_op_p (insn_2
, &rt
, &rt2
, &pair
, &load
)
4525 && AARCH64_LDST_UIMM (insn_3
)
4526 && AARCH64_RN (insn_3
) == AARCH64_RD (insn_1
));
4530 /* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
4532 Return TRUE if section CONTENTS at offset I contains one of the
4533 erratum 843419 sequences, otherwise return FALSE. If a sequence is
4534 seen set P_VENEER_I to the offset of the final LOAD/STORE
4535 instruction in the sequence.
4539 _bfd_aarch64_erratum_843419_p (bfd_byte
*contents
, bfd_vma vma
,
4540 bfd_vma i
, bfd_vma span_end
,
4541 bfd_vma
*p_veneer_i
)
4543 uint32_t insn_1
= bfd_getl32 (contents
+ i
);
4545 if (!_bfd_aarch64_adrp_p (insn_1
))
4548 if (span_end
< i
+ 12)
4551 uint32_t insn_2
= bfd_getl32 (contents
+ i
+ 4);
4552 uint32_t insn_3
= bfd_getl32 (contents
+ i
+ 8);
4554 if ((vma
& 0xfff) != 0xff8 && (vma
& 0xfff) != 0xffc)
4557 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_3
))
4559 *p_veneer_i
= i
+ 8;
4563 if (span_end
< i
+ 16)
4566 uint32_t insn_4
= bfd_getl32 (contents
+ i
+ 12);
4568 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1
, insn_2
, insn_4
))
4570 *p_veneer_i
= i
+ 12;
4578 /* Resize all stub sections. */
4581 _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table
*htab
)
4585 /* OK, we've added some stubs. Find out the new size of the
4587 for (section
= htab
->stub_bfd
->sections
;
4588 section
!= NULL
; section
= section
->next
)
4590 /* Ignore non-stub sections. */
4591 if (!strstr (section
->name
, STUB_SUFFIX
))
4596 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_size_one_stub
, htab
);
4598 for (section
= htab
->stub_bfd
->sections
;
4599 section
!= NULL
; section
= section
->next
)
4601 if (!strstr (section
->name
, STUB_SUFFIX
))
4604 /* Add space for a branch. Add 8 bytes to keep section 8 byte aligned,
4605 as long branch stubs contain a 64-bit address. */
4609 /* Ensure all stub sections have a size which is a multiple of
4610 4096. This is important in order to ensure that the insertion
4611 of stub sections does not in itself move existing code around
4612 in such a way that new errata sequences are created. We only do this
4613 when the ADRP workaround is enabled. If only the ADR workaround is
4614 enabled then the stubs workaround won't ever be used. */
4615 if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
4617 section
->size
= BFD_ALIGN (section
->size
, 0x1000);
4621 /* Construct an erratum 843419 workaround stub name. */
4624 _bfd_aarch64_erratum_843419_stub_name (asection
*input_section
,
4627 const bfd_size_type len
= 8 + 4 + 1 + 8 + 1 + 16 + 1;
4628 char *stub_name
= bfd_malloc (len
);
4630 if (stub_name
!= NULL
)
4631 snprintf (stub_name
, len
, "e843419@%04x_%08x_%" BFD_VMA_FMT
"x",
4632 input_section
->owner
->id
,
4638 /* Build a stub_entry structure describing an 843419 fixup.
4640 The stub_entry constructed is populated with the bit pattern INSN
4641 of the instruction located at OFFSET within input SECTION.
4643 Returns TRUE on success. */
4646 _bfd_aarch64_erratum_843419_fixup (uint32_t insn
,
4647 bfd_vma adrp_offset
,
4648 bfd_vma ldst_offset
,
4650 struct bfd_link_info
*info
)
4652 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4654 struct elf_aarch64_stub_hash_entry
*stub_entry
;
4656 stub_name
= _bfd_aarch64_erratum_843419_stub_name (section
, ldst_offset
);
4657 if (stub_name
== NULL
)
4659 stub_entry
= aarch64_stub_hash_lookup (&htab
->stub_hash_table
, stub_name
,
4667 /* We always place an 843419 workaround veneer in the stub section
4668 attached to the input section in which an erratum sequence has
4669 been found. This ensures that later in the link process (in
4670 elfNN_aarch64_write_section) when we copy the veneered
4671 instruction from the input section into the stub section the
4672 copied instruction will have had any relocations applied to it.
4673 If we placed workaround veneers in any other stub section then we
4674 could not assume that all relocations have been processed on the
4675 corresponding input section at the point we output the stub
4678 stub_entry
= _bfd_aarch64_add_stub_entry_after (stub_name
, section
, htab
);
4679 if (stub_entry
== NULL
)
4685 stub_entry
->adrp_offset
= adrp_offset
;
4686 stub_entry
->target_value
= ldst_offset
;
4687 stub_entry
->target_section
= section
;
4688 stub_entry
->stub_type
= aarch64_stub_erratum_843419_veneer
;
4689 stub_entry
->veneered_insn
= insn
;
4690 stub_entry
->output_name
= stub_name
;
4696 /* Scan an input section looking for the signature of erratum 843419.
4698 Scans input SECTION in INPUT_BFD looking for erratum 843419
4699 signatures, for each signature found a stub_entry is created
4700 describing the location of the erratum for subsequent fixup.
4702 Return TRUE on successful scan, FALSE on failure to scan.
4706 _bfd_aarch64_erratum_843419_scan (bfd
*input_bfd
, asection
*section
,
4707 struct bfd_link_info
*info
)
4709 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4714 if (elf_section_type (section
) != SHT_PROGBITS
4715 || (elf_section_flags (section
) & SHF_EXECINSTR
) == 0
4716 || (section
->flags
& SEC_EXCLUDE
) != 0
4717 || (section
->sec_info_type
== SEC_INFO_TYPE_JUST_SYMS
)
4718 || (section
->output_section
== bfd_abs_section_ptr
))
4723 bfd_byte
*contents
= NULL
;
4724 struct _aarch64_elf_section_data
*sec_data
;
4727 if (elf_section_data (section
)->this_hdr
.contents
!= NULL
)
4728 contents
= elf_section_data (section
)->this_hdr
.contents
;
4729 else if (! bfd_malloc_and_get_section (input_bfd
, section
, &contents
))
4732 sec_data
= elf_aarch64_section_data (section
);
4734 if (sec_data
->mapcount
)
4735 qsort (sec_data
->map
, sec_data
->mapcount
,
4736 sizeof (elf_aarch64_section_map
), elf_aarch64_compare_mapping
);
4738 for (span
= 0; span
< sec_data
->mapcount
; span
++)
4740 unsigned int span_start
= sec_data
->map
[span
].vma
;
4741 unsigned int span_end
= ((span
== sec_data
->mapcount
- 1)
4742 ? sec_data
->map
[0].vma
+ section
->size
4743 : sec_data
->map
[span
+ 1].vma
);
4745 char span_type
= sec_data
->map
[span
].type
;
4747 if (span_type
== 'd')
4750 for (i
= span_start
; i
+ 8 < span_end
; i
+= 4)
4752 bfd_vma vma
= (section
->output_section
->vma
4753 + section
->output_offset
4757 if (_bfd_aarch64_erratum_843419_p
4758 (contents
, vma
, i
, span_end
, &veneer_i
))
4760 uint32_t insn
= bfd_getl32 (contents
+ veneer_i
);
4762 if (!_bfd_aarch64_erratum_843419_fixup (insn
, i
, veneer_i
,
4769 if (elf_section_data (section
)->this_hdr
.contents
== NULL
)
4778 section_start_symbol (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*section
,
4781 return section
->vma
== *(bfd_vma
*)valp
;
4784 /* Capability format functions. */
4787 exponent (uint64_t len
)
4789 #define CAP_MAX_EXPONENT 50
4790 /* Size is a 65 bit value, so there's an implicit 0 MSB. */
4791 unsigned zeroes
= __builtin_clzl (len
) + 1;
4793 /* All bits up to and including CAP_MW - 2 are zero. */
4794 if (CAP_MAX_EXPONENT
< zeroes
)
4795 return (unsigned) -1;
4797 return CAP_MAX_EXPONENT
- zeroes
;
4798 #undef CAP_MAX_EXPONENT
4801 #define ONES(x) ((1ULL << (x)) - 1)
4802 #define ALIGN_UP(x, a) (((x) + ONES (a)) & (~ONES (a)))
4805 c64_valid_cap_range (bfd_vma
*basep
, bfd_vma
*limitp
, unsigned *alignmentp
)
4807 bfd_vma base
= *basep
, size
= *limitp
- *basep
;
4812 if ((e
= exponent (size
)) == (unsigned) -1)
4815 size
= ALIGN_UP (size
, e
+ 3);
4817 e
= exponent (size
);
4819 size
= ALIGN_UP (size
, e
+ 3);
4821 base
= ALIGN_UP (base
, e
+ 3);
4824 if (base
== *basep
&& *limitp
== base
+ size
)
4828 *limitp
= base
+ size
;
4832 /* Check if the bounds of section SEC will get rounded off in the Morello
4833 capability format and if it would, adjust the section to ensure any
4834 capability spanning this section would have its bounds precise. */
4836 ensure_precisely_bounded_section (asection
*sec
,
4837 struct elf_aarch64_link_hash_table
*htab
,
4838 void (*c64_pad_section
) (asection
*, bfd_vma
))
4840 bfd_vma low
= sec
->vma
;
4841 bfd_vma high
= sec
->vma
+ sec
->size
;
4844 bfd_boolean did_change
= FALSE
;
4845 if (!c64_valid_cap_range (&low
, &high
, &alignment
))
4847 bfd_vma padding
= high
- low
- sec
->size
;
4848 c64_pad_section (sec
, padding
);
4851 if (sec
->alignment_power
< alignment
)
4853 sec
->alignment_power
= alignment
;
4858 (*htab
->layout_sections_again
) ();
4861 /* Make sure that all capabilities that refer to sections have bounds that
4862 won't overlap with neighbouring sections. This is needed in two specific
4863 cases. The first case is that of PCC, which needs to span across all
4864 readonly sections as well as the GOT and PLT sections in the output binary.
4865 The second case is that of linker and ldscript defined symbols that indicate
4866 start and/or end of sections and/or zero-sized symbols.
4868 In both cases, overlap of capability bounds are avoided by aligning the base
4869 of the section and if necessary, adding a pad at the end of the section so
4870 that the section following it starts only after the pad. */
4872 static bfd_vma pcc_low
;
4873 static bfd_vma pcc_high
;
4875 elfNN_c64_resize_sections (bfd
*output_bfd
, struct bfd_link_info
*info
,
4876 void (*c64_pad_section
) (asection
*, bfd_vma
),
4877 void (*layout_sections_again
) (void))
4880 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
4884 htab
->layout_sections_again
= layout_sections_again
;
4886 /* If this is not a PURECAP binary, and has no C64 code in it, then this is
4887 just a stock AArch64 binary and the section padding is not necessary.
4888 We can have PURECAP shared libraries that are data-only, so just checking
4889 if there is C64 code in this executable is not enough. We can have HYBRID
4890 binaries, so just checking for PURECAP is not enough. */
4891 if (!(htab
->c64_output
4892 || (elf_elfheader (output_bfd
)->e_flags
& EF_AARCH64_CHERI_PURECAP
)))
4895 /* First, walk through all the relocations to find those referring to linker
4896 defined and ldscript defined symbols since we set their range to their
4898 for (input_bfd
= info
->input_bfds
;
4899 /* No point iterating over all relocations to ensure each section that
4900 needs to give the bounds for a capability is padded accordingly if
4901 there are no capability relocations in the GOT and there are no
4902 CAPINIT relocations.
4903 N.b. It is possible that when creating a dynamic object a
4904 section-spanning symbol could be used by some other executable
4905 linking to it when we don't have a relocation to it in the given
4906 dynamic library. Rather than pad every section which has a linker
4907 defined symbol pointing into it we choose to allow such use-cases to
4908 have sizes which bleed into another section. */
4909 (htab
->c64_rel
|| htab
->srelcaps
) && input_bfd
!= NULL
;
4910 input_bfd
= input_bfd
->link
.next
)
4912 Elf_Internal_Shdr
*symtab_hdr
;
4914 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4915 if (symtab_hdr
->sh_info
== 0)
4918 for (sec
= input_bfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
4920 Elf_Internal_Rela
*irelaend
, *irela
;
4922 /* If there aren't any relocs, then there's nothing more to do. */
4923 if ((sec
->flags
& SEC_RELOC
) == 0 || sec
->reloc_count
== 0)
4926 irela
= _bfd_elf_link_read_relocs (input_bfd
, sec
, NULL
, NULL
,
4931 /* Now examine each relocation. */
4932 irelaend
= irela
+ sec
->reloc_count
;
4933 for (; irela
< irelaend
; irela
++)
4935 unsigned int r_indx
;
4936 struct elf_link_hash_entry
*h
;
4940 r_indx
= ELFNN_R_SYM (irela
->r_info
);
4942 /* Linker defined or linker script defined symbols are always in
4944 if (r_indx
< symtab_hdr
->sh_info
)
4947 e_indx
= r_indx
- symtab_hdr
->sh_info
;
4948 h
= elf_sym_hashes (input_bfd
)[e_indx
];
4950 /* XXX Does this ever happen? */
4954 os
= h
->root
.u
.def
.section
->output_section
;
4956 if (h
->root
.linker_def
)
4957 ensure_precisely_bounded_section (os
, htab
, c64_pad_section
);
4958 else if (h
->root
.ldscript_def
)
4960 const char *name
= h
->root
.root
.string
;
4961 size_t len
= strlen (name
);
4962 asection
*altos
= NULL
;
4963 bfd_vma value
= os
->vma
+ os
->size
;
4965 if (len
> 8 && name
[0] == '_' && name
[1] == '_'
4966 && (!strncmp (name
+ 2, "start_", 6)
4967 || !strcmp (name
+ len
- 6, "_start"))
4968 && ((altos
= bfd_sections_find_if
4969 (info
->output_bfd
, section_start_symbol
, &value
))
4971 ensure_precisely_bounded_section (altos
, htab
,
4973 /* XXX We're overfitting here because the offset of H within
4974 the output section is not yet resolved and ldscript
4975 defined symbols do not have input section information. */
4976 ensure_precisely_bounded_section (os
, htab
, c64_pad_section
);
4982 /* Next, walk through output sections to find the PCC span and add a padding
4983 at the end to ensure that PCC bounds don't bleed into neighbouring
4984 sections. For now PCC needs to encompass all code sections, .got, .plt
4986 If there is no C64 code in this binary, then we do not need to care about
4987 PCC bounds, hence skip this bit.
4988 It's tempting to also avoid padding the PCC range when we have no static
4989 relocations in this binary, since it would seem that we can never end up
4990 trying to access something "outside" the PCC bounds (any PCC bounded
4991 capability provided to an outside dynamic object would be sealed by the
4992 runtime, and hence can't be offset). Unfortunately it is still possible,
4993 since an `adr c0, 0` gives an unsealed capability to the current code
4994 which could then be offset by some other means.
4995 While that seems unlikely to happen, having no relocations in a file also
4996 seems quite unlikely, so we may as well play it safe. */
4997 if (!htab
->c64_output
)
5000 bfd_vma low
= (bfd_vma
) -1, high
= 0;
5001 asection
*pcc_low_sec
= NULL
, *pcc_high_sec
= NULL
;
5002 for (sec
= output_bfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
5004 /* XXX This is a good place to figure out if there are any readable or
5005 writable sections in the PCC range that are not in the list of
5006 sections we want the PCC to span and then warn the user of it. */
5008 #define NOT_OP_SECTION(s) ((s) == NULL || (s)->output_section != sec)
5010 if ((sec
->flags
& SEC_READONLY
) == 0
5011 && NOT_OP_SECTION (htab
->root
.sgotplt
)
5012 && NOT_OP_SECTION (htab
->root
.igotplt
)
5013 && NOT_OP_SECTION (htab
->root
.sgot
)
5014 && NOT_OP_SECTION (htab
->root
.splt
)
5015 && NOT_OP_SECTION (htab
->root
.iplt
)
5016 && (sec
->vma
< info
->relro_start
5017 || sec
->vma
>= info
->relro_end
))
5019 if ((sec
->flags
& SEC_ALLOC
) == 0)
5027 if (sec
->vma
+ sec
->size
> high
)
5029 high
= sec
->vma
+ sec
->size
;
5033 #undef NOT_OP_SECTION
5036 /* Set the PCC range to have precise bounds to ensure that PCC relative loads
5037 can not access outside of their given range. */
5038 if (pcc_low_sec
!= NULL
)
5040 BFD_ASSERT (pcc_high_sec
);
5042 bfd_vma pcc_low_tmp
;
5043 bfd_vma pcc_high_tmp
;
5045 /* We have to be a little careful about the padding we introduce. The
5046 padding we could calculate here may not be the padding that we would
5047 want after the very first section in the PCC bounds has been aligned
5048 properly. That change in the start address propagated through a few
5049 different sections with their own alignment requirements can easily
5050 change the length of the region we want the PCC to span.
5051 Also, that change in length could change the alignment we want. We
5052 don't proove that the alignment requirement converges, but believe
5053 that it should (there is only so much space that existing alignment
5054 requirements could trigger to be added -- a section with an alignment
5055 requirement of 16 can only really add 15 bytes to the length). */
5056 bfd_boolean valid_range
= FALSE
;
5058 pcc_low_tmp
= pcc_low_sec
->vma
;
5059 pcc_high_tmp
= pcc_high_sec
->vma
+ pcc_high_sec
->size
;
5061 c64_valid_cap_range (&pcc_low_tmp
, &pcc_high_tmp
, &align
);
5062 if (pcc_low_sec
->alignment_power
>= align
)
5064 pcc_low_sec
->alignment_power
= align
;
5065 (*htab
->layout_sections_again
) ();
5068 /* We have calculated the bottom and top address that we want in the
5069 above call to c64_valid_cap_range. We have also aligned the lowest
5070 section in the PCC range to where we want it. Just have to add the
5071 padding remaining if needs be. */
5074 BFD_ASSERT (pcc_low_tmp
== pcc_low_sec
->vma
);
5075 bfd_vma current_length
=
5076 (pcc_high_sec
->vma
+ pcc_high_sec
->size
) - pcc_low_sec
->vma
;
5077 bfd_vma desired_length
= (pcc_high_tmp
- pcc_low_tmp
);
5078 bfd_vma padding
= desired_length
- current_length
;
5079 c64_pad_section (pcc_high_sec
, padding
);
5080 (*htab
->layout_sections_again
) ();
5083 pcc_low
= pcc_low_sec
->vma
;
5084 pcc_high
= pcc_high_sec
->vma
+ pcc_high_sec
->size
;
5088 /* Determine and set the size of the stub section for a final link.
5090 The basic idea here is to examine all the relocations looking for
5091 PC-relative calls to a target that either needs a PE state change (A64 to
5092 C64 or vice versa) or in case of unconditional branches (B/BL), is
5096 elfNN_aarch64_size_stubs (bfd
*output_bfd
,
5098 struct bfd_link_info
*info
,
5099 bfd_signed_vma group_size
,
5100 asection
* (*add_stub_section
) (const char *,
5102 void (*layout_sections_again
) (void))
5104 bfd_size_type stub_group_size
;
5105 bfd_boolean stubs_always_before_branch
;
5106 bfd_boolean stub_changed
= FALSE
;
5107 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
5108 unsigned int num_erratum_835769_fixes
= 0;
5110 /* Propagate mach to stub bfd, because it may not have been
5111 finalized when we created stub_bfd. */
5112 bfd_set_arch_mach (stub_bfd
, bfd_get_arch (output_bfd
),
5113 bfd_get_mach (output_bfd
));
5115 /* Stash our params away. */
5116 htab
->stub_bfd
= stub_bfd
;
5117 htab
->add_stub_section
= add_stub_section
;
5118 htab
->layout_sections_again
= layout_sections_again
;
5119 stubs_always_before_branch
= group_size
< 0;
5121 stub_group_size
= -group_size
;
5123 stub_group_size
= group_size
;
5125 if (stub_group_size
== 1)
5127 /* Default values. */
5128 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
5129 stub_group_size
= 127 * 1024 * 1024;
5132 group_sections (htab
, stub_group_size
, stubs_always_before_branch
);
5134 (*htab
->layout_sections_again
) ();
5136 if (htab
->fix_erratum_835769
)
5140 for (input_bfd
= info
->input_bfds
;
5141 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
5143 if (!is_aarch64_elf (input_bfd
)
5144 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
5147 if (!_bfd_aarch64_erratum_835769_scan (input_bfd
, info
,
5148 &num_erratum_835769_fixes
))
5152 _bfd_aarch64_resize_stubs (htab
);
5153 (*htab
->layout_sections_again
) ();
5156 if (htab
->fix_erratum_843419
!= ERRAT_NONE
)
5160 for (input_bfd
= info
->input_bfds
;
5162 input_bfd
= input_bfd
->link
.next
)
5166 if (!is_aarch64_elf (input_bfd
)
5167 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
5170 for (section
= input_bfd
->sections
;
5172 section
= section
->next
)
5173 if (!_bfd_aarch64_erratum_843419_scan (input_bfd
, section
, info
))
5177 _bfd_aarch64_resize_stubs (htab
);
5178 (*htab
->layout_sections_again
) ();
5185 for (input_bfd
= info
->input_bfds
;
5186 input_bfd
!= NULL
; input_bfd
= input_bfd
->link
.next
)
5188 Elf_Internal_Shdr
*symtab_hdr
;
5191 if (!is_aarch64_elf (input_bfd
)
5192 || (input_bfd
->flags
& BFD_LINKER_CREATED
) != 0)
5195 /* We'll need the symbol table in a second. */
5196 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
5197 if (symtab_hdr
->sh_info
== 0)
5200 /* Walk over each section attached to the input bfd. */
5201 for (section
= input_bfd
->sections
;
5202 section
!= NULL
; section
= section
->next
)
5204 Elf_Internal_Rela
*internal_relocs
, *irelaend
, *irela
;
5206 /* If there aren't any relocs, then there's nothing more
5208 if ((section
->flags
& SEC_RELOC
) == 0
5209 || section
->reloc_count
== 0
5210 || (section
->flags
& SEC_CODE
) == 0)
5213 /* If this section is a link-once section that will be
5214 discarded, then don't create any stubs. */
5215 if (section
->output_section
== NULL
5216 || section
->output_section
->owner
!= output_bfd
)
5219 /* Get the relocs. */
5221 = _bfd_elf_link_read_relocs (input_bfd
, section
, NULL
,
5222 NULL
, info
->keep_memory
);
5223 if (internal_relocs
== NULL
)
5224 goto error_ret_free_local
;
5226 /* Now examine each relocation. */
5227 irela
= internal_relocs
;
5228 irelaend
= irela
+ section
->reloc_count
;
5229 for (; irela
< irelaend
; irela
++)
5231 unsigned int r_type
, r_indx
;
5232 enum elf_aarch64_stub_type stub_type
= aarch64_stub_none
;
5233 struct elf_aarch64_stub_hash_entry
*stub_entry
;
5236 bfd_vma destination
;
5237 struct elf_aarch64_link_hash_entry
*hash
;
5238 const char *sym_name
;
5240 const asection
*id_sec
;
5241 unsigned char st_type
;
5243 unsigned branch_to_c64
= FALSE
;
5246 r_type
= ELFNN_R_TYPE (irela
->r_info
);
5247 r_indx
= ELFNN_R_SYM (irela
->r_info
);
5249 if (r_type
>= (unsigned int) R_AARCH64_end
)
5251 bfd_set_error (bfd_error_bad_value
);
5252 error_ret_free_internal
:
5253 if (elf_section_data (section
)->relocs
== NULL
)
5254 free (internal_relocs
);
5255 goto error_ret_free_local
;
5258 /* Only look for stubs on unconditional branch and
5259 branch and link instructions. */
5260 if (!aarch64_branch_reloc_p (r_type
))
5263 /* Now determine the call target, its name, value,
5270 if (r_indx
< symtab_hdr
->sh_info
)
5272 /* It's a local symbol. */
5273 Elf_Internal_Sym
*sym
=
5274 bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
5277 goto error_ret_free_internal
;
5279 branch_to_c64
|= (sym
->st_target_internal
5280 & ST_BRANCH_TO_C64
);
5282 Elf_Internal_Shdr
*hdr
=
5283 elf_elfsections (input_bfd
)[sym
->st_shndx
];
5285 sym_sec
= hdr
->bfd_section
;
5287 /* This is an undefined symbol. It can never
5291 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
5292 sym_value
= sym
->st_value
;
5293 destination
= (sym_value
+ irela
->r_addend
5294 + sym_sec
->output_offset
5295 + sym_sec
->output_section
->vma
);
5296 st_type
= ELF_ST_TYPE (sym
->st_info
);
5298 = bfd_elf_string_from_elf_section (input_bfd
,
5299 symtab_hdr
->sh_link
,
5302 /* Get the interworking stub if needed. */
5303 stub_type
= aarch64_interwork_stub (r_type
,
5309 struct elf_aarch64_link_hash_table
*globals
=
5310 elf_aarch64_hash_table (info
);
5312 e_indx
= r_indx
- symtab_hdr
->sh_info
;
5313 hash
= ((struct elf_aarch64_link_hash_entry
*)
5314 elf_sym_hashes (input_bfd
)[e_indx
]);
5316 while (hash
->root
.root
.type
== bfd_link_hash_indirect
5317 || hash
->root
.root
.type
== bfd_link_hash_warning
)
5318 hash
= ((struct elf_aarch64_link_hash_entry
*)
5319 hash
->root
.root
.u
.i
.link
);
5321 /* Static executable. */
5322 if (globals
->root
.splt
== NULL
|| hash
== NULL
5323 || hash
->root
.plt
.offset
== (bfd_vma
) - 1)
5325 branch_to_c64
|= (hash
->root
.target_internal
5326 & ST_BRANCH_TO_C64
);
5327 stub_type
= aarch64_interwork_stub (r_type
,
5331 if (hash
->root
.root
.type
== bfd_link_hash_defined
5332 || hash
->root
.root
.type
== bfd_link_hash_defweak
)
5334 sym_sec
= hash
->root
.root
.u
.def
.section
;
5335 sym_value
= hash
->root
.root
.u
.def
.value
;
5336 /* For a destination in a shared library,
5337 use the PLT stub as target address to
5338 decide whether a branch stub is
5340 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
5341 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
5343 sym_sec
= globals
->root
.splt
;
5344 sym_value
= hash
->root
.plt
.offset
;
5345 if (sym_sec
->output_section
!= NULL
)
5346 destination
= (sym_value
5347 + sym_sec
->output_offset
5349 sym_sec
->output_section
->vma
);
5351 else if (sym_sec
->output_section
!= NULL
)
5352 destination
= (sym_value
+ irela
->r_addend
5353 + sym_sec
->output_offset
5354 + sym_sec
->output_section
->vma
);
5356 else if (hash
->root
.root
.type
== bfd_link_hash_undefined
5357 || (hash
->root
.root
.type
5358 == bfd_link_hash_undefweak
))
5360 /* For a shared library, use the PLT stub as
5361 target address to decide whether a long
5362 branch stub is needed.
5363 For absolute code, they cannot be handled. */
5365 if (globals
->root
.splt
!= NULL
&& hash
!= NULL
5366 && hash
->root
.plt
.offset
!= (bfd_vma
) - 1)
5368 sym_sec
= globals
->root
.splt
;
5369 sym_value
= hash
->root
.plt
.offset
;
5370 if (sym_sec
->output_section
!= NULL
)
5371 destination
= (sym_value
5372 + sym_sec
->output_offset
5374 sym_sec
->output_section
->vma
);
5381 bfd_set_error (bfd_error_bad_value
);
5382 goto error_ret_free_internal
;
5384 st_type
= ELF_ST_TYPE (hash
->root
.type
);
5385 sym_name
= hash
->root
.root
.root
.string
;
5388 /* Determine what (if any) linker stub is needed. */
5389 if (stub_type
== aarch64_stub_none
)
5390 stub_type
= aarch64_type_of_stub (section
, irela
, sym_sec
,
5391 st_type
, destination
);
5393 if (stub_type
== aarch64_stub_none
)
5396 /* Support for grouping stub sections. */
5397 id_sec
= htab
->stub_group
[section
->id
].link_sec
;
5399 /* Get the name of this stub. */
5400 stub_name
= elfNN_aarch64_stub_name (id_sec
, sym_sec
, hash
,
5403 goto error_ret_free_internal
;
5406 aarch64_stub_hash_lookup (&htab
->stub_hash_table
,
5407 stub_name
, FALSE
, FALSE
);
5408 if (stub_entry
!= NULL
)
5410 /* The proper stub has already been created. */
5412 /* Always update this stub's target since it may have
5413 changed after layout. */
5414 stub_entry
->target_value
= sym_value
+ irela
->r_addend
;
5416 /* Set LSB for A64 to C64 branch. */
5418 stub_entry
->target_value
|= 1;
5423 stub_entry
= _bfd_aarch64_add_stub_entry_in_group
5424 (stub_name
, section
, htab
);
5425 if (stub_entry
== NULL
)
5428 goto error_ret_free_internal
;
5431 stub_entry
->target_value
= sym_value
+ irela
->r_addend
;
5432 /* Set LSB for A64 to C64 branch. */
5434 stub_entry
->target_value
|= 1;
5436 stub_entry
->target_section
= sym_sec
;
5437 stub_entry
->stub_type
= stub_type
;
5438 stub_entry
->h
= hash
;
5439 stub_entry
->st_type
= st_type
;
5441 suffix
= aarch64_lookup_stub_type_suffix (stub_type
);
5443 if (sym_name
== NULL
)
5444 sym_name
= "unnamed";
5445 len
= (sizeof (STUB_ENTRY_NAME
) + strlen (sym_name
)
5447 stub_entry
->output_name
= bfd_alloc (htab
->stub_bfd
, len
);
5448 if (stub_entry
->output_name
== NULL
)
5451 goto error_ret_free_internal
;
5454 snprintf (stub_entry
->output_name
, len
, STUB_ENTRY_NAME
,
5457 stub_changed
= TRUE
;
5460 /* We're done with the internal relocs, free them. */
5461 if (elf_section_data (section
)->relocs
== NULL
)
5462 free (internal_relocs
);
5469 _bfd_aarch64_resize_stubs (htab
);
5471 /* Ask the linker to do its stuff. */
5472 (*htab
->layout_sections_again
) ();
5473 stub_changed
= FALSE
;
5478 error_ret_free_local
:
5482 /* Build all the stubs associated with the current output file. The
5483 stubs are kept in a hash table attached to the main linker hash
5484 table. We also set up the .plt entries for statically linked PIC
5485 functions here. This function is called via aarch64_elf_finish in the
5489 elfNN_aarch64_build_stubs (struct bfd_link_info
*info
)
5492 struct bfd_hash_table
*table
;
5493 struct elf_aarch64_link_hash_table
*htab
;
5495 htab
= elf_aarch64_hash_table (info
);
5497 for (stub_sec
= htab
->stub_bfd
->sections
;
5498 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
5502 /* Ignore non-stub sections. */
5503 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
5506 /* Allocate memory to hold the linker stubs. */
5507 size
= stub_sec
->size
;
5508 stub_sec
->contents
= bfd_zalloc (htab
->stub_bfd
, size
);
5509 if (stub_sec
->contents
== NULL
&& size
!= 0)
5513 /* Add a branch around the stub section, and a nop, to keep it 8 byte
5514 aligned, as long branch stubs contain a 64-bit address. */
5515 bfd_putl32 (0x14000000 | (size
>> 2), stub_sec
->contents
);
5516 bfd_putl32 (INSN_NOP
, stub_sec
->contents
+ 4);
5517 stub_sec
->size
+= 8;
5520 /* Build the stubs as directed by the stub hash table. */
5521 table
= &htab
->stub_hash_table
;
5523 bfd_error_type save_error
= bfd_get_error ();
5524 bfd_set_error (bfd_error_no_error
);
5525 bfd_hash_traverse (table
, aarch64_build_one_stub
, info
);
5527 if (bfd_get_error () != bfd_error_no_error
)
5530 bfd_set_error (save_error
);
5536 /* Add an entry to the code/data map for section SEC. */
5539 elfNN_aarch64_section_map_add (bfd
*abfd
, asection
*sec
, char type
,
5542 struct _aarch64_elf_section_data
*sec_data
=
5543 elf_aarch64_section_data (sec
);
5544 unsigned int newidx
;
5546 /* The aarch64 section hook was not called for this section. */
5547 if (!sec_data
->elf
.is_target_section_data
)
5549 struct _aarch64_elf_section_data
*newdata
=
5550 bfd_zalloc (abfd
, sizeof (*newdata
));
5552 if (newdata
== NULL
)
5555 newdata
->elf
= sec_data
->elf
;
5556 newdata
->elf
.is_target_section_data
= TRUE
;
5558 sec
->used_by_bfd
= sec_data
= newdata
;
5561 if (sec_data
->map
== NULL
)
5563 sec_data
->map
= bfd_malloc (sizeof (elf_aarch64_section_map
));
5564 sec_data
->mapcount
= 0;
5565 sec_data
->mapsize
= 1;
5568 newidx
= sec_data
->mapcount
++;
5570 if (sec_data
->mapcount
> sec_data
->mapsize
)
5572 sec_data
->mapsize
*= 2;
5573 sec_data
->map
= bfd_realloc_or_free
5574 (sec_data
->map
, sec_data
->mapsize
* sizeof (elf_aarch64_section_map
));
5579 sec_data
->map
[newidx
].vma
= vma
;
5580 sec_data
->map
[newidx
].type
= type
;
5585 /* Initialise maps of insn/data for input BFDs. */
5587 bfd_elfNN_aarch64_init_maps (bfd
*abfd
, struct bfd_link_info
*info
)
5589 Elf_Internal_Sym
*isymbuf
;
5590 Elf_Internal_Shdr
*hdr
;
5591 unsigned int i
, localsyms
;
5593 /* Make sure that we are dealing with an AArch64 elf binary. */
5594 if (!is_aarch64_elf (abfd
))
5597 if (elf_aarch64_tdata (abfd
)->secmaps_initialised
)
5600 if ((abfd
->flags
& DYNAMIC
) != 0)
5603 hdr
= &elf_symtab_hdr (abfd
);
5604 localsyms
= hdr
->sh_info
;
5606 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
5607 should contain the number of local symbols, which should come before any
5608 global symbols. Mapping symbols are always local. */
5609 isymbuf
= bfd_elf_get_elf_syms (abfd
, hdr
, localsyms
, 0, NULL
, NULL
, NULL
);
5611 /* No internal symbols read? Skip this BFD. */
5612 if (isymbuf
== NULL
)
5615 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table ((info
));
5617 for (i
= 0; i
< localsyms
; i
++)
5619 Elf_Internal_Sym
*isym
= &isymbuf
[i
];
5620 asection
*sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
5623 if (sec
!= NULL
&& ELF_ST_BIND (isym
->st_info
) == STB_LOCAL
)
5625 name
= bfd_elf_string_from_elf_section (abfd
,
5629 if (bfd_is_aarch64_special_symbol_name
5630 (name
, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP
))
5632 elfNN_aarch64_section_map_add (abfd
, sec
, name
[1],
5634 if (!htab
->c64_output
&& name
[1] == 'c')
5635 htab
->c64_output
= TRUE
;
5639 elf_aarch64_tdata (abfd
)->secmaps_initialised
= TRUE
;
5643 setup_plt_values (struct bfd_link_info
*link_info
,
5644 aarch64_plt_type plt_type
)
5646 struct elf_aarch64_link_hash_table
*globals
;
5647 globals
= elf_aarch64_hash_table (link_info
);
5649 /* Set up plt stubs in case we need C64 PLT. Override BTI/PAC since they're
5650 not compatible. PLT stub sizes are the same as the default ones. */
5651 if (globals
->c64_rel
)
5653 if (plt_type
!= PLT_NORMAL
)
5655 (_("ignoring C64-incompatible extensions: %s"),
5656 (plt_type
== PLT_BTI_PAC
? "BTI, PAC"
5657 : plt_type
== PLT_BTI
? "BTI" : "PAC"));
5659 globals
->plt0_entry
= elfNN_c64_small_plt0_entry
;
5660 globals
->plt_entry
= elfNN_c64_small_plt_entry
;
5664 if (plt_type
== PLT_BTI_PAC
)
5666 globals
->plt0_entry
= elfNN_aarch64_small_plt0_bti_entry
;
5668 /* Only in ET_EXEC we need PLTn with BTI. */
5669 if (bfd_link_pde (link_info
))
5671 globals
->plt_entry_size
= PLT_BTI_PAC_SMALL_ENTRY_SIZE
;
5672 globals
->plt_entry
= elfNN_aarch64_small_plt_bti_pac_entry
;
5676 globals
->plt_entry_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
5677 globals
->plt_entry
= elfNN_aarch64_small_plt_pac_entry
;
5680 else if (plt_type
== PLT_BTI
)
5682 globals
->plt0_entry
= elfNN_aarch64_small_plt0_bti_entry
;
5684 /* Only in ET_EXEC we need PLTn with BTI. */
5685 if (bfd_link_pde (link_info
))
5687 globals
->plt_entry_size
= PLT_BTI_SMALL_ENTRY_SIZE
;
5688 globals
->plt_entry
= elfNN_aarch64_small_plt_bti_entry
;
5691 else if (plt_type
== PLT_PAC
)
5693 globals
->plt_entry_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
5694 globals
->plt_entry
= elfNN_aarch64_small_plt_pac_entry
;
5698 /* Set option values needed during linking. */
5700 bfd_elfNN_aarch64_set_options (struct bfd
*output_bfd
,
5701 struct bfd_link_info
*link_info
,
5703 int no_wchar_warn
, int pic_veneer
,
5704 int fix_erratum_835769
,
5705 erratum_84319_opts fix_erratum_843419
,
5706 int no_apply_dynamic_relocs
,
5707 aarch64_bti_pac_info bp_info
)
5709 struct elf_aarch64_link_hash_table
*globals
;
5711 globals
= elf_aarch64_hash_table (link_info
);
5712 globals
->pic_veneer
= pic_veneer
;
5713 globals
->fix_erratum_835769
= fix_erratum_835769
;
5714 /* If the default options are used, then ERRAT_ADR will be set by default
5715 which will enable the ADRP->ADR workaround for the erratum 843419
5717 globals
->fix_erratum_843419
= fix_erratum_843419
;
5718 globals
->no_apply_dynamic_relocs
= no_apply_dynamic_relocs
;
5719 globals
->c64_rel
= 0;
5721 BFD_ASSERT (is_aarch64_elf (output_bfd
));
5722 elf_aarch64_tdata (output_bfd
)->no_enum_size_warning
= no_enum_warn
;
5723 elf_aarch64_tdata (output_bfd
)->no_wchar_size_warning
= no_wchar_warn
;
5725 switch (bp_info
.bti_type
)
5728 elf_aarch64_tdata (output_bfd
)->no_bti_warn
= 0;
5729 elf_aarch64_tdata (output_bfd
)->gnu_and_prop
5730 |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI
;
5736 elf_aarch64_tdata (output_bfd
)->plt_type
= bp_info
.plt_type
;
5737 elf_aarch64_tdata (output_bfd
)->secmaps_initialised
= FALSE
;
5741 aarch64_calculate_got_entry_vma (struct elf_link_hash_entry
*h
,
5742 struct elf_aarch64_link_hash_table
5743 *globals
, struct bfd_link_info
*info
,
5744 bfd_vma value
, bfd
*output_bfd
,
5745 bfd_boolean
*unresolved_reloc_p
)
5747 bfd_vma off
= (bfd_vma
) - 1;
5748 asection
*basegot
= globals
->root
.sgot
;
5749 bfd_boolean dyn
= globals
->root
.dynamic_sections_created
;
5753 BFD_ASSERT (basegot
!= NULL
);
5754 off
= h
->got
.offset
;
5755 BFD_ASSERT (off
!= (bfd_vma
) - 1);
5756 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
5757 || (bfd_link_pic (info
)
5758 && SYMBOL_REFERENCES_LOCAL (info
, h
))
5759 || (ELF_ST_VISIBILITY (h
->other
)
5760 && h
->root
.type
== bfd_link_hash_undefweak
))
5762 /* This is actually a static link, or it is a -Bsymbolic link
5763 and the symbol is defined locally. We must initialize this
5764 entry in the global offset table. Since the offset must
5765 always be a multiple of 8 (4 in the case of ILP32), we use
5766 the least significant bit to record whether we have
5767 initialized it already.
5768 When doing a dynamic link, we create a .rel(a).got relocation
5769 entry to initialize the value. This is done in the
5770 finish_dynamic_symbol routine. */
5775 bfd_put_NN (output_bfd
, value
, basegot
->contents
+ off
);
5780 *unresolved_reloc_p
= FALSE
;
5782 off
= off
+ basegot
->output_section
->vma
+ basegot
->output_offset
;
5788 /* Change R_TYPE to a more efficient access model where possible,
5789 return the new reloc type. */
5791 static bfd_reloc_code_real_type
5792 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type
,
5793 struct bfd_link_info
*info
,
5794 struct elf_link_hash_entry
*h
,
5795 bfd_boolean morello_reloc
)
5797 bfd_boolean is_local
= h
== NULL
;
5801 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
5802 return (is_local
|| !bfd_link_pic (info
)
5803 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5806 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5807 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5809 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5810 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
);
5812 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5814 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5817 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5819 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
5820 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
5822 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5824 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5825 : BFD_RELOC_AARCH64_NONE
);
5827 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
5829 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5830 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
);
5832 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
5834 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5835 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
);
5837 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
5838 return ((is_local
|| !bfd_link_pie (info
)
5839 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
));
5841 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
5842 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5844 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
5845 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
);
5847 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5848 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
: r_type
;
5850 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
5851 return is_local
? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
: r_type
;
5853 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5856 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5858 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
5859 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
);
5861 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
5862 return ((is_local
|| !bfd_link_pie (info
))
5863 ? BFD_RELOC_AARCH64_NONE
: r_type
);
5865 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
5866 if (morello_reloc
&& !is_local
&& bfd_link_pie (info
))
5869 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5870 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5871 /* Instructions with these relocations will be fully resolved during the
5872 transition into either a NOP in the A64 case or movk and add in
5874 return BFD_RELOC_AARCH64_NONE
;
5876 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5877 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5878 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5879 return is_local
? BFD_RELOC_AARCH64_NONE
: r_type
;
5882 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
5884 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
5885 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
;
5887 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
5889 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
5890 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
;
5901 aarch64_reloc_got_type (bfd_reloc_code_real_type r_type
)
5905 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
5906 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
5907 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
5908 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
5909 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
5910 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
5911 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
5912 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
5913 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
5916 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
5917 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
5920 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
5921 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
5922 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
5923 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
5924 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
5925 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
5926 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
5927 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
5930 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
5931 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
5932 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
5933 return GOT_TLSDESC_GD
| GOT_CAP
;
5935 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
5936 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
5937 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
5938 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
5939 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
5940 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
5941 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
5942 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
5943 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
5944 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
5945 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
5946 return GOT_TLSDESC_GD
;
5948 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
5949 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
5950 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
5951 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
5952 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
5953 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
5963 aarch64_can_relax_tls (bfd
*input_bfd
,
5964 struct bfd_link_info
*info
,
5965 const Elf_Internal_Rela
*rel
,
5966 struct elf_link_hash_entry
*h
,
5967 unsigned long r_symndx
)
5969 unsigned int symbol_got_type
;
5970 unsigned int reloc_got_type
;
5972 bfd_reloc_code_real_type bfd_r_type
5973 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
,
5974 ELFNN_R_TYPE (rel
->r_info
));
5976 if (! IS_AARCH64_TLS_RELAX_RELOC (bfd_r_type
))
5979 symbol_got_type
= elfNN_aarch64_symbol_got_type (h
, input_bfd
, r_symndx
);
5980 reloc_got_type
= aarch64_reloc_got_type (bfd_r_type
);
5982 if (symbol_got_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (reloc_got_type
))
5985 if (!bfd_link_executable (info
))
5988 if (h
&& h
->root
.type
== bfd_link_hash_undefweak
)
5994 /* Given the relocation code R_TYPE, return the relaxed bfd reloc
5997 static bfd_reloc_code_real_type
5998 aarch64_tls_transition (bfd
*input_bfd
,
5999 struct bfd_link_info
*info
,
6000 const Elf_Internal_Rela
*rel
,
6001 struct elf_link_hash_entry
*h
,
6002 unsigned long r_symndx
)
6004 bfd_reloc_code_real_type bfd_r_type
6005 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
,
6006 ELFNN_R_TYPE (rel
->r_info
));
6008 if (! aarch64_can_relax_tls (input_bfd
, info
, rel
, h
, r_symndx
))
6011 bfd_boolean morello_reloc
= (bfd_r_type
== BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
6012 && (ELFNN_R_TYPE (rel
[1].r_info
)
6013 == MORELLO_R (TLSDESC_CALL
)));
6015 /* GD -> IE is not supported for Morello TLSDESC yet. We do however allow
6016 lowering of GD -> LE for static non-pie executables. XXX It ought to be
6017 safe to do this for A64 as well but it is not implemented yet. */
6018 if (h
!= NULL
&& morello_reloc
&& bfd_link_pie (info
))
6021 return aarch64_tls_transition_without_check (bfd_r_type
, info
, h
,
6025 /* Return the base VMA address which should be subtracted from real addresses
6026 when resolving R_AARCH64_TLS_DTPREL relocation. */
6029 dtpoff_base (struct bfd_link_info
*info
)
6031 /* If tls_sec is NULL, we should have signalled an error already. */
6032 BFD_ASSERT (elf_hash_table (info
)->tls_sec
!= NULL
);
6033 return elf_hash_table (info
)->tls_sec
->vma
;
6036 /* Return the base VMA address which should be subtracted from real addresses
6037 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
6040 tpoff_base (struct bfd_link_info
*info
)
6042 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
6044 /* If tls_sec is NULL, we should have signalled an error already. */
6045 BFD_ASSERT (htab
->tls_sec
!= NULL
);
6047 bfd_vma base
= align_power ((bfd_vma
) TCB_SIZE (info
->output_bfd
),
6048 htab
->tls_sec
->alignment_power
);
6049 return htab
->tls_sec
->vma
- base
;
6053 symbol_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6054 unsigned long r_symndx
)
6056 /* Calculate the address of the GOT entry for symbol
6057 referred to in h. */
6059 return &h
->got
.offset
;
6063 struct elf_aarch64_local_symbol
*l
;
6065 l
= elf_aarch64_locals (input_bfd
);
6066 return &l
[r_symndx
].got_offset
;
6071 symbol_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6072 unsigned long r_symndx
)
6075 p
= symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
6080 symbol_got_offset_mark_p (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6081 unsigned long r_symndx
)
6084 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
6089 symbol_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6090 unsigned long r_symndx
)
6093 value
= * symbol_got_offset_ref (input_bfd
, h
, r_symndx
);
6099 symbol_tlsdesc_got_offset_ref (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6100 unsigned long r_symndx
)
6102 /* Calculate the address of the GOT entry for symbol
6103 referred to in h. */
6106 struct elf_aarch64_link_hash_entry
*eh
;
6107 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
6108 return &eh
->tlsdesc_got_jump_table_offset
;
6113 struct elf_aarch64_local_symbol
*l
;
6115 l
= elf_aarch64_locals (input_bfd
);
6116 return &l
[r_symndx
].tlsdesc_got_jump_table_offset
;
6121 symbol_tlsdesc_got_offset_mark (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6122 unsigned long r_symndx
)
6125 p
= symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
6130 symbol_tlsdesc_got_offset_mark_p (bfd
*input_bfd
,
6131 struct elf_link_hash_entry
*h
,
6132 unsigned long r_symndx
)
6135 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
6140 symbol_tlsdesc_got_offset (bfd
*input_bfd
, struct elf_link_hash_entry
*h
,
6141 unsigned long r_symndx
)
6144 value
= * symbol_tlsdesc_got_offset_ref (input_bfd
, h
, r_symndx
);
6149 /* Data for make_branch_to_erratum_835769_stub(). */
6151 struct erratum_835769_branch_to_stub_data
6153 struct bfd_link_info
*info
;
6154 asection
*output_section
;
6158 /* Helper to insert branches to erratum 835769 stubs in the right
6159 places for a particular section. */
6162 make_branch_to_erratum_835769_stub (struct bfd_hash_entry
*gen_entry
,
6165 struct elf_aarch64_stub_hash_entry
*stub_entry
;
6166 struct erratum_835769_branch_to_stub_data
*data
;
6168 unsigned long branch_insn
= 0;
6169 bfd_vma veneered_insn_loc
, veneer_entry_loc
;
6170 bfd_signed_vma branch_offset
;
6171 unsigned int target
;
6174 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
6175 data
= (struct erratum_835769_branch_to_stub_data
*) in_arg
;
6177 if (stub_entry
->target_section
!= data
->output_section
6178 || stub_entry
->stub_type
!= aarch64_stub_erratum_835769_veneer
)
6181 contents
= data
->contents
;
6182 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
6183 + stub_entry
->target_section
->output_offset
6184 + stub_entry
->target_value
;
6185 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
6186 + stub_entry
->stub_sec
->output_offset
6187 + stub_entry
->stub_offset
;
6188 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
6190 abfd
= stub_entry
->target_section
->owner
;
6191 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
6193 (_("%pB: error: erratum 835769 stub out "
6194 "of range (input file too large)"), abfd
);
6196 target
= stub_entry
->target_value
;
6197 branch_insn
= 0x14000000;
6198 branch_offset
>>= 2;
6199 branch_offset
&= 0x3ffffff;
6200 branch_insn
|= branch_offset
;
6201 bfd_putl32 (branch_insn
, &contents
[target
]);
6208 _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry
*gen_entry
,
6211 struct elf_aarch64_stub_hash_entry
*stub_entry
6212 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
6213 struct erratum_835769_branch_to_stub_data
*data
6214 = (struct erratum_835769_branch_to_stub_data
*) in_arg
;
6215 struct bfd_link_info
*info
;
6216 struct elf_aarch64_link_hash_table
*htab
;
6224 contents
= data
->contents
;
6225 section
= data
->output_section
;
6227 htab
= elf_aarch64_hash_table (info
);
6229 if (stub_entry
->target_section
!= section
6230 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
)
6233 BFD_ASSERT (((htab
->fix_erratum_843419
& ERRAT_ADRP
) && stub_entry
->stub_sec
)
6234 || (htab
->fix_erratum_843419
& ERRAT_ADR
));
6236 /* Only update the stub section if we have one. We should always have one if
6237 we're allowed to use the ADRP errata workaround, otherwise it is not
6239 if (stub_entry
->stub_sec
)
6241 insn
= bfd_getl32 (contents
+ stub_entry
->target_value
);
6243 stub_entry
->stub_sec
->contents
+ stub_entry
->stub_offset
);
6246 place
= (section
->output_section
->vma
+ section
->output_offset
6247 + stub_entry
->adrp_offset
);
6248 insn
= bfd_getl32 (contents
+ stub_entry
->adrp_offset
);
6250 if (!_bfd_aarch64_adrp_p (insn
))
6253 bfd_signed_vma imm
=
6254 (_bfd_aarch64_sign_extend
6255 ((bfd_vma
) _bfd_aarch64_decode_adrp_imm (insn
) << 12, 33)
6258 if ((htab
->fix_erratum_843419
& ERRAT_ADR
)
6259 && (imm
>= AARCH64_MIN_ADRP_IMM
&& imm
<= AARCH64_MAX_ADRP_IMM
))
6261 insn
= (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP
, imm
, 0)
6262 | AARCH64_RT (insn
));
6263 bfd_putl32 (insn
, contents
+ stub_entry
->adrp_offset
);
6264 /* Stub is not needed, don't map it out. */
6265 stub_entry
->stub_type
= aarch64_stub_none
;
6267 else if (htab
->fix_erratum_843419
& ERRAT_ADRP
)
6269 bfd_vma veneered_insn_loc
;
6270 bfd_vma veneer_entry_loc
;
6271 bfd_signed_vma branch_offset
;
6272 uint32_t branch_insn
;
6274 veneered_insn_loc
= stub_entry
->target_section
->output_section
->vma
6275 + stub_entry
->target_section
->output_offset
6276 + stub_entry
->target_value
;
6277 veneer_entry_loc
= stub_entry
->stub_sec
->output_section
->vma
6278 + stub_entry
->stub_sec
->output_offset
6279 + stub_entry
->stub_offset
;
6280 branch_offset
= veneer_entry_loc
- veneered_insn_loc
;
6282 abfd
= stub_entry
->target_section
->owner
;
6283 if (!aarch64_valid_branch_p (veneer_entry_loc
, veneered_insn_loc
))
6285 (_("%pB: error: erratum 843419 stub out "
6286 "of range (input file too large)"), abfd
);
6288 branch_insn
= 0x14000000;
6289 branch_offset
>>= 2;
6290 branch_offset
&= 0x3ffffff;
6291 branch_insn
|= branch_offset
;
6292 bfd_putl32 (branch_insn
, contents
+ stub_entry
->target_value
);
6296 abfd
= stub_entry
->target_section
->owner
;
6298 (_("%pB: error: erratum 843419 immediate 0x%" BFD_VMA_FMT
"x "
6299 "out of range for ADR (input file too large) and "
6300 "--fix-cortex-a53-843419=adr used. Run the linker with "
6301 "--fix-cortex-a53-843419=full instead"), abfd
, imm
);
6302 bfd_set_error (bfd_error_bad_value
);
6303 /* This function is called inside a hashtable traversal and the error
6304 handlers called above turn into non-fatal errors. Which means this
6305 case ld returns an exit code 0 and also produces a broken object file.
6306 To prevent this, issue a hard abort. */
6314 elfNN_aarch64_write_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
6315 struct bfd_link_info
*link_info
,
6320 struct elf_aarch64_link_hash_table
*globals
=
6321 elf_aarch64_hash_table (link_info
);
6323 if (globals
== NULL
)
6326 /* Fix code to point to erratum 835769 stubs. */
6327 if (globals
->fix_erratum_835769
)
6329 struct erratum_835769_branch_to_stub_data data
;
6331 data
.info
= link_info
;
6332 data
.output_section
= sec
;
6333 data
.contents
= contents
;
6334 bfd_hash_traverse (&globals
->stub_hash_table
,
6335 make_branch_to_erratum_835769_stub
, &data
);
6338 if (globals
->fix_erratum_843419
)
6340 struct erratum_835769_branch_to_stub_data data
;
6342 data
.info
= link_info
;
6343 data
.output_section
= sec
;
6344 data
.contents
= contents
;
6345 bfd_hash_traverse (&globals
->stub_hash_table
,
6346 _bfd_aarch64_erratum_843419_branch_to_stub
, &data
);
6352 /* Return TRUE if RELOC is a relocation against the base of GOT table. */
6355 aarch64_relocation_aginst_gp_p (bfd_reloc_code_real_type reloc
)
6357 return (reloc
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
6358 || reloc
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
6359 || reloc
== BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
6360 || reloc
== BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
6361 || reloc
== BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
);
6364 /* Build capability meta data, i.e. size and permissions for a capability. */
6367 cap_meta (size_t size
, const asection
*sec
, bfd_boolean
*guessed
)
6370 if (size
>= (1ULL << 56))
6371 return (bfd_vma
) -1;
6373 /* N.b. We are only ever using this function for Morello.
6374 Morello is little-endian.
6375 We are returning a 64bit sized integer.
6376 The format this metadata is supposed to fit is
6377 | 56 bit length | 8 bit permissions |
6378 This means that (in little endian layout) we need to put the 56 bit size
6379 in the *lower* bits of the uint64_t. */
6381 if (sec
->flags
& SEC_CODE
)
6383 else if (sec
->flags
& SEC_READONLY
6384 || sec
->flags
& SEC_ROM
)
6386 else if (sec
->flags
& SEC_ALLOC
)
6389 /* We should usually be able to derive a valid set of permissions
6390 from the section flags. We know that when a relocation is against an
6391 SHN_ABS symbol the section has no associated flags and we must guess.
6393 As it stands we don't know of any other instances where we do not have
6394 permission flags on a section. We choose to allow instances that we do
6395 not know of rather than abort on them so that if the guess is correct we
6396 don't hamper anyone progressing. */
6403 return size
| (flags
<< 56);
6406 enum c64_section_perm_type
{
6407 C64_SYM_UNKNOWN
= 0,
6410 C64_SYM_LDSCRIPT_DEF
,
6411 C64_SYM_LDSCRIPT_START
,
6414 static enum c64_section_perm_type
6415 c64_symbol_section_adjustment (struct elf_link_hash_entry
*h
, bfd_vma value
,
6416 asection
*sym_sec
, asection
**ret_sec
,
6417 struct bfd_link_info
*info
)
6420 return C64_SYM_UNKNOWN
;
6424 return C64_SYM_STANDARD
;
6426 /* Linker defined symbols are always at the start of the section they
6428 if (h
->root
.linker_def
)
6429 return C64_SYM_LINKER_DEF
;
6430 else if (h
->root
.ldscript_def
)
6432 const char *name
= h
->root
.root
.string
;
6433 size_t len
= strlen (name
);
6435 bfd_vma size
= sym_sec
->size
- (value
- sym_sec
->vma
);
6436 /* The special case: the symbol is at the end of the section.
6437 This could either mean that it is an end symbol or it is the
6438 start of the output section following the symbol. We try to
6439 guess if it is a start of the next section by reading its
6440 name. This is a compatibility hack, ideally linker scripts
6441 should be written such that start symbols are defined within
6442 the output section it intends to track. */
6444 && (len
> 8 && name
[0] == '_' && name
[1] == '_'
6445 && (!strncmp (name
+ 2, "start_", 6)
6446 || !strcmp (name
+ len
- 6, "_start"))))
6448 asection
*s
= bfd_sections_find_if (info
->output_bfd
,
6449 section_start_symbol
,
6454 return C64_SYM_LDSCRIPT_START
;
6457 return C64_SYM_LDSCRIPT_DEF
;
6459 return C64_SYM_STANDARD
;
6462 static bfd_reloc_status_type
6463 c64_fixup_frag (bfd
*input_bfd
, struct bfd_link_info
*info
,
6464 bfd_reloc_code_real_type bfd_r_type
, Elf_Internal_Sym
*sym
,
6465 struct elf_link_hash_entry
*h
, asection
*sym_sec
,
6466 asection
*reloc_sec
, bfd_byte
*frag_loc
, bfd_vma value
,
6467 bfd_signed_vma addend
, bfd_vma r_offset
)
6469 BFD_ASSERT (h
|| sym
);
6470 bfd_vma size
= sym
? sym
->st_size
: h
->size
;
6471 asection
*perm_sec
= sym_sec
;
6472 bfd_boolean bounds_ok
= FALSE
;
6474 const int aarch64_reloc_idx
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
6475 const char *reloc_name
= elfNN_aarch64_howto_table
[aarch64_reloc_idx
].name
;
6476 const char *sym_name
;
6480 Elf_Internal_Shdr
*symtab_hdr
= &elf_symtab_hdr (input_bfd
);
6481 sym_name
= (bfd_elf_string_from_elf_section (input_bfd
,
6482 symtab_hdr
->sh_link
,
6486 sym_name
= h
->root
.root
.string
;
6488 if (size
== 0 && sym_sec
)
6491 enum c64_section_perm_type type
6492 = c64_symbol_section_adjustment (h
, value
, sym_sec
, &perm_sec
, info
);
6496 case C64_SYM_STANDARD
:
6498 case C64_SYM_LINKER_DEF
:
6499 size
= perm_sec
->output_section
->size
;
6501 case C64_SYM_LDSCRIPT_DEF
:
6502 size
= perm_sec
->size
- (value
- perm_sec
->vma
);
6504 case C64_SYM_LDSCRIPT_START
:
6505 size
= perm_sec
->size
;
6512 /* Negative addends are not allowed for capability symbols. */
6513 if (addend
< 0 || (bfd_vma
) addend
> size
)
6514 return bfd_reloc_outofrange
;
6516 bfd_vma base
= value
, limit
= value
+ size
;
6519 if (!bounds_ok
&& !c64_valid_cap_range (&base
, &limit
, &align
))
6521 /* Just warn about this. It's not a requirement that bounds on
6522 objects should be precise, so there's no reason to error out on
6524 /* xgettext:c-format */
6526 (_("%pB: capability range for '%s' may exceed object bounds"),
6527 input_bfd
, sym_name
);
6530 if (perm_sec
&& perm_sec
->flags
& SEC_CODE
)
6532 /* Any symbol pointing into an executable section gets bounds according
6533 to PCC. In this case the relocation is set up so that the value is
6534 the base of the PCC, the addend is the offset from the PCC base to the
6535 VA that we want, and the size is the length of the PCC range.
6536 In this function we only use `value` to check the bounds make sense,
6537 which is somewhat superfluous when we're using pcc_high and pcc_low
6538 since we already enforced that in elfNN_c64_resize_sections. No harm
6539 in instead checking that the bounds on the object that were requested
6540 made sense even if they were overridden because this symbol points
6541 into an executable section.
6543 `size` on the other hand is part of the fragment that we output to and
6544 we need to change it in order to have functions that can access global
6545 data or jump to other functions. */
6546 size
= pcc_high
- pcc_low
;
6549 if (perm_sec
!= NULL
)
6551 bfd_boolean permissions_guessed
= FALSE
;
6552 bfd_vma frag
= cap_meta (size
, perm_sec
, &permissions_guessed
);
6554 if (frag
== (bfd_vma
) -1)
6555 return bfd_reloc_outofrange
;
6557 if (permissions_guessed
)
6559 _bfd_error_handler (_("%pB(%pA+%#" PRIx64
"): "
6560 "warning: relocation %s against symbol '%s' in "
6561 "section without permission flags '%s'. "
6562 "Assuming Read-Write."),
6563 input_bfd
, reloc_sec
, r_offset
, reloc_name
,
6564 sym_name
, perm_sec
->name
);
6567 bfd_put_64 (input_bfd
, frag
, frag_loc
);
6570 return bfd_reloc_continue
;
6573 /* Given either a local symbol SYM or global symbol H, do we need to adjust
6574 capability relocations against the symbol due to the fact that it points to
6577 c64_symbol_adjust (struct elf_link_hash_entry
*h
,
6578 bfd_vma value
, asection
*sym_sec
, struct bfd_link_info
*info
,
6579 bfd_vma
*adjust_addr
)
6582 enum c64_section_perm_type type
6583 = c64_symbol_section_adjustment (h
, value
, sym_sec
, &tmp_sec
, info
);
6585 if (type
== C64_SYM_UNKNOWN
)
6588 if (tmp_sec
->flags
& SEC_CODE
)
6590 *adjust_addr
= pcc_low
;
6597 /* Perform a relocation as part of a final link. The input relocation type
6598 should be TLS relaxed. */
6600 static bfd_reloc_status_type
6601 elfNN_aarch64_final_link_relocate (reloc_howto_type
*howto
,
6604 asection
*input_section
,
6606 Elf_Internal_Rela
*rel
,
6608 struct bfd_link_info
*info
,
6610 struct elf_link_hash_entry
*h
,
6611 bfd_boolean
*unresolved_reloc_p
,
6612 bfd_boolean save_addend
,
6613 bfd_vma
*saved_addend
,
6614 Elf_Internal_Sym
*sym
)
6616 Elf_Internal_Shdr
*symtab_hdr
;
6617 unsigned int r_type
= howto
->type
;
6618 bfd_reloc_code_real_type bfd_r_type
6619 = elfNN_aarch64_bfd_reloc_from_howto (howto
);
6620 unsigned long r_symndx
;
6621 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
6622 bfd_vma place
, off
, got_entry_addr
= 0;
6623 bfd_signed_vma signed_addend
;
6624 struct elf_aarch64_link_hash_table
*globals
;
6625 bfd_boolean weak_undef_p
;
6626 bfd_boolean relative_reloc
;
6628 bfd_vma orig_value
= value
;
6629 bfd_boolean resolved_to_zero
;
6630 bfd_boolean abs_symbol_p
;
6631 Elf_Internal_Sym
*isym
= NULL
;
6632 bfd_boolean c64_rtype
= FALSE
;
6633 bfd_boolean to_c64
= FALSE
;
6635 globals
= elf_aarch64_hash_table (info
);
6637 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
6639 BFD_ASSERT (is_aarch64_elf (input_bfd
));
6641 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
6643 place
= input_section
->output_section
->vma
6644 + input_section
->output_offset
+ rel
->r_offset
;
6646 /* Get addend, accumulating the addend for consecutive relocs
6647 which refer to the same offset. */
6648 signed_addend
= saved_addend
? *saved_addend
: 0;
6649 signed_addend
+= rel
->r_addend
;
6651 weak_undef_p
= (h
? h
->root
.type
== bfd_link_hash_undefweak
6652 : bfd_is_und_section (sym_sec
));
6653 abs_symbol_p
= h
!= NULL
&& bfd_is_abs_symbol (&h
->root
);
6657 isym
= bfd_sym_from_r_symndx (&globals
->root
.sym_cache
, input_bfd
,
6659 BFD_ASSERT (isym
!= NULL
);
6660 to_c64
= (isym
->st_target_internal
& ST_BRANCH_TO_C64
) != 0;
6663 to_c64
= (h
->target_internal
& ST_BRANCH_TO_C64
) != 0;
6666 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
6667 it here if it is defined in a non-shared object. */
6669 && h
->type
== STT_GNU_IFUNC
6676 if ((input_section
->flags
& SEC_ALLOC
) == 0)
6678 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
6679 STT_GNU_IFUNC symbol as STT_FUNC. */
6680 if (elf_section_type (input_section
) == SHT_NOTE
)
6683 /* Dynamic relocs are not propagated for SEC_DEBUGGING
6684 sections because such sections are not SEC_ALLOC and
6685 thus ld.so will not process them. */
6686 if ((input_section
->flags
& SEC_DEBUGGING
) != 0)
6687 return bfd_reloc_ok
;
6689 if (h
->root
.root
.string
)
6690 name
= h
->root
.root
.string
;
6692 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
, NULL
);
6694 /* xgettext:c-format */
6695 (_("%pB(%pA+%#" PRIx64
"): "
6696 "unresolvable %s relocation against symbol `%s'"),
6697 input_bfd
, input_section
, (uint64_t) rel
->r_offset
,
6699 bfd_set_error (bfd_error_bad_value
);
6700 return bfd_reloc_notsupported
;
6702 else if (h
->plt
.offset
== (bfd_vma
) -1)
6703 goto bad_ifunc_reloc
;
6705 /* STT_GNU_IFUNC symbol must go through PLT. */
6706 plt
= globals
->root
.splt
? globals
->root
.splt
: globals
->root
.iplt
;
6707 value
= (plt
->output_section
->vma
+ plt
->output_offset
+ h
->plt
.offset
);
6713 if (h
->root
.root
.string
)
6714 name
= h
->root
.root
.string
;
6716 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
6719 /* xgettext:c-format */
6720 (_("%pB: relocation %s against STT_GNU_IFUNC "
6721 "symbol `%s' isn't handled by %s"), input_bfd
,
6722 howto
->name
, name
, __FUNCTION__
);
6723 bfd_set_error (bfd_error_bad_value
);
6724 return bfd_reloc_notsupported
;
6726 case BFD_RELOC_AARCH64_NN
:
6727 if (rel
->r_addend
!= 0)
6729 if (h
->root
.root
.string
)
6730 name
= h
->root
.root
.string
;
6732 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
6735 /* xgettext:c-format */
6736 (_("%pB: relocation %s against STT_GNU_IFUNC "
6737 "symbol `%s' has non-zero addend: %" PRId64
),
6738 input_bfd
, howto
->name
, name
, (int64_t) rel
->r_addend
);
6739 bfd_set_error (bfd_error_bad_value
);
6740 return bfd_reloc_notsupported
;
6743 /* Generate dynamic relocation only when there is a
6744 non-GOT reference in a shared object. */
6745 if (bfd_link_pic (info
) && h
->non_got_ref
)
6747 Elf_Internal_Rela outrel
;
6750 /* Need a dynamic relocation to get the real function
6752 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
6756 if (outrel
.r_offset
== (bfd_vma
) -1
6757 || outrel
.r_offset
== (bfd_vma
) -2)
6760 outrel
.r_offset
+= (input_section
->output_section
->vma
6761 + input_section
->output_offset
);
6763 if (h
->dynindx
== -1
6765 || bfd_link_executable (info
))
6767 /* This symbol is resolved locally. */
6768 outrel
.r_info
= (elf_aarch64_hash_entry (h
)->got_type
6770 ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE
))
6771 : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
)));
6772 outrel
.r_addend
= (h
->root
.u
.def
.value
6773 + h
->root
.u
.def
.section
->output_section
->vma
6774 + h
->root
.u
.def
.section
->output_offset
);
6778 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
6779 outrel
.r_addend
= 0;
6782 sreloc
= globals
->root
.irelifunc
;
6783 elf_append_rela (output_bfd
, sreloc
, &outrel
);
6785 /* If this reloc is against an external symbol, we
6786 do not want to fiddle with the addend. Otherwise,
6787 we need to include the symbol value so that it
6788 becomes an addend for the dynamic reloc. For an
6789 internal symbol, we have updated addend. */
6790 return bfd_reloc_ok
;
6793 case BFD_RELOC_MORELLO_CALL26
:
6794 case BFD_RELOC_MORELLO_JUMP26
:
6795 case BFD_RELOC_AARCH64_CALL26
:
6796 case BFD_RELOC_AARCH64_JUMP26
:
6797 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6801 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
6803 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
6804 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
6805 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
6806 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
6807 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
6808 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
6809 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
6810 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
6811 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
6812 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
6813 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
6814 base_got
= globals
->root
.sgot
;
6815 off
= h
->got
.offset
;
6817 if (base_got
== NULL
)
6820 if (off
== (bfd_vma
) -1)
6824 /* We can't use h->got.offset here to save state, or
6825 even just remember the offset, as finish_dynamic_symbol
6826 would use that as offset into .got. */
6828 if (globals
->root
.splt
!= NULL
)
6830 plt_index
= ((h
->plt
.offset
- globals
->plt_header_size
) /
6831 globals
->plt_entry_size
);
6832 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE (globals
);
6833 base_got
= globals
->root
.sgotplt
;
6837 plt_index
= h
->plt
.offset
/ globals
->plt_entry_size
;
6838 off
= plt_index
* GOT_ENTRY_SIZE (globals
);
6839 base_got
= globals
->root
.igotplt
;
6842 if (h
->dynindx
== -1
6846 /* This references the local definition. We must
6847 initialize this entry in the global offset table.
6848 Since the offset must always be a multiple of 8,
6849 we use the least significant bit to record
6850 whether we have initialized it already.
6852 When doing a dynamic link, we create a .rela.got
6853 relocation entry to initialize the value. This
6854 is done in the finish_dynamic_symbol routine. */
6859 bfd_put_NN (output_bfd
, value
,
6860 base_got
->contents
+ off
);
6861 /* Note that this is harmless as -1 | 1 still is -1. */
6865 value
= (base_got
->output_section
->vma
6866 + base_got
->output_offset
+ off
);
6869 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
6871 unresolved_reloc_p
);
6873 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
6874 addend
= (globals
->root
.sgot
->output_section
->vma
6875 + globals
->root
.sgot
->output_offset
);
6877 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
6879 addend
, weak_undef_p
);
6880 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
, howto
, value
);
6881 case BFD_RELOC_AARCH64_ADD_LO12
:
6882 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
6883 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
6889 resolved_to_zero
= (h
!= NULL
6890 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
6894 case BFD_RELOC_AARCH64_NONE
:
6895 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
6896 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
6897 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
6898 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
6899 *unresolved_reloc_p
= FALSE
;
6900 return bfd_reloc_ok
;
6902 case BFD_RELOC_AARCH64_NN
:
6904 /* When generating a shared object or relocatable executable, these
6905 relocations are copied into the output file to be resolved at
6907 if (((bfd_link_pic (info
)
6908 || globals
->root
.is_relocatable_executable
)
6909 && (input_section
->flags
& SEC_ALLOC
)
6911 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
6912 && !resolved_to_zero
)
6913 || h
->root
.type
!= bfd_link_hash_undefweak
))
6914 /* Or we are creating an executable, we may need to keep relocations
6915 for symbols satisfied by a dynamic library if we manage to avoid
6916 copy relocs for the symbol. */
6917 || (ELIMINATE_COPY_RELOCS
6918 && !bfd_link_pic (info
)
6920 && (input_section
->flags
& SEC_ALLOC
)
6925 || h
->root
.type
== bfd_link_hash_undefweak
6926 || h
->root
.type
== bfd_link_hash_undefined
)))
6928 Elf_Internal_Rela outrel
;
6930 bfd_boolean skip
, relocate
;
6933 *unresolved_reloc_p
= FALSE
;
6938 outrel
.r_addend
= signed_addend
;
6940 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
6942 if (outrel
.r_offset
== (bfd_vma
) - 1)
6944 else if (outrel
.r_offset
== (bfd_vma
) - 2)
6949 else if (abs_symbol_p
)
6951 /* Local absolute symbol. */
6952 skip
= (h
->forced_local
|| (h
->dynindx
== -1));
6956 outrel
.r_offset
+= (input_section
->output_section
->vma
6957 + input_section
->output_offset
);
6960 memset (&outrel
, 0, sizeof outrel
);
6963 && (!bfd_link_pic (info
)
6964 || !(bfd_link_pie (info
) || SYMBOLIC_BIND (info
, h
))
6965 || !h
->def_regular
))
6966 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
6971 /* On SVR4-ish systems, the dynamic loader cannot
6972 relocate the text and data segments independently,
6973 so the symbol does not matter. */
6975 relocate
= globals
->no_apply_dynamic_relocs
? FALSE
: TRUE
;
6976 outrel
.r_info
= ELFNN_R_INFO (symbol
, AARCH64_R (RELATIVE
));
6977 outrel
.r_addend
+= value
;
6980 sreloc
= elf_section_data (input_section
)->sreloc
;
6981 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
6982 return bfd_reloc_notsupported
;
6984 loc
= sreloc
->contents
+ sreloc
->reloc_count
++ * RELOC_SIZE (globals
);
6985 bfd_elfNN_swap_reloca_out (output_bfd
, &outrel
, loc
);
6987 if (sreloc
->reloc_count
* RELOC_SIZE (globals
) > sreloc
->size
)
6989 /* Sanity to check that we have previously allocated
6990 sufficient space in the relocation section for the
6991 number of relocations we actually want to emit. */
6995 /* If this reloc is against an external symbol, we do not want to
6996 fiddle with the addend. Otherwise, we need to include the symbol
6997 value so that it becomes an addend for the dynamic reloc. */
6999 return bfd_reloc_ok
;
7001 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
7002 contents
, rel
->r_offset
, value
,
7006 value
+= signed_addend
;
7009 case BFD_RELOC_MORELLO_CALL26
:
7010 case BFD_RELOC_MORELLO_JUMP26
:
7011 case BFD_RELOC_AARCH64_CALL26
:
7012 case BFD_RELOC_AARCH64_JUMP26
:
7014 asection
*splt
= globals
->root
.splt
;
7015 bfd_boolean via_plt_p
=
7016 splt
!= NULL
&& h
!= NULL
&& h
->plt
.offset
!= (bfd_vma
) - 1;
7018 /* A call to an undefined weak symbol is converted to a jump to
7019 the next instruction unless a PLT entry will be created.
7020 The jump to the next instruction is optimized as a NOP.
7021 Do the same for local undefined symbols. */
7022 if (weak_undef_p
&& ! via_plt_p
)
7024 bfd_putl32 (INSN_NOP
, hit_data
);
7025 return bfd_reloc_ok
;
7028 /* If the call goes through a PLT entry, make sure to
7029 check distance to the right destination address. */
7031 value
= (splt
->output_section
->vma
7032 + splt
->output_offset
+ h
->plt
.offset
);
7034 /* Check if a stub has to be inserted because the destination
7036 struct elf_aarch64_stub_hash_entry
*stub_entry
= NULL
;
7038 enum elf_aarch64_stub_type c64_stub
= aarch64_stub_none
;
7040 /* Figure out if we need an interworking stub and if yes, what
7043 c64_stub
= aarch64_interwork_stub (r_type
, to_c64
);
7045 /* If the branch destination is directed to plt stub, "value" will be
7046 the final destination, otherwise we should plus signed_addend, it may
7047 contain non-zero value, for example call to local function symbol
7048 which are turned into "sec_sym + sec_off", and sec_off is kept in
7050 if (c64_stub
!= aarch64_stub_none
7051 || (aarch64_branch_reloc_p (r_type
)
7052 && !aarch64_valid_branch_p ((via_plt_p
? value
7053 : value
+ signed_addend
), place
)))
7055 /* The target is out of reach, so redirect the branch to
7056 the local stub for this function. */
7057 stub_entry
= elfNN_aarch64_get_stub_entry (input_section
, sym_sec
,
7062 if (stub_entry
!= NULL
)
7064 value
= (stub_entry
->stub_offset
7065 + stub_entry
->stub_sec
->output_offset
7066 + stub_entry
->stub_sec
->output_section
->vma
);
7068 /* We have redirected the destination to stub entry address,
7069 so ignore any addend record in the original rela entry. */
7073 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7075 signed_addend
, weak_undef_p
);
7076 *unresolved_reloc_p
= FALSE
;
7079 case BFD_RELOC_AARCH64_16_PCREL
:
7080 case BFD_RELOC_AARCH64_32_PCREL
:
7081 case BFD_RELOC_AARCH64_64_PCREL
:
7082 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
7083 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
7084 case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL
:
7085 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
7086 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
7087 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
7088 case BFD_RELOC_MORELLO_LD_LO17_PCREL
:
7089 case BFD_RELOC_AARCH64_MOVW_PREL_G0
:
7090 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC
:
7091 case BFD_RELOC_AARCH64_MOVW_PREL_G1
:
7092 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC
:
7093 case BFD_RELOC_AARCH64_MOVW_PREL_G2
:
7094 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC
:
7095 case BFD_RELOC_AARCH64_MOVW_PREL_G3
:
7096 if (bfd_link_pic (info
)
7097 && (input_section
->flags
& SEC_ALLOC
) != 0
7098 && (input_section
->flags
& SEC_READONLY
) != 0
7099 && !SYMBOL_REFERENCES_LOCAL (info
, h
))
7101 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7104 /* xgettext:c-format */
7105 (_("%pB: relocation %s against symbol `%s' which may bind "
7106 "externally can not be used when making a shared object; "
7107 "recompile with -fPIC"),
7108 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7109 h
->root
.root
.string
);
7110 bfd_set_error (bfd_error_bad_value
);
7111 return bfd_reloc_notsupported
;
7113 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7118 if (bfd_r_type
== BFD_RELOC_AARCH64_ADR_LO21_PCREL
&& isym
!= NULL
7119 && isym
->st_target_internal
& ST_BRANCH_TO_C64
)
7123 case BFD_RELOC_MORELLO_BRANCH19
:
7124 case BFD_RELOC_MORELLO_TSTBR14
:
7127 case BFD_RELOC_AARCH64_BRANCH19
:
7128 case BFD_RELOC_AARCH64_TSTBR14
:
7129 if (h
&& h
->root
.type
== bfd_link_hash_undefined
)
7132 /* xgettext:c-format */
7133 (_("%pB: conditional branch to undefined symbol `%s' "
7134 "not allowed"), input_bfd
, h
->root
.root
.string
);
7135 bfd_set_error (bfd_error_bad_value
);
7136 return bfd_reloc_notsupported
;
7139 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7141 if ((c64_rtype
&& !to_c64
) || (!c64_rtype
&& to_c64
))
7144 /* xgettext:c-format */
7145 (_("%pB: interworking not supported on relocation %s"),
7146 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
7147 return bfd_reloc_notsupported
;
7152 case BFD_RELOC_AARCH64_16
:
7154 case BFD_RELOC_AARCH64_32
:
7156 case BFD_RELOC_AARCH64_ADD_LO12
:
7157 case BFD_RELOC_AARCH64_LDST128_LO12
:
7158 case BFD_RELOC_AARCH64_LDST16_LO12
:
7159 case BFD_RELOC_AARCH64_LDST32_LO12
:
7160 case BFD_RELOC_AARCH64_LDST64_LO12
:
7161 case BFD_RELOC_AARCH64_LDST8_LO12
:
7162 case BFD_RELOC_AARCH64_MOVW_G0
:
7163 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
7164 case BFD_RELOC_AARCH64_MOVW_G0_S
:
7165 case BFD_RELOC_AARCH64_MOVW_G1
:
7166 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
7167 case BFD_RELOC_AARCH64_MOVW_G1_S
:
7168 case BFD_RELOC_AARCH64_MOVW_G2
:
7169 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
7170 case BFD_RELOC_AARCH64_MOVW_G2_S
:
7171 case BFD_RELOC_AARCH64_MOVW_G3
:
7172 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7174 signed_addend
, weak_undef_p
);
7175 if (bfd_r_type
== BFD_RELOC_AARCH64_ADD_LO12
&& isym
!= NULL
7176 && isym
->st_target_internal
& ST_BRANCH_TO_C64
)
7181 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
7182 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
7183 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
7184 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
7185 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
7186 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
7187 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
7188 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
7189 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
7190 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
7191 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
7192 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
7193 base_got
= globals
->root
.sgot
;
7195 bfd_boolean c64_reloc
=
7196 (bfd_r_type
== BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
7197 || bfd_r_type
== BFD_RELOC_MORELLO_ADR_GOT_PAGE
);
7199 if (signed_addend
!= 0)
7201 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7203 /* xgettext:c-format */
7204 (_("%pB: symbol plus addend can not be placed into the GOT "
7205 "for relocation %s"),
7206 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
7210 if (base_got
== NULL
)
7211 BFD_ASSERT (h
!= NULL
);
7213 relative_reloc
= FALSE
;
7219 /* If a symbol is not dynamic and is not undefined weak, bind it
7220 locally and generate a RELATIVE relocation under PIC mode.
7222 NOTE: one symbol may be referenced by several relocations, we
7223 should only generate one RELATIVE relocation for that symbol.
7224 Therefore, check GOT offset mark first.
7226 NOTE2: Symbol references via GOT in C64 static binaries without
7227 PIC should always have relative relocations, so we do that here
7229 if (((h
->dynindx
== -1
7231 && h
->root
.type
!= bfd_link_hash_undefweak
7232 && bfd_link_pic (info
))
7233 || (!bfd_link_pic (info
) && bfd_link_executable (info
)
7235 && !symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7236 relative_reloc
= TRUE
;
7239 && c64_symbol_adjust (h
, value
, sym_sec
, info
, &frag_value
))
7240 signed_addend
= (value
| h
->target_internal
) - frag_value
;
7242 frag_value
= value
| h
->target_internal
;
7244 value
= aarch64_calculate_got_entry_vma (h
, globals
, info
,
7247 unresolved_reloc_p
);
7248 /* Record the GOT entry address which will be used when generating
7249 RELATIVE relocation. */
7251 got_entry_addr
= value
;
7253 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
7254 addend
= (globals
->root
.sgot
->output_section
->vma
7255 + globals
->root
.sgot
->output_offset
);
7256 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7258 addend
, weak_undef_p
);
7263 struct elf_aarch64_local_symbol
*locals
7264 = elf_aarch64_locals (input_bfd
);
7268 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7270 /* xgettext:c-format */
7271 (_("%pB: local symbol descriptor table be NULL when applying "
7272 "relocation %s against local symbol"),
7273 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
);
7277 got_entry_addr
= (base_got
->output_section
->vma
7278 + base_got
->output_offset
+ off
);
7280 if (!symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
7285 && c64_symbol_adjust (h
, value
, sym_sec
, info
, &frag_value
))
7286 signed_addend
= (value
| sym
->st_target_internal
) - frag_value
;
7288 frag_value
= value
| sym
->st_target_internal
;
7290 bfd_put_64 (output_bfd
, frag_value
, base_got
->contents
+ off
);
7292 /* For local symbol, we have done absolute relocation in static
7293 linking stage. While for shared library, we need to update the
7294 content of GOT entry according to the shared object's runtime
7295 base address. So, we need to generate a R_AARCH64_RELATIVE reloc
7296 for dynamic linker. */
7297 if (bfd_link_pic (info
)
7298 || (!bfd_link_pic (info
) && bfd_link_executable (info
)
7300 relative_reloc
= TRUE
;
7302 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
7305 /* Update the relocation value to GOT entry addr as we have transformed
7306 the direct data access into indirect data access through GOT. */
7307 value
= got_entry_addr
;
7309 if (aarch64_relocation_aginst_gp_p (bfd_r_type
))
7310 addend
= base_got
->output_section
->vma
+ base_got
->output_offset
;
7312 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7314 addend
, weak_undef_p
);
7320 Elf_Internal_Rela outrel
;
7322 enum elf_aarch64_reloc_type rtype
= AARCH64_R (RELATIVE
);
7324 s
= globals
->root
.srelgot
;
7326 /* For a C64 relative relocation, also add size and permissions into
7330 bfd_reloc_status_type ret
;
7332 ret
= c64_fixup_frag (input_bfd
, info
, bfd_r_type
, sym
, h
,
7333 sym_sec
, s
, base_got
->contents
+ off
+ 8,
7334 orig_value
, 0, off
);
7336 if (ret
!= bfd_reloc_continue
)
7339 rtype
= MORELLO_R (RELATIVE
);
7341 if (bfd_link_executable (info
) && !bfd_link_pic (info
))
7342 s
= globals
->srelcaps
;
7344 outrel
.r_addend
= signed_addend
;
7347 outrel
.r_addend
= orig_value
;
7352 outrel
.r_offset
= got_entry_addr
;
7353 outrel
.r_info
= ELFNN_R_INFO (0, rtype
);
7354 elf_append_rela (output_bfd
, s
, &outrel
);
7358 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
7359 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
7360 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
7361 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
7362 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
7363 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
7364 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
7365 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
7366 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
7367 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
7368 if (globals
->root
.sgot
== NULL
)
7369 return bfd_reloc_notsupported
;
7371 value
= (symbol_got_offset (input_bfd
, h
, r_symndx
)
7372 + globals
->root
.sgot
->output_section
->vma
7373 + globals
->root
.sgot
->output_offset
);
7375 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7378 *unresolved_reloc_p
= FALSE
;
7381 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
7382 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
7383 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
7384 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
7385 if (globals
->root
.sgot
== NULL
)
7386 return bfd_reloc_notsupported
;
7388 value
= symbol_got_offset (input_bfd
, h
, r_symndx
);
7389 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7392 *unresolved_reloc_p
= FALSE
;
7395 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
7396 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
7397 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
7398 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
7399 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
7400 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
7401 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
7402 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
7403 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
7404 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
7405 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
7406 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
7407 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
7408 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
7409 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
7410 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
7412 if (!(weak_undef_p
|| elf_hash_table (info
)->tls_sec
))
7414 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7416 /* xgettext:c-format */
7417 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
7418 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7419 h
->root
.root
.string
);
7420 bfd_set_error (bfd_error_bad_value
);
7421 return bfd_reloc_notsupported
;
7425 = weak_undef_p
? 0 : signed_addend
- dtpoff_base (info
);
7426 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7428 def_value
, weak_undef_p
);
7432 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
7433 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
7434 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
7435 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
:
7436 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
:
7437 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
:
7438 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
:
7439 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
:
7440 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
:
7441 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
:
7442 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
:
7443 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
7444 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
7445 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
7446 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
7447 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
7449 if (!(weak_undef_p
|| elf_hash_table (info
)->tls_sec
))
7451 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
7453 /* xgettext:c-format */
7454 (_("%pB: TLS relocation %s against undefined symbol `%s'"),
7455 input_bfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
7456 h
->root
.root
.string
);
7457 bfd_set_error (bfd_error_bad_value
);
7458 return bfd_reloc_notsupported
;
7462 = weak_undef_p
? 0 : signed_addend
- tpoff_base (info
);
7463 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7465 def_value
, weak_undef_p
);
7466 *unresolved_reloc_p
= FALSE
;
7470 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
7471 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
7472 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
7473 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
7474 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
7475 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
7476 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
7477 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
7478 if (globals
->root
.sgot
== NULL
)
7479 return bfd_reloc_notsupported
;
7480 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
7481 + globals
->root
.sgotplt
->output_section
->vma
7482 + globals
->root
.sgotplt
->output_offset
7483 + globals
->sgotplt_jump_table_size
);
7485 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7488 *unresolved_reloc_p
= FALSE
;
7491 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
7492 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
7493 if (globals
->root
.sgot
== NULL
)
7494 return bfd_reloc_notsupported
;
7496 value
= (symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
)
7497 + globals
->root
.sgotplt
->output_section
->vma
7498 + globals
->root
.sgotplt
->output_offset
7499 + globals
->sgotplt_jump_table_size
);
7501 value
-= (globals
->root
.sgot
->output_section
->vma
7502 + globals
->root
.sgot
->output_offset
);
7504 value
= _bfd_aarch64_elf_resolve_relocation (input_bfd
, bfd_r_type
,
7507 *unresolved_reloc_p
= FALSE
;
7510 case BFD_RELOC_MORELLO_CAPINIT
:
7512 Elf_Internal_Rela outrel
;
7514 if (input_section
->flags
& SEC_READONLY
)
7517 /* xgettext:c-format */
7518 (_("%pB: capability relocation section must be writable"),
7520 bfd_set_error (bfd_error_bad_value
);
7521 return bfd_reloc_notsupported
;
7524 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
, info
,
7528 outrel
.r_offset
+= (input_section
->output_section
->vma
7529 + input_section
->output_offset
);
7531 /* Capability-aligned. */
7532 if (outrel
.r_offset
& 0xf)
7533 return bfd_reloc_overflow
;
7535 bfd_reloc_status_type ret
;
7537 ret
= c64_fixup_frag (input_bfd
, info
, bfd_r_type
, sym
, h
, sym_sec
,
7538 input_section
, hit_data
+ 8, value
,
7539 signed_addend
, rel
->r_offset
);
7541 if (ret
!= bfd_reloc_continue
)
7544 outrel
.r_addend
= signed_addend
;
7545 value
|= (h
!= NULL
? h
->target_internal
: sym
->st_target_internal
);
7547 /* Emit a dynamic relocation if we are building PIC. */
7550 && bfd_link_pic (info
)
7551 && !SYMBOL_REFERENCES_LOCAL (info
, h
))
7552 outrel
.r_info
= ELFNN_R_INFO (h
->dynindx
, r_type
);
7554 outrel
.r_info
= ELFNN_R_INFO (0, MORELLO_R (RELATIVE
));
7556 /* Symbols without size information get bounds to the
7557 whole section: adjust the base of the capability to the
7558 start of the section and set the addend to obtain the
7559 correct address for the symbol. */
7561 if (c64_symbol_adjust (h
, value
, sym_sec
, info
, &new_value
))
7563 outrel
.r_addend
+= (value
- new_value
);
7567 asection
*s
= globals
->srelcaps
;
7569 elf_append_rela (output_bfd
, s
, &outrel
);
7570 *unresolved_reloc_p
= FALSE
;
7575 return bfd_reloc_notsupported
;
7579 *saved_addend
= value
;
7581 /* Only apply the final relocation in a sequence. */
7583 return bfd_reloc_continue
;
7585 return _bfd_aarch64_elf_put_addend (input_bfd
, hit_data
, bfd_r_type
,
7589 /* LP64 and ILP32 operates on x- and w-registers respectively.
7590 Next definitions take into account the difference between
7591 corresponding machine codes. R means x-register if the target
7592 arch is LP64, and w-register if the target is ILP32. */
7595 # define add_R0_R0 (0x91000000)
7596 # define add_R0_R0_R1 (0x8b000020)
7597 # define add_R0_R1 (0x91400020)
7598 # define ldr_R0 (0x58000000)
7599 # define ldr_R0_mask(i) (i & 0xffffffe0)
7600 # define ldr_R0_x0 (0xf9400000)
7601 # define ldr_hw_R0 (0xf2a00000)
7602 # define movk_R0 (0xf2800000)
7603 # define movz_R0 (0xd2a00000)
7604 # define movz_hw_R0 (0xd2c00000)
7605 #else /*ARCH_SIZE == 32 */
7606 # define add_R0_R0 (0x11000000)
7607 # define add_R0_R0_R1 (0x0b000020)
7608 # define add_R0_R1 (0x11400020)
7609 # define ldr_R0 (0x18000000)
7610 # define ldr_R0_mask(i) (i & 0xbfffffe0)
7611 # define ldr_R0_x0 (0xb9400000)
7612 # define ldr_hw_R0 (0x72a00000)
7613 # define movk_R0 (0x72800000)
7614 # define movz_R0 (0x52a00000)
7615 # define movz_hw_R0 (0x52c00000)
7618 /* Structure to hold payload for _bfd_aarch64_erratum_843419_clear_stub,
7619 it is used to identify the stub information to reset. */
7621 struct erratum_843419_branch_to_stub_clear_data
7623 bfd_vma adrp_offset
;
7624 asection
*output_section
;
7627 /* Clear the erratum information for GEN_ENTRY if the ADRP_OFFSET and
7628 section inside IN_ARG matches. The clearing is done by setting the
7629 stub_type to none. */
7632 _bfd_aarch64_erratum_843419_clear_stub (struct bfd_hash_entry
*gen_entry
,
7635 struct elf_aarch64_stub_hash_entry
*stub_entry
7636 = (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
7637 struct erratum_843419_branch_to_stub_clear_data
*data
7638 = (struct erratum_843419_branch_to_stub_clear_data
*) in_arg
;
7640 if (stub_entry
->target_section
!= data
->output_section
7641 || stub_entry
->stub_type
!= aarch64_stub_erratum_843419_veneer
7642 || stub_entry
->adrp_offset
!= data
->adrp_offset
)
7645 /* Change the stub type instead of removing the entry, removing from the hash
7646 table would be slower and we have already reserved the memory for the entry
7647 so there wouldn't be much gain. Changing the stub also keeps around a
7648 record of what was there before. */
7649 stub_entry
->stub_type
= aarch64_stub_none
;
7651 /* We're done and there could have been only one matching stub at that
7652 particular offset, so abort further traversal. */
7656 /* TLS Relaxations may relax an adrp sequence that matches the erratum 843419
7657 sequence. In this case the erratum no longer applies and we need to remove
7658 the entry from the pending stub generation. This clears matching adrp insn
7659 at ADRP_OFFSET in INPUT_SECTION in the stub table defined in GLOBALS. */
7662 clear_erratum_843419_entry (struct elf_aarch64_link_hash_table
*globals
,
7663 bfd_vma adrp_offset
, asection
*input_section
)
7665 if (globals
->fix_erratum_843419
& ERRAT_ADRP
)
7667 struct erratum_843419_branch_to_stub_clear_data data
;
7668 data
.adrp_offset
= adrp_offset
;
7669 data
.output_section
= input_section
;
7671 bfd_hash_traverse (&globals
->stub_hash_table
,
7672 _bfd_aarch64_erratum_843419_clear_stub
, &data
);
7676 #define BUILD_MOVZ(_reg, _imm) (movz_R0 \
7677 | ((((_imm) >> 16) & 0xffff) << 5) \
7679 #define BUILD_MOVK(_reg, _imm) (movk_R0 | (((_imm) & 0xffff) << 5) | (_reg))
7681 /* Handle TLS relaxations. Relaxing is possible for symbols that use
7682 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
7685 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
7686 is to then call final_link_relocate. Return other values in the
7689 static bfd_reloc_status_type
7690 elfNN_aarch64_tls_relax (bfd
*input_bfd
, struct bfd_link_info
*info
,
7691 asection
*input_section
,
7692 bfd_byte
*contents
, Elf_Internal_Rela
*rel
,
7693 struct elf_link_hash_entry
*h
, unsigned long r_symndx
)
7695 bfd_boolean is_local
= h
== NULL
;
7697 unsigned int r_type
= ELFNN_R_TYPE (rel
->r_info
);
7699 bfd_vma sym_size
= 0;
7700 struct elf_aarch64_link_hash_table
*globals
= elf_aarch64_hash_table (info
);
7702 BFD_ASSERT (globals
&& input_bfd
&& contents
&& rel
);
7704 if (is_local
|| !bfd_link_pic (info
))
7710 Elf_Internal_Sym
*sym
;
7712 sym
= bfd_sym_from_r_symndx (&globals
->root
.sym_cache
, input_bfd
,
7714 BFD_ASSERT (sym
!= NULL
);
7715 sym_size
= sym
->st_size
;
7719 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
))
7721 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
7722 if (is_local
|| !bfd_link_pic (info
))
7724 /* GD->LE relaxation:
7725 nop => movz x1, objsize_hi16
7726 adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var */
7727 bfd_putl32 (BUILD_MOVZ(1, sym_size
), contents
+ rel
->r_offset
- 4);
7728 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
7730 /* We have relaxed the adrp into a mov, we may have to clear any
7731 pending erratum fixes. */
7732 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
7733 return bfd_reloc_continue
;
7737 /* GD->IE relaxation: Not implemented. */
7738 return bfd_reloc_continue
;
7740 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
7741 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
7744 /* GD->LE relaxation:
7745 adrp x0, :tlsgd:var => movz R0, :tprel_g1:var
7747 adrp x0, :tlsdesc:var => movz R0, :tprel_g1:var
7749 Where R is x for LP64, and w for ILP32. */
7750 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
7751 /* We have relaxed the adrp into a mov, we may have to clear any
7752 pending erratum fixes. */
7753 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
7754 return bfd_reloc_continue
;
7758 /* GD->IE relaxation:
7759 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
7761 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
7763 return bfd_reloc_continue
;
7766 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
7770 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
7773 /* Tiny TLSDESC->LE relaxation:
7774 ldr x1, :tlsdesc:var => movz R0, #:tprel_g1:var
7775 adr x0, :tlsdesc:var => movk R0, #:tprel_g0_nc:var
7779 Where R is x for LP64, and w for ILP32. */
7780 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
7781 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
7783 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7784 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
7785 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7787 bfd_putl32 (movz_R0
, contents
+ rel
->r_offset
);
7788 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
+ 4);
7789 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
7790 return bfd_reloc_continue
;
7794 /* Tiny TLSDESC->IE relaxation:
7795 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
7796 adr x0, :tlsdesc:var => nop
7800 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSDESC_ADR_PREL21
));
7801 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (TLSDESC_CALL
));
7803 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7804 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7806 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
);
7807 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
7808 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 8);
7809 return bfd_reloc_continue
;
7812 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
7815 /* Tiny GD->LE relaxation:
7816 adr x0, :tlsgd:var => mrs x1, tpidr_el0
7817 bl __tls_get_addr => add R0, R1, #:tprel_hi12:x, lsl #12
7818 nop => add R0, R0, #:tprel_lo12_nc:x
7820 Where R is x for LP64, and x for Ilp32. */
7822 /* First kill the tls_get_addr reloc on the bl instruction. */
7823 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
7825 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 0);
7826 bfd_putl32 (add_R0_R1
, contents
+ rel
->r_offset
+ 4);
7827 bfd_putl32 (add_R0_R0
, contents
+ rel
->r_offset
+ 8);
7829 rel
[1].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7830 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC
));
7831 rel
[1].r_offset
= rel
->r_offset
+ 8;
7833 /* Move the current relocation to the second instruction in
7836 rel
->r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7837 AARCH64_R (TLSLE_ADD_TPREL_HI12
));
7838 return bfd_reloc_continue
;
7842 /* Tiny GD->IE relaxation:
7843 adr x0, :tlsgd:var => ldr R0, :gottprel:var
7844 bl __tls_get_addr => mrs x1, tpidr_el0
7845 nop => add R0, R0, R1
7847 Where R is x for LP64, and w for Ilp32. */
7849 /* First kill the tls_get_addr reloc on the bl instruction. */
7850 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
7851 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7853 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
);
7854 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
7855 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 8);
7856 return bfd_reloc_continue
;
7860 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
7861 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (TLSGD_MOVW_G0_NC
));
7862 BFD_ASSERT (rel
->r_offset
+ 12 == rel
[2].r_offset
);
7863 BFD_ASSERT (ELFNN_R_TYPE (rel
[2].r_info
) == AARCH64_R (CALL26
));
7867 /* Large GD->LE relaxation:
7868 movz x0, #:tlsgd_g1:var => movz x0, #:tprel_g2:var, lsl #32
7869 movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
7870 add x0, gp, x0 => movk x0, #:tprel_g0_nc:var
7871 bl __tls_get_addr => mrs x1, tpidr_el0
7872 nop => add x0, x0, x1
7874 rel
[2].r_info
= ELFNN_R_INFO (ELFNN_R_SYM (rel
->r_info
),
7875 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC
));
7876 rel
[2].r_offset
= rel
->r_offset
+ 8;
7878 bfd_putl32 (movz_hw_R0
, contents
+ rel
->r_offset
+ 0);
7879 bfd_putl32 (ldr_hw_R0
, contents
+ rel
->r_offset
+ 4);
7880 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
+ 8);
7881 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 12);
7882 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 16);
7886 /* Large GD->IE relaxation:
7887 movz x0, #:tlsgd_g1:var => movz x0, #:gottprel_g1:var, lsl #16
7888 movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
7889 add x0, gp, x0 => ldr x0, [gp, x0]
7890 bl __tls_get_addr => mrs x1, tpidr_el0
7891 nop => add x0, x0, x1
7893 rel
[2].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7894 bfd_putl32 (0xd2a80000, contents
+ rel
->r_offset
+ 0);
7895 bfd_putl32 (ldr_R0
, contents
+ rel
->r_offset
+ 8);
7896 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 12);
7897 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 16);
7899 return bfd_reloc_continue
;
7901 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
7902 return bfd_reloc_continue
;
7905 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
7906 return bfd_reloc_continue
;
7908 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
7909 if (is_local
|| !bfd_link_pic (info
))
7911 /* GD->LE relaxation:
7912 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var */
7913 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
7914 return bfd_reloc_continue
;
7918 /* GD->IE relaxation: not implemented. */
7919 return bfd_reloc_continue
;
7921 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
7924 /* GD->LE relaxation:
7925 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
7927 Where R is x for lp64 mode, and w for ILP32 mode. */
7928 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
7929 return bfd_reloc_continue
;
7933 /* GD->IE relaxation:
7934 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr R0, [x0, #:gottprel_lo12:var]
7936 Where R is x for lp64 mode, and w for ILP32 mode. */
7937 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
7938 bfd_putl32 (ldr_R0_mask (insn
), contents
+ rel
->r_offset
);
7939 return bfd_reloc_continue
;
7942 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
7945 /* GD->LE relaxation
7946 add x0, #:tlsgd_lo12:var => movk R0, :tprel_g0_nc:var
7947 bl __tls_get_addr => mrs x1, tpidr_el0
7948 nop => add R0, R1, R0
7950 Where R is x for lp64 mode, and w for ILP32 mode. */
7952 /* First kill the tls_get_addr reloc on the bl instruction. */
7953 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
7954 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7956 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
7957 bfd_putl32 (0xd53bd041, contents
+ rel
->r_offset
+ 4);
7958 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
->r_offset
+ 8);
7959 return bfd_reloc_continue
;
7963 /* GD->IE relaxation
7964 ADD x0, #:tlsgd_lo12:var => ldr R0, [x0, #:gottprel_lo12:var]
7965 BL __tls_get_addr => mrs x1, tpidr_el0
7967 NOP => add R0, R1, R0
7969 Where R is x for lp64 mode, and w for ilp32 mode. */
7971 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
7973 /* Remove the relocation on the BL instruction. */
7974 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
7976 /* We choose to fixup the BL and NOP instructions using the
7977 offset from the second relocation to allow flexibility in
7978 scheduling instructions between the ADD and BL. */
7979 bfd_putl32 (ldr_R0_x0
, contents
+ rel
->r_offset
);
7980 bfd_putl32 (0xd53bd041, contents
+ rel
[1].r_offset
);
7981 bfd_putl32 (add_R0_R0_R1
, contents
+ rel
[1].r_offset
+ 4);
7982 return bfd_reloc_continue
;
7985 case BFD_RELOC_MORELLO_TLSDESC_CALL
:
7986 /* GD->LE relaxation:
7987 blr cd => add c0, c2, x0 */
7988 if (is_local
|| !bfd_link_pic (info
))
7990 bfd_putl32 (0xc2a06040, contents
+ rel
->r_offset
);
7991 return bfd_reloc_ok
;
7996 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
7997 /* GD->LE relaxation:
7998 ldr cd, [c0, #:tlsdesc_lo12:var] => movk x1, objsize_lo16 */
7999 if ((is_local
|| !bfd_link_pic (info
))
8000 && ELFNN_R_TYPE (rel
[1].r_info
) == MORELLO_R (TLSDESC_CALL
))
8002 bfd_putl32 (BUILD_MOVK(1, sym_size
), contents
+ rel
->r_offset
);
8003 return bfd_reloc_continue
;
8007 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
8008 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
8009 /* GD->IE/LE relaxation:
8010 add x0, x0, #:tlsdesc_lo12:var => nop
8014 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
);
8015 return bfd_reloc_ok
;
8017 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
8020 /* GD->LE relaxation:
8021 ldr xd, [gp, xn] => movk R0, #:tprel_g0_nc:var
8023 Where R is x for lp64 mode, and w for ILP32 mode. */
8024 bfd_putl32 (movk_R0
, contents
+ rel
->r_offset
);
8025 return bfd_reloc_continue
;
8029 /* GD->IE relaxation:
8030 ldr xd, [gp, xn] => ldr R0, [gp, xn]
8032 Where R is x for lp64 mode, and w for ILP32 mode. */
8033 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8034 bfd_putl32 (ldr_R0_mask (insn
), contents
+ rel
->r_offset
);
8035 return bfd_reloc_ok
;
8038 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
8039 /* GD->LE relaxation:
8040 movk xd, #:tlsdesc_off_g0_nc:var => movk R0, #:tprel_g1_nc:var, lsl #16
8042 movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
8044 Where R is x for lp64 mode, and w for ILP32 mode. */
8046 bfd_putl32 (ldr_hw_R0
, contents
+ rel
->r_offset
);
8047 return bfd_reloc_continue
;
8049 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
8052 /* GD->LE relaxation:
8053 movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
8055 Where R is x for lp64 mode, and w for ILP32 mode. */
8056 bfd_putl32 (movz_hw_R0
, contents
+ rel
->r_offset
);
8057 return bfd_reloc_continue
;
8061 /* GD->IE relaxation:
8062 movz xd, #:tlsdesc_off_g1:var => movz Rd, #:gottprel_g1:var, lsl #16
8064 Where R is x for lp64 mode, and w for ILP32 mode. */
8065 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8066 bfd_putl32 (movz_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
8067 return bfd_reloc_continue
;
8070 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
8071 /* IE->LE relaxation:
8072 adrp xd, :gottprel:var => movz Rd, :tprel_g1:var
8074 Where R is x for lp64 mode, and w for ILP32 mode. */
8077 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8078 bfd_putl32 (movz_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
8079 /* We have relaxed the adrp into a mov, we may have to clear any
8080 pending erratum fixes. */
8081 clear_erratum_843419_entry (globals
, rel
->r_offset
, input_section
);
8083 return bfd_reloc_continue
;
8085 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
8086 /* IE->LE relaxation:
8087 ldr xd, [xm, #:gottprel_lo12:var] => movk Rd, :tprel_g0_nc:var
8089 Where R is x for lp64 mode, and w for ILP32 mode. */
8092 insn
= bfd_getl32 (contents
+ rel
->r_offset
);
8093 bfd_putl32 (movk_R0
| (insn
& 0x1f), contents
+ rel
->r_offset
);
8095 return bfd_reloc_continue
;
8097 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
8098 /* LD->LE relaxation (tiny):
8099 adr x0, :tlsldm:x => mrs x0, tpidr_el0
8100 bl __tls_get_addr => add R0, R0, TCB_SIZE
8102 Where R is x for lp64 mode, and w for ilp32 mode. */
8105 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
8106 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
8107 /* No need of CALL26 relocation for tls_get_addr. */
8108 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
8109 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
+ 0);
8110 bfd_putl32 (add_R0_R0
| (TCB_SIZE (input_bfd
) << 10),
8111 contents
+ rel
->r_offset
+ 4);
8112 return bfd_reloc_ok
;
8114 return bfd_reloc_continue
;
8116 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
8117 /* LD->LE relaxation (small):
8118 adrp x0, :tlsldm:x => mrs x0, tpidr_el0
8122 bfd_putl32 (0xd53bd040, contents
+ rel
->r_offset
);
8123 return bfd_reloc_ok
;
8125 return bfd_reloc_continue
;
8127 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
8128 /* LD->LE relaxation (small):
8129 add x0, #:tlsldm_lo12:x => add R0, R0, TCB_SIZE
8130 bl __tls_get_addr => nop
8132 Where R is x for lp64 mode, and w for ilp32 mode. */
8135 BFD_ASSERT (rel
->r_offset
+ 4 == rel
[1].r_offset
);
8136 BFD_ASSERT (ELFNN_R_TYPE (rel
[1].r_info
) == AARCH64_R (CALL26
));
8137 /* No need of CALL26 relocation for tls_get_addr. */
8138 rel
[1].r_info
= ELFNN_R_INFO (STN_UNDEF
, R_AARCH64_NONE
);
8139 bfd_putl32 (add_R0_R0
| (TCB_SIZE (input_bfd
) << 10),
8140 contents
+ rel
->r_offset
+ 0);
8141 bfd_putl32 (INSN_NOP
, contents
+ rel
->r_offset
+ 4);
8142 return bfd_reloc_ok
;
8144 return bfd_reloc_continue
;
8147 return bfd_reloc_continue
;
8150 return bfd_reloc_ok
;
8153 /* Relocate an AArch64 ELF section. */
8156 elfNN_aarch64_relocate_section (bfd
*output_bfd
,
8157 struct bfd_link_info
*info
,
8159 asection
*input_section
,
8161 Elf_Internal_Rela
*relocs
,
8162 Elf_Internal_Sym
*local_syms
,
8163 asection
**local_sections
)
8165 Elf_Internal_Shdr
*symtab_hdr
;
8166 struct elf_link_hash_entry
**sym_hashes
;
8167 Elf_Internal_Rela
*rel
;
8168 Elf_Internal_Rela
*relend
;
8170 struct elf_aarch64_link_hash_table
*globals
;
8171 bfd_boolean save_addend
= FALSE
;
8174 globals
= elf_aarch64_hash_table (info
);
8176 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
8177 sym_hashes
= elf_sym_hashes (input_bfd
);
8180 relend
= relocs
+ input_section
->reloc_count
;
8181 for (; rel
< relend
; rel
++)
8183 unsigned int r_type
;
8184 bfd_reloc_code_real_type bfd_r_type
;
8185 bfd_reloc_code_real_type relaxed_bfd_r_type
;
8186 reloc_howto_type
*howto
;
8187 unsigned long r_symndx
;
8188 Elf_Internal_Sym
*sym
;
8190 struct elf_link_hash_entry
*h
;
8192 bfd_reloc_status_type r
;
8195 bfd_boolean unresolved_reloc
= FALSE
;
8196 char *error_message
= NULL
;
8198 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
8199 r_type
= ELFNN_R_TYPE (rel
->r_info
);
8201 bfd_reloc
.howto
= elfNN_aarch64_howto_from_type (input_bfd
, r_type
);
8202 howto
= bfd_reloc
.howto
;
8205 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
8207 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_howto (howto
);
8213 if (r_symndx
< symtab_hdr
->sh_info
)
8215 sym
= local_syms
+ r_symndx
;
8216 sym_type
= ELFNN_ST_TYPE (sym
->st_info
);
8217 sec
= local_sections
[r_symndx
];
8219 /* An object file might have a reference to a local
8220 undefined symbol. This is a daft object file, but we
8221 should at least do something about it. */
8222 if (r_type
!= R_AARCH64_NONE
&& r_type
!= R_AARCH64_NULL
8223 && bfd_is_und_section (sec
)
8224 && ELF_ST_BIND (sym
->st_info
) != STB_WEAK
)
8225 (*info
->callbacks
->undefined_symbol
)
8226 (info
, bfd_elf_string_from_elf_section
8227 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
),
8228 input_bfd
, input_section
, rel
->r_offset
, TRUE
);
8230 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
8232 /* Relocate against local STT_GNU_IFUNC symbol. */
8233 if (!bfd_link_relocatable (info
)
8234 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
8236 h
= elfNN_aarch64_get_local_sym_hash (globals
, input_bfd
,
8241 /* Set STT_GNU_IFUNC symbol value. */
8242 h
->root
.u
.def
.value
= sym
->st_value
;
8243 h
->root
.u
.def
.section
= sec
;
8248 bfd_boolean warned
, ignored
;
8250 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
8251 r_symndx
, symtab_hdr
, sym_hashes
,
8253 unresolved_reloc
, warned
, ignored
);
8258 if (sec
!= NULL
&& discarded_section (sec
))
8259 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
8260 rel
, 1, relend
, howto
, 0, contents
);
8262 if (bfd_link_relocatable (info
))
8266 name
= h
->root
.root
.string
;
8269 name
= (bfd_elf_string_from_elf_section
8270 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
8271 if (name
== NULL
|| *name
== '\0')
8272 name
= bfd_section_name (sec
);
8276 && r_type
!= R_AARCH64_NONE
8277 && r_type
!= R_AARCH64_NULL
8279 || h
->root
.type
== bfd_link_hash_defined
8280 || h
->root
.type
== bfd_link_hash_defweak
)
8281 && IS_AARCH64_TLS_RELOC (bfd_r_type
) != (sym_type
== STT_TLS
))
8284 ((sym_type
== STT_TLS
8285 /* xgettext:c-format */
8286 ? _("%pB(%pA+%#" PRIx64
"): %s used with TLS symbol %s")
8287 /* xgettext:c-format */
8288 : _("%pB(%pA+%#" PRIx64
"): %s used with non-TLS symbol %s")),
8290 input_section
, (uint64_t) rel
->r_offset
, howto
->name
, name
);
8295 && IS_AARCH64_TLS_RELOC (bfd_r_type
)
8296 && h
->root
.type
== bfd_link_hash_undefweak
)
8297 /* We have already warned about these in aarch64_check_relocs,
8298 so just skip over them. */
8301 /* We relax only if we can see that there can be a valid transition
8302 from a reloc type to another.
8303 We call elfNN_aarch64_final_link_relocate unless we're completely
8304 done, i.e., the relaxation produced the final output we want. */
8306 relaxed_bfd_r_type
= aarch64_tls_transition (input_bfd
, info
, rel
,
8308 if (relaxed_bfd_r_type
!= bfd_r_type
)
8310 bfd_r_type
= relaxed_bfd_r_type
;
8311 howto
= elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type
);
8312 BFD_ASSERT (howto
!= NULL
);
8313 r_type
= howto
->type
;
8314 r
= elfNN_aarch64_tls_relax (input_bfd
, info
, input_section
,
8315 contents
, rel
, h
, r_symndx
);
8316 unresolved_reloc
= 0;
8319 r
= bfd_reloc_continue
;
8321 /* There may be multiple consecutive relocations for the
8322 same offset. In that case we are supposed to treat the
8323 output of each relocation as the addend for the next. */
8324 if (rel
+ 1 < relend
8325 && rel
->r_offset
== rel
[1].r_offset
8326 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NONE
8327 && ELFNN_R_TYPE (rel
[1].r_info
) != R_AARCH64_NULL
)
8330 save_addend
= FALSE
;
8332 if (r
== bfd_reloc_continue
)
8333 r
= elfNN_aarch64_final_link_relocate (howto
, input_bfd
, output_bfd
,
8334 input_section
, contents
, rel
,
8335 relocation
, info
, sec
,
8336 h
, &unresolved_reloc
,
8337 save_addend
, &addend
, sym
);
8339 bfd_boolean c64_rtype
= FALSE
;
8341 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
))
8343 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
8344 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
8345 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
8346 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
8347 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
8348 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
8349 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
8350 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
8351 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
8353 bfd_boolean need_relocs
= FALSE
;
8358 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
8359 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8362 (!bfd_link_executable (info
) || indx
!= 0) &&
8364 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8365 || h
->root
.type
!= bfd_link_hash_undefweak
);
8367 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
8371 Elf_Internal_Rela rela
;
8372 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPMOD
));
8374 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
8375 globals
->root
.sgot
->output_offset
+ off
;
8378 loc
= globals
->root
.srelgot
->contents
;
8379 loc
+= globals
->root
.srelgot
->reloc_count
++
8380 * RELOC_SIZE (htab
);
8381 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8383 bfd_reloc_code_real_type real_type
=
8384 elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
8386 if (real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
8387 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
8388 || real_type
== BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
)
8390 /* For local dynamic, don't generate DTPREL in any case.
8391 Initialize the DTPREL slot into zero, so we get module
8392 base address when invoke runtime TLS resolver. */
8393 bfd_put_NN (output_bfd
, 0,
8394 globals
->root
.sgot
->contents
+ off
8395 + GOT_ENTRY_SIZE (globals
));
8399 bfd_put_NN (output_bfd
,
8400 relocation
- dtpoff_base (info
),
8401 globals
->root
.sgot
->contents
+ off
8402 + GOT_ENTRY_SIZE (globals
));
8406 /* This TLS symbol is global. We emit a
8407 relocation to fixup the tls offset at load
8410 ELFNN_R_INFO (indx
, AARCH64_R (TLS_DTPREL
));
8413 (globals
->root
.sgot
->output_section
->vma
8414 + globals
->root
.sgot
->output_offset
+ off
8415 + GOT_ENTRY_SIZE (globals
));
8417 loc
= globals
->root
.srelgot
->contents
;
8418 loc
+= globals
->root
.srelgot
->reloc_count
++
8419 * RELOC_SIZE (globals
);
8420 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8421 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8422 globals
->root
.sgot
->contents
+ off
8423 + GOT_ENTRY_SIZE (globals
));
8428 bfd_put_NN (output_bfd
, (bfd_vma
) 1,
8429 globals
->root
.sgot
->contents
+ off
);
8430 bfd_put_NN (output_bfd
,
8431 relocation
- dtpoff_base (info
),
8432 globals
->root
.sgot
->contents
+ off
8433 + GOT_ENTRY_SIZE (globals
));
8436 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
8440 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
8441 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC
:
8442 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
8443 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
8444 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
8445 if (! symbol_got_offset_mark_p (input_bfd
, h
, r_symndx
))
8447 bfd_boolean need_relocs
= FALSE
;
8452 off
= symbol_got_offset (input_bfd
, h
, r_symndx
);
8454 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8457 (!bfd_link_executable (info
) || indx
!= 0) &&
8459 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8460 || h
->root
.type
!= bfd_link_hash_undefweak
);
8462 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
8466 Elf_Internal_Rela rela
;
8469 rela
.r_addend
= relocation
- dtpoff_base (info
);
8473 rela
.r_info
= ELFNN_R_INFO (indx
, AARCH64_R (TLS_TPREL
));
8474 rela
.r_offset
= globals
->root
.sgot
->output_section
->vma
+
8475 globals
->root
.sgot
->output_offset
+ off
;
8477 loc
= globals
->root
.srelgot
->contents
;
8478 loc
+= globals
->root
.srelgot
->reloc_count
++
8479 * RELOC_SIZE (htab
);
8481 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8483 bfd_put_NN (output_bfd
, rela
.r_addend
,
8484 globals
->root
.sgot
->contents
+ off
);
8487 bfd_put_NN (output_bfd
, relocation
- tpoff_base (info
),
8488 globals
->root
.sgot
->contents
+ off
);
8490 symbol_got_offset_mark (input_bfd
, h
, r_symndx
);
8494 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
8495 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
8499 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
8500 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
8501 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
8502 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC
:
8503 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
8504 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
8505 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
8506 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd
, h
, r_symndx
))
8508 bfd_boolean need_relocs
= FALSE
;
8509 int indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
8510 bfd_vma off
= symbol_tlsdesc_got_offset (input_bfd
, h
, r_symndx
);
8512 need_relocs
= (h
== NULL
8513 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
8514 || h
->root
.type
!= bfd_link_hash_undefweak
);
8516 BFD_ASSERT (globals
->root
.srelgot
!= NULL
);
8517 BFD_ASSERT (globals
->root
.sgot
!= NULL
);
8522 Elf_Internal_Rela rela
;
8524 rela
.r_info
= ELFNN_R_INFO (indx
,
8525 (c64_rtype
? MORELLO_R (TLSDESC
)
8526 : AARCH64_R (TLSDESC
)));
8529 rela
.r_offset
= (globals
->root
.sgotplt
->output_section
->vma
8530 + globals
->root
.sgotplt
->output_offset
8531 + off
+ globals
->sgotplt_jump_table_size
);
8534 rela
.r_addend
= relocation
- dtpoff_base (info
);
8536 /* Allocate the next available slot in the PLT reloc
8537 section to hold our R_AARCH64_TLSDESC, the next
8538 available slot is determined from reloc_count,
8539 which we step. But note, reloc_count was
8540 artifically moved down while allocating slots for
8541 real PLT relocs such that all of the PLT relocs
8542 will fit above the initial reloc_count and the
8543 extra stuff will fit below. */
8544 loc
= globals
->root
.srelplt
->contents
;
8545 loc
+= globals
->root
.srelplt
->reloc_count
++
8546 * RELOC_SIZE (globals
);
8548 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
8550 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8551 globals
->root
.sgotplt
->contents
+ off
+
8552 globals
->sgotplt_jump_table_size
);
8553 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
8554 globals
->root
.sgotplt
->contents
+ off
+
8555 globals
->sgotplt_jump_table_size
+
8556 GOT_ENTRY_SIZE (globals
));
8559 symbol_tlsdesc_got_offset_mark (input_bfd
, h
, r_symndx
);
8566 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
8567 because such sections are not SEC_ALLOC and thus ld.so will
8568 not process them. */
8569 if (unresolved_reloc
8570 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
8572 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
8573 +rel
->r_offset
) != (bfd_vma
) - 1)
8576 /* xgettext:c-format */
8577 (_("%pB(%pA+%#" PRIx64
"): "
8578 "unresolvable %s relocation against symbol `%s'"),
8579 input_bfd
, input_section
, (uint64_t) rel
->r_offset
, howto
->name
,
8580 h
->root
.root
.string
);
8584 if (r
!= bfd_reloc_ok
&& r
!= bfd_reloc_continue
)
8586 bfd_reloc_code_real_type real_r_type
8587 = elfNN_aarch64_bfd_reloc_from_type (input_bfd
, r_type
);
8591 case bfd_reloc_overflow
:
8592 (*info
->callbacks
->reloc_overflow
)
8593 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
8594 input_bfd
, input_section
, rel
->r_offset
);
8595 if (real_r_type
== BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
8596 || real_r_type
== BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
)
8598 (*info
->callbacks
->warning
)
8600 _("too many GOT entries for -fpic, "
8601 "please recompile with -fPIC"),
8602 name
, input_bfd
, input_section
, rel
->r_offset
);
8605 /* Overflow can occur when a variable is referenced with a type
8606 that has a larger alignment than the type with which it was
8608 file1.c: extern int foo; int a (void) { return foo; }
8609 file2.c: char bar, foo, baz;
8610 If the variable is placed into a data section at an offset
8611 that is incompatible with the larger alignment requirement
8612 overflow will occur. (Strictly speaking this is not overflow
8613 but rather an alignment problem, but the bfd_reloc_ error
8614 enum does not have a value to cover that situation).
8616 Try to catch this situation here and provide a more helpful
8617 error message to the user. */
8618 if (addend
& (((bfd_vma
) 1 << howto
->rightshift
) - 1)
8619 /* FIXME: Are we testing all of the appropriate reloc
8621 && (real_r_type
== BFD_RELOC_AARCH64_LD_LO19_PCREL
8622 || real_r_type
== BFD_RELOC_AARCH64_LDST16_LO12
8623 || real_r_type
== BFD_RELOC_AARCH64_LDST32_LO12
8624 || real_r_type
== BFD_RELOC_AARCH64_LDST64_LO12
8625 || real_r_type
== BFD_RELOC_AARCH64_LDST128_LO12
))
8627 info
->callbacks
->warning
8628 (info
, _("one possible cause of this error is that the \
8629 symbol is being referenced in the indicated code as if it had a larger \
8630 alignment than was declared where it was defined"),
8631 name
, input_bfd
, input_section
, rel
->r_offset
);
8634 if (real_r_type
== BFD_RELOC_MORELLO_CAPINIT
)
8635 info
->callbacks
->warning
8636 (info
, _("relocation offset must be capability aligned"),
8637 name
, input_bfd
, input_section
, rel
->r_offset
);
8640 case bfd_reloc_undefined
:
8641 (*info
->callbacks
->undefined_symbol
)
8642 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
);
8645 case bfd_reloc_outofrange
:
8646 error_message
= _("out of range");
8649 case bfd_reloc_notsupported
:
8650 error_message
= _("unsupported relocation");
8653 case bfd_reloc_dangerous
:
8654 /* error_message should already be set. */
8658 error_message
= _("unknown error");
8662 BFD_ASSERT (error_message
!= NULL
);
8663 (*info
->callbacks
->reloc_dangerous
)
8664 (info
, error_message
, input_bfd
, input_section
, rel
->r_offset
);
8676 /* Set the right machine number. */
8679 elfNN_aarch64_object_p (bfd
*abfd
)
8682 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64_ilp32
);
8684 bfd_default_set_arch_mach (abfd
, bfd_arch_aarch64
, bfd_mach_aarch64
);
8689 /* Function to keep AArch64 specific flags in the ELF header. */
8692 elfNN_aarch64_set_private_flags (bfd
*abfd
, flagword flags
)
8694 if (elf_flags_init (abfd
) && elf_elfheader (abfd
)->e_flags
!= flags
)
8699 elf_elfheader (abfd
)->e_flags
= flags
;
8700 elf_flags_init (abfd
) = TRUE
;
8706 /* Merge backend specific data from an object file to the output
8707 object file when linking. */
8710 elfNN_aarch64_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
8712 bfd
*obfd
= info
->output_bfd
;
8715 bfd_boolean flags_compatible
= FALSE
;
8718 /* Check if we have the same endianess. */
8719 if (!_bfd_generic_verify_endian_match (ibfd
, info
))
8722 if (!is_aarch64_elf (ibfd
) || !is_aarch64_elf (obfd
))
8725 /* The input BFD must have had its flags initialised. */
8726 /* The following seems bogus to me -- The flags are initialized in
8727 the assembler but I don't think an elf_flags_init field is
8728 written into the object. */
8729 /* BFD_ASSERT (elf_flags_init (ibfd)); */
8731 in_flags
= elf_elfheader (ibfd
)->e_flags
;
8732 out_flags
= elf_elfheader (obfd
)->e_flags
;
8734 if (!elf_flags_init (obfd
))
8736 elf_flags_init (obfd
) = TRUE
;
8738 /* If the input is the default architecture and had the default
8739 flags then do not bother setting the flags for the output
8740 architecture, instead allow future merges to do this. If no
8741 future merges ever set these flags then they will retain their
8742 uninitialised values, which surprise surprise, correspond
8743 to the default values. */
8744 if (bfd_get_arch_info (ibfd
)->the_default
8745 && elf_elfheader (ibfd
)->e_flags
== 0)
8748 elf_elfheader (obfd
)->e_flags
= in_flags
;
8750 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
8751 && bfd_get_arch_info (obfd
)->the_default
)
8752 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
8753 bfd_get_mach (ibfd
));
8758 /* Identical flags must be compatible. */
8759 if (in_flags
== out_flags
)
8762 /* Check to see if the input BFD actually contains any sections. If
8763 not, its flags may not have been initialised either, but it
8764 cannot actually cause any incompatiblity. Do not short-circuit
8765 dynamic objects; their section list may be emptied by
8766 elf_link_add_object_symbols.
8768 Also check to see if there are no code sections in the input.
8769 In this case there is no need to check for code specific flags.
8770 XXX - do we need to worry about floating-point format compatability
8773 We definitely need to check for data sections if one set of flags is
8774 targetting the PURECAP abi and another is not. Pointers being
8775 capabilities in data sections can not be glossed over. */
8776 if (!(ibfd
->flags
& DYNAMIC
))
8778 bfd_boolean null_input_bfd
= TRUE
;
8779 bfd_boolean only_data_sections
8780 = !(in_flags
& EF_AARCH64_CHERI_PURECAP
8781 || out_flags
& EF_AARCH64_CHERI_PURECAP
);
8783 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
8785 if ((bfd_section_flags (sec
)
8786 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
8787 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
8788 only_data_sections
= FALSE
;
8790 null_input_bfd
= FALSE
;
8794 if (null_input_bfd
|| only_data_sections
)
8798 return flags_compatible
;
8801 /* Display the flags field. */
8804 elfNN_aarch64_print_private_bfd_data (bfd
*abfd
, void *ptr
)
8806 FILE *file
= (FILE *) ptr
;
8807 unsigned long flags
;
8809 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
8811 /* Print normal ELF private data. */
8812 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
8814 flags
= elf_elfheader (abfd
)->e_flags
;
8815 /* Ignore init flag - it may not be set, despite the flags field
8816 containing valid data. */
8818 /* xgettext:c-format */
8819 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
8822 fprintf (file
, _("<Unrecognised flag bits set>"));
8829 /* Return true if we need copy relocation against EH. */
8832 need_copy_relocation_p (struct elf_aarch64_link_hash_entry
*eh
)
8834 struct elf_dyn_relocs
*p
;
8837 for (p
= eh
->root
.dyn_relocs
; p
!= NULL
; p
= p
->next
)
8839 /* If there is any pc-relative reference, we need to keep copy relocation
8840 to avoid propagating the relocation into runtime that current glibc
8841 does not support. */
8845 s
= p
->sec
->output_section
;
8846 /* Need copy relocation if it's against read-only section. */
8847 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
8854 /* Adjust a symbol defined by a dynamic object and referenced by a
8855 regular object. The current definition is in some section of the
8856 dynamic object, but we're not including those sections. We have to
8857 change the definition to something the rest of the link can
8861 elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info
*info
,
8862 struct elf_link_hash_entry
*h
)
8864 struct elf_aarch64_link_hash_table
*htab
;
8867 /* If this is a function, put it in the procedure linkage table. We
8868 will fill in the contents of the procedure linkage table later,
8869 when we know the address of the .got section. */
8870 if (h
->type
== STT_FUNC
|| h
->type
== STT_GNU_IFUNC
|| h
->needs_plt
)
8872 if (h
->plt
.refcount
<= 0
8873 || (h
->type
!= STT_GNU_IFUNC
8874 && (SYMBOL_CALLS_LOCAL (info
, h
)
8875 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
8876 && h
->root
.type
== bfd_link_hash_undefweak
))))
8878 /* This case can occur if we saw a CALL26 reloc in
8879 an input file, but the symbol wasn't referred to
8880 by a dynamic object or all references were
8881 garbage collected. In which case we can end up
8883 h
->plt
.offset
= (bfd_vma
) - 1;
8890 /* Otherwise, reset to -1. */
8891 h
->plt
.offset
= (bfd_vma
) - 1;
8894 /* If this is a weak symbol, and there is a real definition, the
8895 processor independent code will have arranged for us to see the
8896 real definition first, and we can just use the same value. */
8897 if (h
->is_weakalias
)
8899 struct elf_link_hash_entry
*def
= weakdef (h
);
8900 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
8901 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
8902 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
8903 if (ELIMINATE_COPY_RELOCS
|| info
->nocopyreloc
)
8904 h
->non_got_ref
= def
->non_got_ref
;
8908 /* If we are creating a shared library, we must presume that the
8909 only references to the symbol are via the global offset table.
8910 For such cases we need not do anything here; the relocations will
8911 be handled correctly by relocate_section. */
8912 if (bfd_link_pic (info
))
8915 /* If there are no references to this symbol that do not use the
8916 GOT, we don't need to generate a copy reloc. */
8917 if (!h
->non_got_ref
)
8920 /* If -z nocopyreloc was given, we won't generate them either. */
8921 if (info
->nocopyreloc
)
8927 if (ELIMINATE_COPY_RELOCS
)
8929 struct elf_aarch64_link_hash_entry
*eh
;
8930 /* If we don't find any dynamic relocs in read-only sections, then
8931 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
8932 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
8933 if (!need_copy_relocation_p (eh
))
8940 /* We must allocate the symbol in our .dynbss section, which will
8941 become part of the .bss section of the executable. There will be
8942 an entry for this symbol in the .dynsym section. The dynamic
8943 object will contain position independent code, so all references
8944 from the dynamic object to this symbol will go through the global
8945 offset table. The dynamic linker will use the .dynsym entry to
8946 determine the address it must put in the global offset table, so
8947 both the dynamic object and the regular object will refer to the
8948 same memory location for the variable. */
8950 htab
= elf_aarch64_hash_table (info
);
8952 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
8953 to copy the initial value out of the dynamic object and into the
8954 runtime process image. */
8955 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
8957 s
= htab
->root
.sdynrelro
;
8958 srel
= htab
->root
.sreldynrelro
;
8962 s
= htab
->root
.sdynbss
;
8963 srel
= htab
->root
.srelbss
;
8965 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0 && h
->size
!= 0)
8967 srel
->size
+= RELOC_SIZE (htab
);
8971 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
8976 elfNN_aarch64_allocate_local_symbols (bfd
*abfd
, unsigned number
)
8978 struct elf_aarch64_local_symbol
*locals
;
8979 locals
= elf_aarch64_locals (abfd
);
8982 locals
= (struct elf_aarch64_local_symbol
*)
8983 bfd_zalloc (abfd
, number
* sizeof (struct elf_aarch64_local_symbol
));
8986 elf_aarch64_locals (abfd
) = locals
;
8991 /* Initialise the .got section to hold the global offset table. */
8994 aarch64_elf_init_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
8996 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
8998 struct elf_aarch64_link_hash_table
*globals
= elf_aarch64_hash_table (info
);
8999 unsigned int align
= bed
->s
->log_file_align
+ globals
->c64_rel
;
9001 if (globals
->root
.sgot
!= NULL
)
9003 bfd_set_section_alignment (globals
->root
.srelgot
,
9004 bed
->s
->log_file_align
);
9005 bfd_set_section_alignment (globals
->root
.sgot
, align
);
9006 globals
->root
.sgot
->size
+= GOT_ENTRY_SIZE (globals
);
9009 /* Track capability initialisation for static non-PIE binaries. */
9010 if (bfd_link_executable (info
) && !bfd_link_pic (info
)
9011 && globals
->srelcaps
== NULL
)
9012 globals
->srelcaps
= globals
->root
.srelgot
;
9014 if (globals
->root
.igotplt
!= NULL
)
9015 bfd_set_section_alignment (globals
->root
.igotplt
, align
);
9017 s
= globals
->root
.sgot
;
9019 if (globals
->root
.sgotplt
!= NULL
)
9021 bfd_set_section_alignment (globals
->root
.sgotplt
, align
);
9022 s
= globals
->root
.sgotplt
;
9025 /* The first bit of the global offset table is the header. */
9027 s
->size
+= bed
->got_header_size (info
);
9030 /* Create the .got section to hold the global offset table. */
9033 aarch64_elf_create_got_section (bfd
*abfd
, struct bfd_link_info
*info
)
9035 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
9038 struct elf_link_hash_entry
*h
;
9039 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
9041 /* This function may be called more than once. */
9042 if (htab
->sgot
!= NULL
)
9045 flags
= bed
->dynamic_sec_flags
;
9047 s
= bfd_make_section_anyway_with_flags (abfd
,
9048 (bed
->rela_plts_and_copies_p
9049 ? ".rela.got" : ".rel.got"),
9050 (bed
->dynamic_sec_flags
9056 s
= bfd_make_section_anyway_with_flags (abfd
, ".got", flags
);
9061 if (bed
->want_got_sym
)
9063 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
9064 (or .got.plt) section. We don't do this in the linker script
9065 because we don't want to define the symbol if we are not creating
9066 a global offset table. */
9067 h
= _bfd_elf_define_linkage_sym (abfd
, info
, s
,
9068 "_GLOBAL_OFFSET_TABLE_");
9069 elf_hash_table (info
)->hgot
= h
;
9074 if (bed
->want_got_plt
)
9076 s
= bfd_make_section_anyway_with_flags (abfd
, ".got.plt", flags
);
9085 /* Look through the relocs for a section during the first phase. */
9088 elfNN_aarch64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
9089 asection
*sec
, const Elf_Internal_Rela
*relocs
)
9091 Elf_Internal_Shdr
*symtab_hdr
;
9092 struct elf_link_hash_entry
**sym_hashes
;
9093 const Elf_Internal_Rela
*rel
;
9094 const Elf_Internal_Rela
*rel_end
;
9097 struct elf_aarch64_link_hash_table
*htab
;
9099 if (bfd_link_relocatable (info
))
9102 BFD_ASSERT (is_aarch64_elf (abfd
));
9104 htab
= elf_aarch64_hash_table (info
);
9107 symtab_hdr
= &elf_symtab_hdr (abfd
);
9108 sym_hashes
= elf_sym_hashes (abfd
);
9110 bfd_elfNN_aarch64_init_maps (abfd
, info
);
9112 rel_end
= relocs
+ sec
->reloc_count
;
9113 for (rel
= relocs
; rel
< rel_end
; rel
++)
9115 struct elf_link_hash_entry
*h
;
9116 unsigned int r_symndx
, r_type
;
9117 bfd_reloc_code_real_type bfd_r_type
;
9118 Elf_Internal_Sym
*isym
;
9120 r_symndx
= ELFNN_R_SYM (rel
->r_info
);
9121 r_type
= ELFNN_R_TYPE (rel
->r_info
);
9122 bfd_r_type
= elfNN_aarch64_bfd_reloc_from_type (abfd
, r_type
);
9124 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
9126 /* xgettext:c-format */
9127 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd
, r_symndx
);
9131 if (r_symndx
< symtab_hdr
->sh_info
)
9133 /* A local symbol. */
9134 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
9139 /* Check relocation against local STT_GNU_IFUNC symbol. */
9140 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
9142 h
= elfNN_aarch64_get_local_sym_hash (htab
, abfd
, rel
,
9147 /* Fake a STT_GNU_IFUNC symbol. */
9148 h
->type
= STT_GNU_IFUNC
;
9151 h
->forced_local
= 1;
9152 h
->root
.type
= bfd_link_hash_defined
;
9159 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
9160 while (h
->root
.type
== bfd_link_hash_indirect
9161 || h
->root
.type
== bfd_link_hash_warning
)
9162 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
9165 /* Ignore TLS relocations against weak undef symbols and warn about them.
9166 The behaviour of weak TLS variables is not well defined. Since making
9167 these well behaved is not a priority for Morello, we simply ignore
9168 TLS relocations against such symbols here to avoid the linker crashing
9169 on these and to enable making progress in other areas. */
9172 && IS_AARCH64_TLS_RELOC (bfd_r_type
)
9173 && h
->root
.type
== bfd_link_hash_undefweak
)
9175 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9176 _bfd_error_handler (_("%pB(%pA+%#" PRIx64
"): ignoring TLS relocation "
9177 "%s against undef weak symbol %s"),
9179 (uint64_t) rel
->r_offset
,
9180 elfNN_aarch64_howto_table
[howto_index
].name
,
9181 h
->root
.root
.string
);
9185 /* Could be done earlier, if h were already available. */
9186 bfd_r_type
= aarch64_tls_transition (abfd
, info
, rel
, h
, r_symndx
);
9190 /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
9191 This shows up in particular in an R_AARCH64_PREL64 in large model
9192 when calculating the pc-relative address to .got section which is
9193 used to initialize the gp register. */
9194 if (h
->root
.root
.string
9195 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
9197 if (htab
->root
.dynobj
== NULL
)
9198 htab
->root
.dynobj
= abfd
;
9200 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
9203 BFD_ASSERT (h
== htab
->root
.hgot
);
9206 /* Create the ifunc sections for static executables. If we
9207 never see an indirect function symbol nor we are building
9208 a static executable, those sections will be empty and
9209 won't appear in output. */
9215 case BFD_RELOC_MORELLO_CALL26
:
9216 case BFD_RELOC_MORELLO_JUMP26
:
9217 /* For dynamic symbols record caller information so that we can
9218 decide what kind of PLT stubs to emit. */
9220 elf_aarch64_hash_entry (h
)->got_type
= GOT_CAP
;
9223 case BFD_RELOC_AARCH64_ADD_LO12
:
9224 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
9225 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
9226 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
9227 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
9228 case BFD_RELOC_AARCH64_CALL26
:
9229 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
9230 case BFD_RELOC_AARCH64_JUMP26
:
9231 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
9232 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
9233 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
9234 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
9235 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
9236 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
9237 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
9238 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
9239 case BFD_RELOC_AARCH64_NN
:
9240 if (htab
->root
.dynobj
== NULL
)
9241 htab
->root
.dynobj
= abfd
;
9242 if (!_bfd_elf_create_ifunc_sections (htab
->root
.dynobj
, info
))
9247 /* It is referenced by a non-shared object. */
9253 case BFD_RELOC_AARCH64_16
:
9255 case BFD_RELOC_AARCH64_32
:
9257 if (bfd_link_pic (info
) && (sec
->flags
& SEC_ALLOC
) != 0)
9260 /* This is an absolute symbol. It represents a value instead
9262 && (bfd_is_abs_symbol (&h
->root
)
9263 /* This is an undefined symbol. */
9264 || h
->root
.type
== bfd_link_hash_undefined
))
9267 /* For local symbols, defined global symbols in a non-ABS section,
9268 it is assumed that the value is an address. */
9269 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9271 /* xgettext:c-format */
9272 (_("%pB: relocation %s against `%s' can not be used when making "
9274 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
9275 (h
) ? h
->root
.root
.string
: "a local symbol");
9276 bfd_set_error (bfd_error_bad_value
);
9282 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
9283 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
9284 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
9285 case BFD_RELOC_AARCH64_MOVW_G3
:
9286 if (bfd_link_pic (info
))
9288 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9290 /* xgettext:c-format */
9291 (_("%pB: relocation %s against `%s' can not be used when making "
9292 "a shared object; recompile with -fPIC"),
9293 abfd
, elfNN_aarch64_howto_table
[howto_index
].name
,
9294 (h
) ? h
->root
.root
.string
: "a local symbol");
9295 bfd_set_error (bfd_error_bad_value
);
9300 case BFD_RELOC_AARCH64_16_PCREL
:
9301 case BFD_RELOC_AARCH64_32_PCREL
:
9302 case BFD_RELOC_AARCH64_64_PCREL
:
9303 case BFD_RELOC_AARCH64_ADD_LO12
:
9304 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
9305 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
9306 case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL
:
9307 case BFD_RELOC_MORELLO_ADR_HI20_PCREL
:
9308 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
9309 case BFD_RELOC_AARCH64_LDST128_LO12
:
9310 case BFD_RELOC_AARCH64_LDST16_LO12
:
9311 case BFD_RELOC_AARCH64_LDST32_LO12
:
9312 case BFD_RELOC_AARCH64_LDST64_LO12
:
9313 case BFD_RELOC_AARCH64_LDST8_LO12
:
9314 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
9315 case BFD_RELOC_MORELLO_LD_LO17_PCREL
:
9316 if (h
== NULL
|| bfd_link_pic (info
))
9320 case BFD_RELOC_AARCH64_NN
:
9322 /* We don't need to handle relocs into sections not going into
9323 the "real" output. */
9324 if ((sec
->flags
& SEC_ALLOC
) == 0)
9329 if (!bfd_link_pic (info
))
9332 h
->plt
.refcount
+= 1;
9333 h
->pointer_equality_needed
= 1;
9336 /* No need to do anything if we're not creating a shared
9338 if (!(bfd_link_pic (info
)
9339 /* If on the other hand, we are creating an executable, we
9340 may need to keep relocations for symbols satisfied by a
9341 dynamic library if we manage to avoid copy relocs for the
9344 NOTE: Currently, there is no support of copy relocs
9345 elimination on pc-relative relocation types, because there is
9346 no dynamic relocation support for them in glibc. We still
9347 record the dynamic symbol reference for them. This is
9348 because one symbol may be referenced by both absolute
9349 relocation (for example, BFD_RELOC_AARCH64_NN) and
9350 pc-relative relocation. We need full symbol reference
9351 information to make correct decision later in
9352 elfNN_aarch64_adjust_dynamic_symbol. */
9353 || (ELIMINATE_COPY_RELOCS
9354 && !bfd_link_pic (info
)
9356 && (h
->root
.type
== bfd_link_hash_defweak
9357 || !h
->def_regular
))))
9361 struct elf_dyn_relocs
*p
;
9362 struct elf_dyn_relocs
**head
;
9363 int howto_index
= bfd_r_type
- BFD_RELOC_AARCH64_RELOC_START
;
9365 /* We must copy these reloc types into the output file.
9366 Create a reloc section in dynobj and make room for
9370 if (htab
->root
.dynobj
== NULL
)
9371 htab
->root
.dynobj
= abfd
;
9373 sreloc
= _bfd_elf_make_dynamic_reloc_section
9374 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
, abfd
, /*rela? */ TRUE
);
9380 /* If this is a global symbol, we count the number of
9381 relocations we need for this symbol. */
9384 head
= &h
->dyn_relocs
;
9388 /* Track dynamic relocs needed for local syms too.
9389 We really need local syms available to do this
9395 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
,
9400 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
9404 /* Beware of type punned pointers vs strict aliasing
9406 vpp
= &(elf_section_data (s
)->local_dynrel
);
9407 head
= (struct elf_dyn_relocs
**) vpp
;
9411 if (p
== NULL
|| p
->sec
!= sec
)
9413 size_t amt
= sizeof *p
;
9414 p
= ((struct elf_dyn_relocs
*)
9415 bfd_zalloc (htab
->root
.dynobj
, amt
));
9425 if (elfNN_aarch64_howto_table
[howto_index
].pc_relative
)
9430 /* RR: We probably want to keep a consistency check that
9431 there are no dangling GOT_PAGE relocs. */
9432 case BFD_RELOC_MORELLO_ADR_GOT_PAGE
:
9433 case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
:
9434 case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
:
9435 case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
:
9439 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
9440 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
9441 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
9442 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
9443 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
9444 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
9445 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
9446 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
9447 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
9448 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
9449 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
9450 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
9451 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
9452 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
9453 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
9454 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
9455 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
9456 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
9457 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
9458 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
9459 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
9460 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
9461 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
9462 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
9463 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
9464 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
9465 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
9466 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
9467 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
9468 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
9469 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
9472 unsigned old_got_type
;
9474 got_type
= aarch64_reloc_got_type (bfd_r_type
);
9478 h
->got
.refcount
+= 1;
9479 old_got_type
= elf_aarch64_hash_entry (h
)->got_type
;
9483 struct elf_aarch64_local_symbol
*locals
;
9485 if (!elfNN_aarch64_allocate_local_symbols
9486 (abfd
, symtab_hdr
->sh_info
))
9489 locals
= elf_aarch64_locals (abfd
);
9490 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
9491 locals
[r_symndx
].got_refcount
+= 1;
9492 old_got_type
= locals
[r_symndx
].got_type
;
9495 /* If a variable is accessed with both general dynamic TLS
9496 methods, two slots may be created. */
9497 if (GOT_TLS_GD_ANY_P (old_got_type
) && GOT_TLS_GD_ANY_P (got_type
))
9498 got_type
|= old_got_type
;
9500 /* We will already have issued an error message if there
9501 is a TLS/non-TLS mismatch, based on the symbol type.
9502 So just combine any TLS types needed. */
9503 if (old_got_type
!= GOT_UNKNOWN
&& old_got_type
!= GOT_NORMAL
9504 && got_type
!= GOT_NORMAL
&& old_got_type
!= GOT_CAP
9505 && got_type
!= GOT_CAP
)
9506 got_type
|= old_got_type
;
9508 /* If the symbol is accessed by both IE and GD methods, we
9509 are able to relax. Turn off the GD flag, without
9510 messing up with any other kind of TLS types that may be
9512 if ((got_type
& GOT_TLS_IE
) && GOT_TLS_GD_ANY_P (got_type
))
9513 got_type
&= ~ (GOT_TLSDESC_GD
| GOT_TLS_GD
);
9515 /* Prefer the capability reference. */
9516 if ((old_got_type
& GOT_CAP
) && (got_type
& GOT_NORMAL
))
9518 got_type
&= ~GOT_NORMAL
;
9519 got_type
|= GOT_CAP
;
9522 if (old_got_type
!= got_type
)
9525 elf_aarch64_hash_entry (h
)->got_type
= got_type
;
9528 struct elf_aarch64_local_symbol
*locals
;
9529 locals
= elf_aarch64_locals (abfd
);
9530 BFD_ASSERT (r_symndx
< symtab_hdr
->sh_info
);
9531 locals
[r_symndx
].got_type
= got_type
;
9535 if (htab
->root
.dynobj
== NULL
)
9536 htab
->root
.dynobj
= abfd
;
9537 if (! aarch64_elf_create_got_section (htab
->root
.dynobj
, info
))
9542 case BFD_RELOC_MORELLO_CALL26
:
9543 case BFD_RELOC_MORELLO_JUMP26
:
9546 elf_aarch64_hash_entry (h
)->got_type
= GOT_CAP
;
9549 case BFD_RELOC_AARCH64_CALL26
:
9550 case BFD_RELOC_AARCH64_JUMP26
:
9553 isym
= bfd_sym_from_r_symndx (&htab
->root
.sym_cache
, abfd
,
9558 asection
*s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
9563 if (c64_value_p (s
, isym
->st_value
))
9564 isym
->st_target_internal
|= ST_BRANCH_TO_C64
;
9566 /* If this is a local symbol then we resolve it
9567 directly without creating a PLT entry. */
9571 if (h
->root
.type
== bfd_link_hash_defined
9572 || h
->root
.type
== bfd_link_hash_defweak
)
9574 asection
*sym_sec
= h
->root
.u
.def
.section
;
9575 bfd_vma sym_value
= h
->root
.u
.def
.value
;
9577 if (sym_sec
!= NULL
&& c64_value_p (sym_sec
, sym_value
))
9578 h
->target_internal
|= ST_BRANCH_TO_C64
;
9582 if (h
->plt
.refcount
<= 0)
9583 h
->plt
.refcount
= 1;
9585 h
->plt
.refcount
+= 1;
9588 case BFD_RELOC_MORELLO_CAPINIT
:
9589 if (htab
->srelcaps
== NULL
)
9591 if (htab
->root
.dynobj
== NULL
)
9592 htab
->root
.dynobj
= abfd
;
9594 sreloc
= _bfd_elf_make_dynamic_reloc_section
9595 (sec
, htab
->root
.dynobj
, LOG_FILE_ALIGN
,
9596 abfd
, /*rela? */ TRUE
);
9601 htab
->srelcaps
= sreloc
;
9603 htab
->srelcaps
->size
+= RELOC_SIZE (htab
);
9615 /* Treat mapping symbols as special target symbols. */
9618 elfNN_aarch64_is_target_special_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
9621 return bfd_is_aarch64_special_symbol_name (sym
->name
,
9622 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
);
9625 /* If the ELF symbol SYM might be a function in SEC, return the
9626 function size and set *CODE_OFF to the function's entry point,
9627 otherwise return zero. */
9629 static bfd_size_type
9630 elfNN_aarch64_maybe_function_sym (const asymbol
*sym
, asection
*sec
,
9635 if ((sym
->flags
& (BSF_SECTION_SYM
| BSF_FILE
| BSF_OBJECT
9636 | BSF_THREAD_LOCAL
| BSF_RELC
| BSF_SRELC
)) != 0
9637 || sym
->section
!= sec
)
9640 if (!(sym
->flags
& BSF_SYNTHETIC
))
9641 switch (ELF_ST_TYPE (((elf_symbol_type
*) sym
)->internal_elf_sym
.st_info
))
9650 if ((sym
->flags
& BSF_LOCAL
)
9651 && bfd_is_aarch64_special_symbol_name (sym
->name
,
9652 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY
))
9655 *code_off
= sym
->value
;
9657 if (!(sym
->flags
& BSF_SYNTHETIC
))
9658 size
= ((elf_symbol_type
*) sym
)->internal_elf_sym
.st_size
;
9665 elfNN_aarch64_find_inliner_info (bfd
*abfd
,
9666 const char **filename_ptr
,
9667 const char **functionname_ptr
,
9668 unsigned int *line_ptr
)
9671 found
= _bfd_dwarf2_find_inliner_info
9672 (abfd
, filename_ptr
,
9673 functionname_ptr
, line_ptr
, &elf_tdata (abfd
)->dwarf2_find_line_info
);
9679 elfNN_aarch64_init_file_header (bfd
*abfd
, struct bfd_link_info
*link_info
)
9681 Elf_Internal_Ehdr
*i_ehdrp
; /* ELF file header, internal form. */
9683 if (!_bfd_elf_init_file_header (abfd
, link_info
))
9686 i_ehdrp
= elf_elfheader (abfd
);
9687 i_ehdrp
->e_ident
[EI_ABIVERSION
] = AARCH64_ELF_ABI_VERSION
;
9691 static enum elf_reloc_type_class
9692 elfNN_aarch64_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
9693 const asection
*rel_sec ATTRIBUTE_UNUSED
,
9694 const Elf_Internal_Rela
*rela
)
9696 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
9698 if (htab
->root
.dynsym
!= NULL
9699 && htab
->root
.dynsym
->contents
!= NULL
)
9701 /* Check relocation against STT_GNU_IFUNC symbol if there are
9703 bfd
*abfd
= info
->output_bfd
;
9704 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
9705 unsigned long r_symndx
= ELFNN_R_SYM (rela
->r_info
);
9706 if (r_symndx
!= STN_UNDEF
)
9708 Elf_Internal_Sym sym
;
9709 if (!bed
->s
->swap_symbol_in (abfd
,
9710 (htab
->root
.dynsym
->contents
9711 + r_symndx
* bed
->s
->sizeof_sym
),
9714 /* xgettext:c-format */
9715 _bfd_error_handler (_("%pB symbol number %lu references"
9716 " nonexistent SHT_SYMTAB_SHNDX section"),
9718 /* Ideally an error class should be returned here. */
9720 else if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
9721 return reloc_class_ifunc
;
9725 switch ((int) ELFNN_R_TYPE (rela
->r_info
))
9727 case AARCH64_R (IRELATIVE
):
9728 case MORELLO_R (IRELATIVE
):
9729 return reloc_class_ifunc
;
9730 case AARCH64_R (RELATIVE
):
9731 case MORELLO_R (RELATIVE
):
9732 return reloc_class_relative
;
9733 case AARCH64_R (JUMP_SLOT
):
9734 case MORELLO_R (JUMP_SLOT
):
9735 return reloc_class_plt
;
9736 case AARCH64_R (COPY
):
9737 return reloc_class_copy
;
9739 return reloc_class_normal
;
9743 /* Handle an AArch64 specific section when reading an object file. This is
9744 called when bfd_section_from_shdr finds a section with an unknown
9748 elfNN_aarch64_section_from_shdr (bfd
*abfd
,
9749 Elf_Internal_Shdr
*hdr
,
9750 const char *name
, int shindex
)
9752 /* There ought to be a place to keep ELF backend specific flags, but
9753 at the moment there isn't one. We just keep track of the
9754 sections by their name, instead. Fortunately, the ABI gives
9755 names for all the AArch64 specific sections, so we will probably get
9757 switch (hdr
->sh_type
)
9759 case SHT_AARCH64_ATTRIBUTES
:
9766 if (!_bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
9775 struct bfd_link_info
*info
;
9778 int (*func
) (void *, const char *, Elf_Internal_Sym
*,
9779 asection
*, struct elf_link_hash_entry
*);
9780 } output_arch_syminfo
;
9782 enum map_symbol_type
9790 /* Output a single mapping symbol. */
9793 elfNN_aarch64_output_map_sym (output_arch_syminfo
*osi
,
9794 enum map_symbol_type type
, bfd_vma offset
)
9796 static const char *names
[3] = { "$x", "$d", "$c" };
9797 Elf_Internal_Sym sym
;
9799 sym
.st_value
= (osi
->sec
->output_section
->vma
9800 + osi
->sec
->output_offset
+ offset
);
9803 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_NOTYPE
);
9804 sym
.st_shndx
= osi
->sec_shndx
;
9805 sym
.st_target_internal
= 0;
9806 return osi
->func (osi
->finfo
, names
[type
], &sym
, osi
->sec
, NULL
) == 1;
9809 /* Output a single local symbol for a generated stub. */
9812 elfNN_aarch64_output_stub_sym (output_arch_syminfo
*osi
, const char *name
,
9813 bfd_vma offset
, bfd_vma size
)
9815 Elf_Internal_Sym sym
;
9817 sym
.st_value
= (osi
->sec
->output_section
->vma
9818 + osi
->sec
->output_offset
+ offset
);
9821 sym
.st_info
= ELF_ST_INFO (STB_LOCAL
, STT_FUNC
);
9822 sym
.st_shndx
= osi
->sec_shndx
;
9823 sym
.st_target_internal
= 0;
9824 return osi
->func (osi
->finfo
, name
, &sym
, osi
->sec
, NULL
) == 1;
9828 aarch64_map_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
9830 struct elf_aarch64_stub_hash_entry
*stub_entry
;
9834 output_arch_syminfo
*osi
;
9836 /* Massage our args to the form they really have. */
9837 stub_entry
= (struct elf_aarch64_stub_hash_entry
*) gen_entry
;
9838 osi
= (output_arch_syminfo
*) in_arg
;
9840 stub_sec
= stub_entry
->stub_sec
;
9842 /* Ensure this stub is attached to the current section being
9844 if (stub_sec
!= osi
->sec
)
9847 addr
= (bfd_vma
) stub_entry
->stub_offset
;
9849 stub_name
= stub_entry
->output_name
;
9851 switch (stub_entry
->stub_type
)
9853 case aarch64_stub_adrp_branch
:
9854 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9855 sizeof (aarch64_adrp_branch_stub
)))
9857 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9860 case aarch64_stub_long_branch
:
9861 if (!elfNN_aarch64_output_stub_sym
9862 (osi
, stub_name
, addr
, sizeof (aarch64_long_branch_stub
)))
9864 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9866 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_DATA
, addr
+ 16))
9869 case aarch64_stub_erratum_835769_veneer
:
9870 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9871 sizeof (aarch64_erratum_835769_stub
)))
9873 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9876 case aarch64_stub_erratum_843419_veneer
:
9877 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9878 sizeof (aarch64_erratum_843419_stub
)))
9880 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_INSN
, addr
))
9883 case aarch64_stub_branch_c64
:
9884 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9885 sizeof (aarch64_c64_branch_stub
)))
9887 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_C64
, addr
))
9890 case c64_stub_branch_aarch64
:
9891 case c64_stub_branch_c64
:
9892 if (!elfNN_aarch64_output_stub_sym (osi
, stub_name
, addr
,
9893 sizeof (c64_aarch64_branch_stub
)))
9895 if (!elfNN_aarch64_output_map_sym (osi
, AARCH64_MAP_C64
, addr
))
9898 case aarch64_stub_none
:
9908 /* Output mapping symbols for linker generated sections. */
9911 elfNN_aarch64_output_arch_local_syms (bfd
*output_bfd
,
9912 struct bfd_link_info
*info
,
9914 int (*func
) (void *, const char *,
9917 struct elf_link_hash_entry
9920 output_arch_syminfo osi
;
9921 struct elf_aarch64_link_hash_table
*htab
;
9923 htab
= elf_aarch64_hash_table (info
);
9929 /* Long calls stubs. */
9930 if (htab
->stub_bfd
&& htab
->stub_bfd
->sections
)
9934 for (stub_sec
= htab
->stub_bfd
->sections
;
9935 stub_sec
!= NULL
; stub_sec
= stub_sec
->next
)
9937 /* Ignore non-stub sections. */
9938 if (!strstr (stub_sec
->name
, STUB_SUFFIX
))
9943 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
9944 (output_bfd
, osi
.sec
->output_section
);
9946 /* The first instruction in a stub is always a branch. */
9947 if (!elfNN_aarch64_output_map_sym (&osi
, AARCH64_MAP_INSN
, 0))
9950 bfd_hash_traverse (&htab
->stub_hash_table
, aarch64_map_one_stub
,
9955 /* Finally, output mapping symbols for the PLT. */
9956 if (!htab
->root
.splt
|| htab
->root
.splt
->size
== 0)
9959 osi
.sec_shndx
= _bfd_elf_section_from_bfd_section
9960 (output_bfd
, htab
->root
.splt
->output_section
);
9961 osi
.sec
= htab
->root
.splt
;
9963 elfNN_aarch64_output_map_sym (&osi
, (htab
->c64_rel
? AARCH64_MAP_C64
9964 : AARCH64_MAP_INSN
), 0);
9970 /* Allocate target specific section data. */
9973 elfNN_aarch64_new_section_hook (bfd
*abfd
, asection
*sec
)
9975 if (!sec
->used_by_bfd
)
9977 _aarch64_elf_section_data
*sdata
;
9978 size_t amt
= sizeof (*sdata
);
9980 sdata
= bfd_zalloc (abfd
, amt
);
9983 sdata
->elf
.is_target_section_data
= TRUE
;
9984 sec
->used_by_bfd
= sdata
;
9987 return _bfd_elf_new_section_hook (abfd
, sec
);
9991 /* Create dynamic sections. This is different from the ARM backend in that
9992 the got, plt, gotplt and their relocation sections are all created in the
9993 standard part of the bfd elf backend. */
9996 elfNN_aarch64_create_dynamic_sections (bfd
*dynobj
,
9997 struct bfd_link_info
*info
)
9999 /* We need to create .got section. */
10000 if (!aarch64_elf_create_got_section (dynobj
, info
))
10003 return _bfd_elf_create_dynamic_sections (dynobj
, info
);
10007 /* Allocate space in .plt, .got and associated reloc sections for
10011 elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry
*h
, void *inf
)
10013 struct bfd_link_info
*info
;
10014 struct elf_aarch64_link_hash_table
*htab
;
10015 struct elf_aarch64_link_hash_entry
*eh
;
10016 struct elf_dyn_relocs
*p
;
10018 /* An example of a bfd_link_hash_indirect symbol is versioned
10019 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
10020 -> __gxx_personality_v0(bfd_link_hash_defined)
10022 There is no need to process bfd_link_hash_indirect symbols here
10023 because we will also be presented with the concrete instance of
10024 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
10025 called to copy all relevant data from the generic to the concrete
10026 symbol instance. */
10027 if (h
->root
.type
== bfd_link_hash_indirect
)
10030 if (h
->root
.type
== bfd_link_hash_warning
)
10031 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
10033 info
= (struct bfd_link_info
*) inf
;
10034 htab
= elf_aarch64_hash_table (info
);
10036 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
10037 here if it is defined and referenced in a non-shared object. */
10038 if (h
->type
== STT_GNU_IFUNC
10041 else if (htab
->root
.dynamic_sections_created
&& h
->plt
.refcount
> 0)
10043 /* Make sure this symbol is output as a dynamic symbol.
10044 Undefined weak syms won't yet be marked as dynamic. */
10045 if (h
->dynindx
== -1 && !h
->forced_local
10046 && h
->root
.type
== bfd_link_hash_undefweak
)
10048 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
10052 if (bfd_link_pic (info
) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
10054 asection
*s
= htab
->root
.splt
;
10056 /* If this is the first .plt entry, make room for the special
10059 s
->size
+= htab
->plt_header_size
;
10061 h
->plt
.offset
= s
->size
;
10063 /* If this symbol is not defined in a regular file, and we are
10064 not generating a shared library, then set the symbol to this
10065 location in the .plt. This is required to make function
10066 pointers compare as equal between the normal executable and
10067 the shared library. */
10068 if (!bfd_link_pic (info
) && !h
->def_regular
)
10070 h
->root
.u
.def
.section
= s
;
10071 h
->root
.u
.def
.value
= h
->plt
.offset
;
10074 /* Make room for this entry. For now we only create the
10075 small model PLT entries. We later need to find a way
10076 of relaxing into these from the large model PLT entries. */
10077 s
->size
+= htab
->plt_entry_size
;
10079 /* We also need to make an entry in the .got.plt section, which
10080 will be placed in the .got section by the linker script. */
10081 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE (htab
);
10083 /* We also need to make an entry in the .rela.plt section. */
10084 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
10086 /* We need to ensure that all GOT entries that serve the PLT
10087 are consecutive with the special GOT slots [0] [1] and
10088 [2]. Any addtional relocations, such as
10089 R_AARCH64_TLSDESC, must be placed after the PLT related
10090 entries. We abuse the reloc_count such that during
10091 sizing we adjust reloc_count to indicate the number of
10092 PLT related reserved entries. In subsequent phases when
10093 filling in the contents of the reloc entries, PLT related
10094 entries are placed by computing their PLT index (0
10095 .. reloc_count). While other none PLT relocs are placed
10096 at the slot indicated by reloc_count and reloc_count is
10099 htab
->root
.srelplt
->reloc_count
++;
10101 /* Mark the DSO in case R_<CLS>_JUMP_SLOT relocs against
10102 variant PCS symbols are present. */
10103 if (h
->other
& STO_AARCH64_VARIANT_PCS
)
10104 htab
->variant_pcs
= 1;
10109 h
->plt
.offset
= (bfd_vma
) - 1;
10115 h
->plt
.offset
= (bfd_vma
) - 1;
10119 eh
= (struct elf_aarch64_link_hash_entry
*) h
;
10120 eh
->tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
10122 if (h
->got
.refcount
> 0)
10125 unsigned got_type
= elf_aarch64_hash_entry (h
)->got_type
;
10127 h
->got
.offset
= (bfd_vma
) - 1;
10129 dyn
= htab
->root
.dynamic_sections_created
;
10131 /* Make sure this symbol is output as a dynamic symbol.
10132 Undefined weak syms won't yet be marked as dynamic. */
10133 if (dyn
&& h
->dynindx
== -1 && !h
->forced_local
10134 && h
->root
.type
== bfd_link_hash_undefweak
)
10136 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
10140 if (got_type
== GOT_UNKNOWN
)
10143 else if (got_type
== GOT_NORMAL
10144 || got_type
== GOT_CAP
)
10146 h
->got
.offset
= htab
->root
.sgot
->size
;
10147 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10148 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
10149 || h
->root
.type
!= bfd_link_hash_undefweak
)
10150 && (bfd_link_pic (info
)
10151 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
))
10152 /* Undefined weak symbol in static PIE resolves to 0 without
10153 any dynamic relocations. */
10154 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10156 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
10158 else if (bfd_link_executable (info
) && !bfd_link_pic (info
))
10159 htab
->srelcaps
->size
+= RELOC_SIZE (htab
);
10164 if (got_type
& GOT_TLSDESC_GD
)
10166 eh
->tlsdesc_got_jump_table_offset
=
10167 (htab
->root
.sgotplt
->size
10168 - aarch64_compute_jump_table_size (htab
));
10169 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10170 h
->got
.offset
= (bfd_vma
) - 2;
10173 if (got_type
& GOT_TLS_GD
)
10175 h
->got
.offset
= htab
->root
.sgot
->size
;
10176 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10179 if (got_type
& GOT_TLS_IE
)
10181 h
->got
.offset
= htab
->root
.sgot
->size
;
10182 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10185 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
10186 if ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
10187 || h
->root
.type
!= bfd_link_hash_undefweak
)
10188 && (!bfd_link_executable (info
)
10190 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, 0, h
)
10191 /* On Morello support only TLSDESC_GD to TLSLE relaxation;
10192 for everything else we must emit a dynamic relocation. */
10193 || got_type
& GOT_CAP
))
10195 if (got_type
& GOT_TLSDESC_GD
)
10197 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
10198 /* Note reloc_count not incremented here! We have
10199 already adjusted reloc_count for this relocation
10202 /* TLSDESC PLT is now needed, but not yet determined. */
10203 htab
->root
.tlsdesc_plt
= (bfd_vma
) - 1;
10206 if (got_type
& GOT_TLS_GD
)
10207 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
10209 if (got_type
& GOT_TLS_IE
)
10210 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
10216 h
->got
.offset
= (bfd_vma
) - 1;
10219 if (h
->dyn_relocs
== NULL
)
10222 /* In the shared -Bsymbolic case, discard space allocated for
10223 dynamic pc-relative relocs against symbols which turn out to be
10224 defined in regular objects. For the normal shared case, discard
10225 space for pc-relative relocs that have become local due to symbol
10226 visibility changes. */
10228 if (bfd_link_pic (info
))
10230 /* Relocs that use pc_count are those that appear on a call
10231 insn, or certain REL relocs that can generated via assembly.
10232 We want calls to protected symbols to resolve directly to the
10233 function rather than going via the plt. If people want
10234 function pointer comparisons to work as expected then they
10235 should avoid writing weird assembly. */
10236 if (SYMBOL_CALLS_LOCAL (info
, h
))
10238 struct elf_dyn_relocs
**pp
;
10240 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
;)
10242 p
->count
-= p
->pc_count
;
10251 /* Also discard relocs on undefined weak syms with non-default
10253 if (h
->dyn_relocs
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
10255 if (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
10256 || UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10257 h
->dyn_relocs
= NULL
;
10259 /* Make sure undefined weak symbols are output as a dynamic
10261 else if (h
->dynindx
== -1
10262 && !h
->forced_local
10263 && h
->root
.type
== bfd_link_hash_undefweak
10264 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
10269 else if (ELIMINATE_COPY_RELOCS
)
10271 /* For the non-shared case, discard space for relocs against
10272 symbols which turn out to need copy relocs or are not
10275 if (!h
->non_got_ref
10276 && ((h
->def_dynamic
10277 && !h
->def_regular
)
10278 || (htab
->root
.dynamic_sections_created
10279 && (h
->root
.type
== bfd_link_hash_undefweak
10280 || h
->root
.type
== bfd_link_hash_undefined
))))
10282 /* Make sure this symbol is output as a dynamic symbol.
10283 Undefined weak syms won't yet be marked as dynamic. */
10284 if (h
->dynindx
== -1
10285 && !h
->forced_local
10286 && h
->root
.type
== bfd_link_hash_undefweak
10287 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
10290 /* If that succeeded, we know we'll be keeping all the
10292 if (h
->dynindx
!= -1)
10296 h
->dyn_relocs
= NULL
;
10301 /* Finally, allocate space. */
10302 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
10306 sreloc
= elf_section_data (p
->sec
)->sreloc
;
10308 BFD_ASSERT (sreloc
!= NULL
);
10310 sreloc
->size
+= p
->count
* RELOC_SIZE (htab
);
10316 /* Allocate space in .plt, .got and associated reloc sections for
10317 ifunc dynamic relocs. */
10320 elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry
*h
,
10323 struct bfd_link_info
*info
;
10324 struct elf_aarch64_link_hash_table
*htab
;
10326 /* An example of a bfd_link_hash_indirect symbol is versioned
10327 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
10328 -> __gxx_personality_v0(bfd_link_hash_defined)
10330 There is no need to process bfd_link_hash_indirect symbols here
10331 because we will also be presented with the concrete instance of
10332 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
10333 called to copy all relevant data from the generic to the concrete
10334 symbol instance. */
10335 if (h
->root
.type
== bfd_link_hash_indirect
)
10338 if (h
->root
.type
== bfd_link_hash_warning
)
10339 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
10341 info
= (struct bfd_link_info
*) inf
;
10342 htab
= elf_aarch64_hash_table (info
);
10344 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
10345 here if it is defined and referenced in a non-shared object. */
10346 if (h
->type
== STT_GNU_IFUNC
10348 return _bfd_elf_allocate_ifunc_dyn_relocs (info
, h
,
10350 htab
->plt_entry_size
,
10351 htab
->plt_header_size
,
10352 GOT_ENTRY_SIZE (htab
),
10357 /* Allocate space in .plt, .got and associated reloc sections for
10358 local ifunc dynamic relocs. */
10361 elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot
, void *inf
)
10363 struct elf_link_hash_entry
*h
10364 = (struct elf_link_hash_entry
*) *slot
;
10366 if (h
->type
!= STT_GNU_IFUNC
10369 || !h
->forced_local
10370 || h
->root
.type
!= bfd_link_hash_defined
)
10373 return elfNN_aarch64_allocate_ifunc_dynrelocs (h
, inf
);
10376 /* This is the most important function of all . Innocuosly named
10380 elfNN_aarch64_size_dynamic_sections (bfd
*output_bfd
,
10381 struct bfd_link_info
*info
)
10383 struct elf_aarch64_link_hash_table
*htab
;
10386 bfd_boolean relocs
;
10389 htab
= elf_aarch64_hash_table ((info
));
10390 dynobj
= htab
->root
.dynobj
;
10392 BFD_ASSERT (dynobj
!= NULL
);
10394 if (htab
->root
.dynamic_sections_created
)
10396 if (bfd_link_executable (info
) && !info
->nointerp
)
10398 s
= bfd_get_linker_section (dynobj
, ".interp");
10401 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
10402 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
10406 aarch64_elf_init_got_section (output_bfd
, info
);
10408 setup_plt_values (info
, elf_aarch64_tdata (output_bfd
)->plt_type
);
10410 /* Set up .got offsets for local syms, and space for local dynamic
10412 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
10414 struct elf_aarch64_local_symbol
*locals
= NULL
;
10415 Elf_Internal_Shdr
*symtab_hdr
;
10419 if (!is_aarch64_elf (ibfd
))
10422 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
10424 struct elf_dyn_relocs
*p
;
10426 for (p
= (struct elf_dyn_relocs
*)
10427 (elf_section_data (s
)->local_dynrel
); p
!= NULL
; p
= p
->next
)
10429 if (!bfd_is_abs_section (p
->sec
)
10430 && bfd_is_abs_section (p
->sec
->output_section
))
10432 /* Input section has been discarded, either because
10433 it is a copy of a linkonce section or due to
10434 linker script /DISCARD/, so we'll be discarding
10437 else if (p
->count
!= 0)
10439 srel
= elf_section_data (p
->sec
)->sreloc
;
10440 srel
->size
+= p
->count
* RELOC_SIZE (htab
);
10441 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
10442 info
->flags
|= DF_TEXTREL
;
10447 locals
= elf_aarch64_locals (ibfd
);
10451 symtab_hdr
= &elf_symtab_hdr (ibfd
);
10452 srel
= htab
->root
.srelgot
;
10453 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
10455 locals
[i
].got_offset
= (bfd_vma
) - 1;
10456 locals
[i
].tlsdesc_got_jump_table_offset
= (bfd_vma
) - 1;
10457 if (locals
[i
].got_refcount
> 0)
10459 unsigned got_type
= locals
[i
].got_type
;
10460 if (got_type
& GOT_TLSDESC_GD
)
10462 locals
[i
].tlsdesc_got_jump_table_offset
=
10463 (htab
->root
.sgotplt
->size
10464 - aarch64_compute_jump_table_size (htab
));
10465 htab
->root
.sgotplt
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10466 locals
[i
].got_offset
= (bfd_vma
) - 2;
10469 if (got_type
& GOT_TLS_GD
)
10471 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
10472 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
) * 2;
10475 if (got_type
& GOT_TLS_IE
10476 || got_type
& GOT_NORMAL
10477 || got_type
& GOT_CAP
)
10479 locals
[i
].got_offset
= htab
->root
.sgot
->size
;
10480 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10483 if (got_type
== GOT_UNKNOWN
)
10487 if (bfd_link_pic (info
))
10489 if (got_type
& GOT_TLSDESC_GD
)
10491 htab
->root
.srelplt
->size
+= RELOC_SIZE (htab
);
10492 /* Note RELOC_COUNT not incremented here! */
10493 htab
->root
.tlsdesc_plt
= (bfd_vma
) - 1;
10496 if (got_type
& GOT_TLS_GD
)
10497 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
) * 2;
10499 if (got_type
& GOT_TLS_IE
10500 || got_type
& GOT_NORMAL
10501 || got_type
& GOT_CAP
)
10502 htab
->root
.srelgot
->size
+= RELOC_SIZE (htab
);
10504 /* Static binary; put relocs into srelcaps. */
10505 else if (bfd_link_executable (info
) && (got_type
& GOT_CAP
))
10506 htab
->srelcaps
->size
+= RELOC_SIZE (htab
);
10510 locals
[i
].got_refcount
= (bfd_vma
) - 1;
10516 /* Allocate global sym .plt and .got entries, and space for global
10517 sym dynamic relocs. */
10518 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_dynrelocs
,
10521 /* Allocate global ifunc sym .plt and .got entries, and space for global
10522 ifunc sym dynamic relocs. */
10523 elf_link_hash_traverse (&htab
->root
, elfNN_aarch64_allocate_ifunc_dynrelocs
,
10526 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
10527 htab_traverse (htab
->loc_hash_table
,
10528 elfNN_aarch64_allocate_local_ifunc_dynrelocs
,
10531 if (bfd_link_executable (info
)
10532 && !bfd_link_pic (info
)
10534 && htab
->srelcaps
->size
> 0)
10536 struct elf_link_hash_entry
*h
;
10538 h
= _bfd_elf_define_linkage_sym (output_bfd
, info
,
10540 "__rela_dyn_start");
10541 h
= _bfd_elf_define_linkage_sym (output_bfd
, info
,
10545 h
->root
.u
.def
.value
= htab
->srelcaps
->vma
+ htab
->srelcaps
->size
;
10548 /* For every jump slot reserved in the sgotplt, reloc_count is
10549 incremented. However, when we reserve space for TLS descriptors,
10550 it's not incremented, so in order to compute the space reserved
10551 for them, it suffices to multiply the reloc count by the jump
10554 if (htab
->root
.srelplt
)
10555 htab
->sgotplt_jump_table_size
= aarch64_compute_jump_table_size (htab
);
10557 if (htab
->root
.tlsdesc_plt
)
10559 if (htab
->root
.splt
->size
== 0)
10560 htab
->root
.splt
->size
+= htab
->plt_header_size
;
10562 /* If we're not using lazy TLS relocations, don't generate the
10563 GOT and PLT entry required. */
10564 if ((info
->flags
& DF_BIND_NOW
))
10565 htab
->root
.tlsdesc_plt
= 0;
10568 htab
->root
.tlsdesc_plt
= htab
->root
.splt
->size
;
10569 htab
->root
.splt
->size
+= htab
->tlsdesc_plt_entry_size
;
10571 htab
->root
.tlsdesc_got
= htab
->root
.sgot
->size
;
10572 htab
->root
.sgot
->size
+= GOT_ENTRY_SIZE (htab
);
10576 /* Init mapping symbols information to use later to distingush between
10577 code and data while scanning for errata. */
10578 if (htab
->fix_erratum_835769
|| htab
->fix_erratum_843419
)
10579 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
10581 if (!is_aarch64_elf (ibfd
))
10583 bfd_elfNN_aarch64_init_maps (ibfd
, info
);
10586 /* We now have determined the sizes of the various dynamic sections.
10587 Allocate memory for them. */
10589 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
10591 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
10594 if (s
== htab
->root
.splt
10595 || s
== htab
->root
.sgot
10596 || s
== htab
->root
.sgotplt
10597 || s
== htab
->root
.iplt
10598 || s
== htab
->root
.igotplt
10599 || s
== htab
->root
.sdynbss
10600 || s
== htab
->root
.sdynrelro
)
10602 /* Strip this section if we don't need it; see the
10605 else if (CONST_STRNEQ (bfd_section_name (s
), ".rela"))
10607 if (s
->size
!= 0 && s
!= htab
->root
.srelplt
)
10610 /* We use the reloc_count field as a counter if we need
10611 to copy relocs into the output file. */
10612 if (s
!= htab
->root
.srelplt
)
10613 s
->reloc_count
= 0;
10617 /* It's not one of our sections, so don't allocate space. */
10623 /* If we don't need this section, strip it from the
10624 output file. This is mostly to handle .rela.bss and
10625 .rela.plt. We must create both sections in
10626 create_dynamic_sections, because they must be created
10627 before the linker maps input sections to output
10628 sections. The linker does that before
10629 adjust_dynamic_symbol is called, and it is that
10630 function which decides whether anything needs to go
10631 into these sections. */
10632 s
->flags
|= SEC_EXCLUDE
;
10636 if ((s
->flags
& SEC_HAS_CONTENTS
) == 0)
10639 /* Allocate memory for the section contents. We use bfd_zalloc
10640 here in case unused entries are not reclaimed before the
10641 section's contents are written out. This should not happen,
10642 but this way if it does, we get a R_AARCH64_NONE reloc instead
10644 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
10645 if (s
->contents
== NULL
)
10649 if (htab
->root
.dynamic_sections_created
)
10651 /* Add some entries to the .dynamic section. We fill in the
10652 values later, in elfNN_aarch64_finish_dynamic_sections, but we
10653 must add the entries now so that we get the correct size for
10654 the .dynamic section. The DT_DEBUG entry is filled in by the
10655 dynamic linker and used by the debugger. */
10656 #define add_dynamic_entry(TAG, VAL) \
10657 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
10659 if (!_bfd_elf_add_dynamic_tags (output_bfd
, info
, relocs
))
10662 if (htab
->root
.splt
->size
!= 0)
10664 if (htab
->variant_pcs
10665 && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS
, 0))
10668 if ((elf_aarch64_tdata (output_bfd
)->plt_type
== PLT_BTI_PAC
)
10669 && (!add_dynamic_entry (DT_AARCH64_BTI_PLT
, 0)
10670 || !add_dynamic_entry (DT_AARCH64_PAC_PLT
, 0)))
10673 else if ((elf_aarch64_tdata (output_bfd
)->plt_type
== PLT_BTI
)
10674 && !add_dynamic_entry (DT_AARCH64_BTI_PLT
, 0))
10677 else if ((elf_aarch64_tdata (output_bfd
)->plt_type
== PLT_PAC
)
10678 && !add_dynamic_entry (DT_AARCH64_PAC_PLT
, 0))
10682 #undef add_dynamic_entry
10688 elf_aarch64_update_plt_entry (bfd
*output_bfd
,
10689 bfd_reloc_code_real_type r_type
,
10690 bfd_byte
*plt_entry
, bfd_vma value
)
10692 reloc_howto_type
*howto
= elfNN_aarch64_howto_from_bfd_reloc (r_type
);
10694 /* FIXME: We should check the return value from this function call. */
10695 (void) _bfd_aarch64_elf_put_addend (output_bfd
, plt_entry
, r_type
, howto
, value
);
10699 aarch64_update_c64_plt_entry (bfd
*output_bfd
, bfd_byte
*plt_entry
,
10700 bfd_vma plt_base
, bfd_vma plt_got_ent
)
10702 /* Fill in the top 20 bits for this: ADRP c16, PLT_GOT + n * 16.
10703 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
10704 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_MORELLO_ADR_HI20_PCREL
,
10706 PG (plt_got_ent
) - PG (plt_base
));
10708 elf_aarch64_update_plt_entry (output_bfd
,
10709 BFD_RELOC_AARCH64_LDST128_LO12
,
10711 PG_OFFSET (plt_got_ent
));
10713 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
10715 PG_OFFSET (plt_got_ent
));
10719 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry
*h
,
10720 struct elf_aarch64_link_hash_table
10721 *htab
, bfd
*output_bfd
,
10722 struct bfd_link_info
*info
)
10724 bfd_byte
*plt_entry
;
10726 bfd_vma got_offset
;
10727 bfd_vma gotplt_entry_address
;
10728 bfd_vma plt_entry_address
;
10729 Elf_Internal_Rela rela
;
10731 asection
*plt
, *gotplt
, *relplt
;
10733 /* When building a static executable, use .iplt, .igot.plt and
10734 .rela.iplt sections for STT_GNU_IFUNC symbols. */
10735 if (htab
->root
.splt
!= NULL
)
10737 plt
= htab
->root
.splt
;
10738 gotplt
= htab
->root
.sgotplt
;
10739 relplt
= htab
->root
.srelplt
;
10743 plt
= htab
->root
.iplt
;
10744 gotplt
= htab
->root
.igotplt
;
10745 relplt
= htab
->root
.irelplt
;
10748 /* Get the index in the procedure linkage table which
10749 corresponds to this symbol. This is the index of this symbol
10750 in all the symbols for which we are making plt entries. The
10751 first entry in the procedure linkage table is reserved.
10753 Get the offset into the .got table of the entry that
10754 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
10755 bytes. The first three are reserved for the dynamic linker.
10757 For static executables, we don't reserve anything. */
10759 if (plt
== htab
->root
.splt
)
10761 plt_index
= (h
->plt
.offset
- htab
->plt_header_size
) / htab
->plt_entry_size
;
10762 got_offset
= (plt_index
+ 3) * GOT_ENTRY_SIZE (htab
);
10766 plt_index
= h
->plt
.offset
/ htab
->plt_entry_size
;
10767 got_offset
= plt_index
* GOT_ENTRY_SIZE (htab
);
10770 plt_entry
= plt
->contents
+ h
->plt
.offset
;
10771 plt_entry_address
= plt
->output_section
->vma
10772 + plt
->output_offset
+ h
->plt
.offset
;
10773 gotplt_entry_address
= gotplt
->output_section
->vma
+
10774 gotplt
->output_offset
+ got_offset
;
10776 /* Copy in the boiler-plate for the PLTn entry. */
10777 memcpy (plt_entry
, htab
->plt_entry
, htab
->plt_entry_size
);
10780 aarch64_update_c64_plt_entry (output_bfd
, plt_entry
, plt_entry_address
,
10781 gotplt_entry_address
);
10785 /* First instruction in BTI enabled PLT stub is a BTI
10786 instruction so skip it. */
10787 if (elf_aarch64_tdata (output_bfd
)->plt_type
& PLT_BTI
10788 && elf_elfheader (output_bfd
)->e_type
== ET_EXEC
)
10789 plt_entry
= plt_entry
+ 4;
10791 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
10792 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
10793 elf_aarch64_update_plt_entry (output_bfd
,
10794 BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
10796 PG (gotplt_entry_address
) -
10797 PG (plt_entry_address
));
10799 /* Fill in the lo12 bits for the load from the pltgot. */
10800 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
10802 PG_OFFSET (gotplt_entry_address
));
10804 /* Fill in the lo12 bits for the add from the pltgot entry. */
10805 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
10807 PG_OFFSET (gotplt_entry_address
));
10810 /* All the GOTPLT Entries are essentially initialized to PLT0. Set LSB if
10812 bfd_vma plt0
= ((plt
->output_section
->vma
+ plt
->output_offset
)
10814 bfd_put_NN (output_bfd
, plt0
, gotplt
->contents
+ got_offset
);
10816 rela
.r_offset
= gotplt_entry_address
;
10818 if (h
->dynindx
== -1
10819 || ((bfd_link_executable (info
)
10820 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
10822 && h
->type
== STT_GNU_IFUNC
))
10824 /* If an STT_GNU_IFUNC symbol is locally defined, generate
10825 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
10826 rela
.r_info
= (elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
10827 ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE
))
10828 : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE
)));
10829 rela
.r_addend
= (h
->root
.u
.def
.value
10830 + h
->root
.u
.def
.section
->output_section
->vma
10831 + h
->root
.u
.def
.section
->output_offset
);
10835 /* Fill in the entry in the .rela.plt section. */
10836 rela
.r_info
= (elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
10837 ? ELFNN_R_INFO (h
->dynindx
, MORELLO_R (JUMP_SLOT
))
10838 : ELFNN_R_INFO (h
->dynindx
, AARCH64_R (JUMP_SLOT
)));
10842 /* Compute the relocation entry to used based on PLT index and do
10843 not adjust reloc_count. The reloc_count has already been adjusted
10844 to account for this entry. */
10845 loc
= relplt
->contents
+ plt_index
* RELOC_SIZE (htab
);
10846 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
10849 /* Size sections even though they're not dynamic. We use it to setup
10850 _TLS_MODULE_BASE_, if needed. */
10853 elfNN_aarch64_always_size_sections (bfd
*output_bfd
,
10854 struct bfd_link_info
*info
)
10858 if (bfd_link_relocatable (info
))
10861 tls_sec
= elf_hash_table (info
)->tls_sec
;
10865 struct elf_link_hash_entry
*tlsbase
;
10867 tlsbase
= elf_link_hash_lookup (elf_hash_table (info
),
10868 "_TLS_MODULE_BASE_", TRUE
, TRUE
, FALSE
);
10872 struct bfd_link_hash_entry
*h
= NULL
;
10873 const struct elf_backend_data
*bed
=
10874 get_elf_backend_data (output_bfd
);
10876 if (!(_bfd_generic_link_add_one_symbol
10877 (info
, output_bfd
, "_TLS_MODULE_BASE_", BSF_LOCAL
,
10878 tls_sec
, 0, NULL
, FALSE
, bed
->collect
, &h
)))
10881 tlsbase
->type
= STT_TLS
;
10882 tlsbase
= (struct elf_link_hash_entry
*) h
;
10883 tlsbase
->def_regular
= 1;
10884 tlsbase
->other
= STV_HIDDEN
;
10885 (*bed
->elf_backend_hide_symbol
) (info
, tlsbase
, TRUE
);
10892 /* Finish up dynamic symbol handling. We set the contents of various
10893 dynamic sections here. */
10896 elfNN_aarch64_finish_dynamic_symbol (bfd
*output_bfd
,
10897 struct bfd_link_info
*info
,
10898 struct elf_link_hash_entry
*h
,
10899 Elf_Internal_Sym
*sym
)
10901 struct elf_aarch64_link_hash_table
*htab
;
10902 htab
= elf_aarch64_hash_table (info
);
10904 if (h
->plt
.offset
!= (bfd_vma
) - 1)
10906 asection
*plt
, *gotplt
, *relplt
;
10908 /* This symbol has an entry in the procedure linkage table. Set
10911 /* When building a static executable, use .iplt, .igot.plt and
10912 .rela.iplt sections for STT_GNU_IFUNC symbols. */
10913 if (htab
->root
.splt
!= NULL
)
10915 plt
= htab
->root
.splt
;
10916 gotplt
= htab
->root
.sgotplt
;
10917 relplt
= htab
->root
.srelplt
;
10921 plt
= htab
->root
.iplt
;
10922 gotplt
= htab
->root
.igotplt
;
10923 relplt
= htab
->root
.irelplt
;
10926 /* This symbol has an entry in the procedure linkage table. Set
10928 if ((h
->dynindx
== -1
10929 && !((h
->forced_local
|| bfd_link_executable (info
))
10931 && h
->type
== STT_GNU_IFUNC
))
10937 elfNN_aarch64_create_small_pltn_entry (h
, htab
, output_bfd
, info
);
10938 if (!h
->def_regular
)
10940 /* Mark the symbol as undefined, rather than as defined in
10941 the .plt section. */
10942 sym
->st_shndx
= SHN_UNDEF
;
10943 /* If the symbol is weak we need to clear the value.
10944 Otherwise, the PLT entry would provide a definition for
10945 the symbol even if the symbol wasn't defined anywhere,
10946 and so the symbol would never be NULL. Leave the value if
10947 there were any relocations where pointer equality matters
10948 (this is a clue for the dynamic linker, to make function
10949 pointer comparisons work between an application and shared
10951 if (!h
->ref_regular_nonweak
|| !h
->pointer_equality_needed
)
10956 bfd_boolean is_c64
= elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
;
10958 if (h
->got
.offset
!= (bfd_vma
) - 1
10959 && (elf_aarch64_hash_entry (h
)->got_type
== GOT_NORMAL
10960 || elf_aarch64_hash_entry (h
)->got_type
== GOT_CAP
)
10961 /* Undefined weak symbol in static PIE resolves to 0 without
10962 any dynamic relocations. */
10963 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
10965 Elf_Internal_Rela rela
;
10968 /* This symbol has an entry in the global offset table. Set it
10970 if (htab
->root
.sgot
== NULL
|| htab
->root
.srelgot
== NULL
)
10973 rela
.r_offset
= (htab
->root
.sgot
->output_section
->vma
10974 + htab
->root
.sgot
->output_offset
10975 + (h
->got
.offset
& ~(bfd_vma
) 1));
10978 && h
->type
== STT_GNU_IFUNC
)
10980 if (bfd_link_pic (info
))
10982 /* Generate R_AARCH64_GLOB_DAT. */
10989 if (!h
->pointer_equality_needed
)
10992 /* For non-shared object, we can't use .got.plt, which
10993 contains the real function address if we need pointer
10994 equality. We load the GOT entry with the PLT entry. */
10995 plt
= htab
->root
.splt
? htab
->root
.splt
: htab
->root
.iplt
;
10996 bfd_put_NN (output_bfd
, (plt
->output_section
->vma
10997 + plt
->output_offset
10999 htab
->root
.sgot
->contents
11000 + (h
->got
.offset
& ~(bfd_vma
) 1));
11004 else if (bfd_link_pic (info
) && SYMBOL_REFERENCES_LOCAL (info
, h
))
11006 if (!(h
->def_regular
|| ELF_COMMON_DEF_P (h
)))
11009 BFD_ASSERT ((h
->got
.offset
& 1) != 0);
11012 rela
.r_info
= ELFNN_R_INFO (0, MORELLO_R (RELATIVE
));
11017 rela
.r_info
= ELFNN_R_INFO (0, AARCH64_R (RELATIVE
));
11018 rela
.r_addend
= (h
->root
.u
.def
.value
11019 + h
->root
.u
.def
.section
->output_section
->vma
11020 + h
->root
.u
.def
.section
->output_offset
);
11026 BFD_ASSERT ((h
->got
.offset
& 1) == 0);
11027 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
11028 htab
->root
.sgot
->contents
+ h
->got
.offset
);
11029 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
,
11030 (is_c64
? MORELLO_R (GLOB_DAT
)
11031 : AARCH64_R (GLOB_DAT
)));
11035 loc
= htab
->root
.srelgot
->contents
;
11036 loc
+= htab
->root
.srelgot
->reloc_count
++ * RELOC_SIZE (htab
);
11037 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
11042 Elf_Internal_Rela rela
;
11046 /* This symbol needs a copy reloc. Set it up. */
11047 if (h
->dynindx
== -1
11048 || (h
->root
.type
!= bfd_link_hash_defined
11049 && h
->root
.type
!= bfd_link_hash_defweak
)
11050 || htab
->root
.srelbss
== NULL
)
11053 rela
.r_offset
= (h
->root
.u
.def
.value
11054 + h
->root
.u
.def
.section
->output_section
->vma
11055 + h
->root
.u
.def
.section
->output_offset
);
11056 rela
.r_info
= ELFNN_R_INFO (h
->dynindx
, AARCH64_R (COPY
));
11058 if (h
->root
.u
.def
.section
== htab
->root
.sdynrelro
)
11059 s
= htab
->root
.sreldynrelro
;
11061 s
= htab
->root
.srelbss
;
11062 loc
= s
->contents
+ s
->reloc_count
++ * RELOC_SIZE (htab
);
11063 bfd_elfNN_swap_reloca_out (output_bfd
, &rela
, loc
);
11066 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
11067 be NULL for local symbols. */
11069 && (h
== elf_hash_table (info
)->hdynamic
11070 || h
== elf_hash_table (info
)->hgot
))
11071 sym
->st_shndx
= SHN_ABS
;
11076 /* Finish up local dynamic symbol handling. We set the contents of
11077 various dynamic sections here. */
11080 elfNN_aarch64_finish_local_dynamic_symbol (void **slot
, void *inf
)
11082 struct elf_link_hash_entry
*h
11083 = (struct elf_link_hash_entry
*) *slot
;
11084 struct bfd_link_info
*info
11085 = (struct bfd_link_info
*) inf
;
11087 return elfNN_aarch64_finish_dynamic_symbol (info
->output_bfd
,
11092 elfNN_aarch64_init_small_plt0_entry (bfd
*output_bfd ATTRIBUTE_UNUSED
,
11093 struct elf_aarch64_link_hash_table
11096 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
11097 small and large plts and at the minute just generates
11100 /* PLT0 of the small PLT looks like this in ELF64 -
11101 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
11102 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
11103 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
11105 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
11106 // GOTPLT entry for this.
11108 PLT0 will be slightly different in ELF32 due to different got entry
11110 bfd_vma plt_got_2nd_ent
; /* Address of GOT[2]. */
11114 memcpy (htab
->root
.splt
->contents
, htab
->plt0_entry
,
11115 htab
->plt_header_size
);
11117 /* PR 26312: Explicitly set the sh_entsize to 0 so that
11118 consumers do not think that the section contains fixed
11120 elf_section_data (htab
->root
.splt
->output_section
)->this_hdr
.sh_entsize
= 0;
11122 plt_got_2nd_ent
= (htab
->root
.sgotplt
->output_section
->vma
11123 + htab
->root
.sgotplt
->output_offset
11124 + GOT_ENTRY_SIZE (htab
) * 2);
11126 plt_base
= htab
->root
.splt
->output_section
->vma
+
11127 htab
->root
.splt
->output_offset
;
11129 bfd_byte
*plt0_entry
= htab
->root
.splt
->contents
;
11133 aarch64_update_c64_plt_entry (output_bfd
, plt0_entry
+ 4,
11134 plt_base
+ 4, plt_got_2nd_ent
);
11138 /* First instruction in BTI enabled PLT stub is a BTI
11139 instruction so skip it. */
11140 if (elf_aarch64_tdata (output_bfd
)->plt_type
& PLT_BTI
)
11141 plt0_entry
= plt0_entry
+ 4;
11143 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
11144 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
11145 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADR_HI21_PCREL
,
11147 PG (plt_got_2nd_ent
) - PG (plt_base
+ 4));
11149 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_LDSTNN_LO12
,
11151 PG_OFFSET (plt_got_2nd_ent
));
11153 elf_aarch64_update_plt_entry (output_bfd
, BFD_RELOC_AARCH64_ADD_LO12
,
11155 PG_OFFSET (plt_got_2nd_ent
));
11159 elfNN_aarch64_finish_dynamic_sections (bfd
*output_bfd
,
11160 struct bfd_link_info
*info
)
11162 struct elf_aarch64_link_hash_table
*htab
;
11166 htab
= elf_aarch64_hash_table (info
);
11167 dynobj
= htab
->root
.dynobj
;
11168 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
11170 if (htab
->root
.dynamic_sections_created
)
11172 ElfNN_External_Dyn
*dyncon
, *dynconend
;
11174 if (sdyn
== NULL
|| htab
->root
.sgot
== NULL
)
11177 dyncon
= (ElfNN_External_Dyn
*) sdyn
->contents
;
11178 dynconend
= (ElfNN_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
11179 for (; dyncon
< dynconend
; dyncon
++)
11181 Elf_Internal_Dyn dyn
;
11184 bfd_elfNN_swap_dyn_in (dynobj
, dyncon
, &dyn
);
11192 s
= htab
->root
.sgotplt
;
11193 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
11197 s
= htab
->root
.srelplt
;
11198 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
11202 s
= htab
->root
.srelplt
;
11203 dyn
.d_un
.d_val
= s
->size
;
11206 case DT_TLSDESC_PLT
:
11207 s
= htab
->root
.splt
;
11208 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
11209 + htab
->root
.tlsdesc_plt
;
11212 case DT_TLSDESC_GOT
:
11213 s
= htab
->root
.sgot
;
11214 BFD_ASSERT (htab
->root
.tlsdesc_got
!= (bfd_vma
)-1);
11215 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
11216 + htab
->root
.tlsdesc_got
;
11220 bfd_elfNN_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
11225 /* Fill in the special first entry in the procedure linkage table. */
11226 if (htab
->root
.splt
&& htab
->root
.splt
->size
> 0)
11228 elfNN_aarch64_init_small_plt0_entry (output_bfd
, htab
);
11230 if (htab
->root
.tlsdesc_plt
&& !(info
->flags
& DF_BIND_NOW
))
11232 BFD_ASSERT (htab
->root
.tlsdesc_got
!= (bfd_vma
)-1);
11233 bfd_put_NN (output_bfd
, (bfd_vma
) 0,
11234 htab
->root
.sgot
->contents
+ htab
->root
.tlsdesc_got
);
11236 const bfd_byte
*entry
= elfNN_aarch64_tlsdesc_small_plt_entry
;
11237 htab
->tlsdesc_plt_entry_size
= PLT_TLSDESC_ENTRY_SIZE
;
11239 unsigned adrp_rtype
= BFD_RELOC_AARCH64_ADR_HI21_PCREL
;
11240 unsigned ldr_rtype
= BFD_RELOC_AARCH64_LDSTNN_LO12
;
11242 aarch64_plt_type type
= elf_aarch64_tdata (output_bfd
)->plt_type
;
11245 entry
= elfNN_aarch64_tlsdesc_small_plt_c64_entry
;
11246 adrp_rtype
= BFD_RELOC_MORELLO_ADR_HI20_PCREL
;
11247 ldr_rtype
= BFD_RELOC_AARCH64_LDST128_LO12
;
11249 else if (type
== PLT_BTI
|| type
== PLT_BTI_PAC
)
11251 entry
= elfNN_aarch64_tlsdesc_small_plt_bti_entry
;
11254 memcpy (htab
->root
.splt
->contents
+ htab
->root
.tlsdesc_plt
,
11255 entry
, htab
->tlsdesc_plt_entry_size
);
11258 bfd_vma adrp1_addr
=
11259 htab
->root
.splt
->output_section
->vma
11260 + htab
->root
.splt
->output_offset
11261 + htab
->root
.tlsdesc_plt
+ 4;
11263 bfd_vma adrp2_addr
= adrp1_addr
+ 4;
11266 htab
->root
.sgot
->output_section
->vma
11267 + htab
->root
.sgot
->output_offset
;
11269 bfd_vma pltgot_addr
=
11270 htab
->root
.sgotplt
->output_section
->vma
11271 + htab
->root
.sgotplt
->output_offset
;
11273 bfd_vma dt_tlsdesc_got
= got_addr
+ htab
->root
.tlsdesc_got
;
11275 bfd_byte
*plt_entry
=
11276 htab
->root
.splt
->contents
+ htab
->root
.tlsdesc_plt
;
11278 /* First instruction in BTI enabled PLT stub is a BTI
11279 instruction so skip it. */
11280 if (type
& PLT_BTI
)
11282 plt_entry
= plt_entry
+ 4;
11283 adrp1_addr
= adrp1_addr
+ 4;
11284 adrp2_addr
= adrp2_addr
+ 4;
11287 /* adrp x2, DT_TLSDESC_GOT */
11288 elf_aarch64_update_plt_entry (output_bfd
,
11291 (PG (dt_tlsdesc_got
)
11292 - PG (adrp1_addr
)));
11295 elf_aarch64_update_plt_entry (output_bfd
,
11299 - PG (adrp2_addr
)));
11301 /* ldr x2, [x2, #0] */
11302 elf_aarch64_update_plt_entry (output_bfd
,
11305 PG_OFFSET (dt_tlsdesc_got
));
11307 /* add x3, x3, 0 */
11308 elf_aarch64_update_plt_entry (output_bfd
,
11309 BFD_RELOC_AARCH64_ADD_LO12
,
11311 PG_OFFSET (pltgot_addr
));
11316 if (htab
->root
.sgotplt
)
11318 if (bfd_is_abs_section (htab
->root
.sgotplt
->output_section
))
11321 (_("discarded output section: `%pA'"), htab
->root
.sgotplt
);
11325 /* Fill in the first three entries in the global offset table. */
11326 if (htab
->root
.sgotplt
->size
> 0)
11328 bfd_put_NN (output_bfd
, (bfd_vma
) 0, htab
->root
.sgotplt
->contents
);
11330 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
11331 bfd_put_NN (output_bfd
,
11333 htab
->root
.sgotplt
->contents
+ GOT_ENTRY_SIZE (htab
));
11334 bfd_put_NN (output_bfd
,
11336 (htab
->root
.sgotplt
->contents
11337 + GOT_ENTRY_SIZE (htab
) * 2));
11340 if (htab
->root
.sgot
)
11342 if (htab
->root
.sgot
->size
> 0)
11345 sdyn
? sdyn
->output_section
->vma
+ sdyn
->output_offset
: 0;
11346 bfd_put_NN (output_bfd
, addr
, htab
->root
.sgot
->contents
);
11350 elf_section_data (htab
->root
.sgotplt
->output_section
)->
11351 this_hdr
.sh_entsize
= GOT_ENTRY_SIZE (htab
);
11354 if (htab
->root
.sgot
&& htab
->root
.sgot
->size
> 0)
11355 elf_section_data (htab
->root
.sgot
->output_section
)->this_hdr
.sh_entsize
11356 = GOT_ENTRY_SIZE (htab
);
11358 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
11359 htab_traverse (htab
->loc_hash_table
,
11360 elfNN_aarch64_finish_local_dynamic_symbol
,
11366 /* Check if BTI enabled PLTs are needed. Returns the type needed. */
11367 static aarch64_plt_type
11368 get_plt_type (bfd
*abfd
)
11370 aarch64_plt_type ret
= PLT_NORMAL
;
11371 bfd_byte
*contents
, *extdyn
, *extdynend
;
11372 asection
*sec
= bfd_get_section_by_name (abfd
, ".dynamic");
11373 if (!sec
|| !bfd_malloc_and_get_section (abfd
, sec
, &contents
))
11376 extdynend
= contents
+ sec
->size
;
11377 for (; extdyn
< extdynend
; extdyn
+= sizeof (ElfNN_External_Dyn
))
11379 Elf_Internal_Dyn dyn
;
11380 bfd_elfNN_swap_dyn_in (abfd
, extdyn
, &dyn
);
11382 /* Let's check the processor specific dynamic array tags. */
11383 bfd_vma tag
= dyn
.d_tag
;
11384 if (tag
< DT_LOPROC
|| tag
> DT_HIPROC
)
11389 case DT_AARCH64_BTI_PLT
:
11393 case DT_AARCH64_PAC_PLT
:
11405 elfNN_aarch64_get_synthetic_symtab (bfd
*abfd
,
11412 elf_aarch64_tdata (abfd
)->plt_type
= get_plt_type (abfd
);
11413 return _bfd_elf_get_synthetic_symtab (abfd
, symcount
, syms
,
11414 dynsymcount
, dynsyms
, ret
);
11417 /* Return address for Ith PLT stub in section PLT, for relocation REL
11418 or (bfd_vma) -1 if it should not be included. */
11421 elfNN_aarch64_plt_sym_val (bfd_vma i
, const asection
*plt
,
11422 const arelent
*rel ATTRIBUTE_UNUSED
)
11424 size_t plt0_size
= PLT_ENTRY_SIZE
;
11425 size_t pltn_size
= PLT_SMALL_ENTRY_SIZE
;
11427 if (elf_aarch64_tdata (plt
->owner
)->plt_type
== PLT_BTI_PAC
)
11429 if (elf_elfheader (plt
->owner
)->e_type
== ET_EXEC
)
11430 pltn_size
= PLT_BTI_PAC_SMALL_ENTRY_SIZE
;
11432 pltn_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
11434 else if (elf_aarch64_tdata (plt
->owner
)->plt_type
== PLT_BTI
)
11436 if (elf_elfheader (plt
->owner
)->e_type
== ET_EXEC
)
11437 pltn_size
= PLT_BTI_SMALL_ENTRY_SIZE
;
11439 else if (elf_aarch64_tdata (plt
->owner
)->plt_type
== PLT_PAC
)
11441 pltn_size
= PLT_PAC_SMALL_ENTRY_SIZE
;
11444 return plt
->vma
+ plt0_size
+ i
* pltn_size
;
11447 /* Returns TRUE if NAME is an AArch64 mapping symbol.
11448 The ARM ELF standard defines $x (for A64 code) and $d (for data).
11449 It also allows a period initiated suffix to be added to the symbol, ie:
11450 "$[adtx]\.[:sym_char]+". */
11453 is_aarch64_mapping_symbol (const char * name
)
11455 return name
!= NULL
/* Paranoia. */
11456 && name
[0] == '$' /* Note: if objcopy --prefix-symbols has been used then
11457 the mapping symbols could have acquired a prefix.
11458 We do not support this here, since such symbols no
11459 longer conform to the ARM ELF ABI. */
11460 && (name
[1] == 'd' || name
[1] == 'x' || name
[1] == 'c')
11461 && (name
[2] == 0 || name
[2] == '.');
11462 /* FIXME: Strictly speaking the symbol is only a valid mapping symbol if
11463 any characters that follow the period are legal characters for the body
11464 of a symbol's name. For now we just assume that this is the case. */
11467 /* Make sure that mapping symbols in object files are not removed via the
11468 "strip --strip-unneeded" tool. These symbols might needed in order to
11469 correctly generate linked files. Once an object file has been linked,
11470 it should be safe to remove them. */
11473 elfNN_aarch64_backend_symbol_processing (bfd
*abfd
, asymbol
*sym
)
11475 if (((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
11476 && sym
->section
!= bfd_abs_section_ptr
11477 && is_aarch64_mapping_symbol (sym
->name
))
11478 sym
->flags
|= BSF_KEEP
;
11481 /* Implement elf_backend_setup_gnu_properties for AArch64. It serves as a
11482 wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account
11483 for the effect of GNU properties of the output_bfd. */
11485 elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info
*info
)
11487 uint32_t prop
= elf_aarch64_tdata (info
->output_bfd
)->gnu_and_prop
;
11488 bfd
*pbfd
= _bfd_aarch64_elf_link_setup_gnu_properties (info
, &prop
);
11489 elf_aarch64_tdata (info
->output_bfd
)->gnu_and_prop
= prop
;
11490 elf_aarch64_tdata (info
->output_bfd
)->plt_type
11491 |= (prop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
) ? PLT_BTI
: 0;
11495 /* Implement elf_backend_merge_gnu_properties for AArch64. It serves as a
11496 wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account
11497 for the effect of GNU properties of the output_bfd. */
11499 elfNN_aarch64_merge_gnu_properties (struct bfd_link_info
*info
,
11500 bfd
*abfd
, bfd
*bbfd
,
11501 elf_property
*aprop
,
11502 elf_property
*bprop
)
11505 = elf_aarch64_tdata (info
->output_bfd
)->gnu_and_prop
;
11507 /* If output has been marked with BTI using command line argument, give out
11508 warning if necessary. */
11509 /* Properties are merged per type, hence only check for warnings when merging
11510 GNU_PROPERTY_AARCH64_FEATURE_1_AND. */
11511 if (((aprop
&& aprop
->pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
)
11512 || (bprop
&& bprop
->pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
))
11513 && (prop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
)
11514 && (!elf_aarch64_tdata (info
->output_bfd
)->no_bti_warn
))
11516 if ((aprop
&& !(aprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
11519 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
11520 "all inputs do not have BTI in NOTE section."),
11523 if ((bprop
&& !(bprop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
11526 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
11527 "all inputs do not have BTI in NOTE section."),
11532 return _bfd_aarch64_elf_merge_gnu_properties (info
, abfd
, aprop
,
11536 /* Demangle c64 function symbols as we read them in. */
11539 aarch64_elfNN_swap_symbol_in (bfd
* abfd
,
11542 Elf_Internal_Sym
*dst
)
11544 if (!bfd_elfNN_swap_symbol_in (abfd
, psrc
, pshn
, dst
))
11547 dst
->st_target_internal
= 0;
11549 if (ELF_ST_TYPE (dst
->st_info
) == STT_FUNC
11550 || ELF_ST_TYPE (dst
->st_info
) == STT_GNU_IFUNC
)
11552 dst
->st_target_internal
= dst
->st_value
& ST_BRANCH_TO_C64
;
11553 dst
->st_value
&= ~(bfd_vma
) ST_BRANCH_TO_C64
;
11560 /* Mangle c64 function symbols as we write them out. */
11563 aarch64_elfNN_swap_symbol_out (bfd
*abfd
,
11564 const Elf_Internal_Sym
*src
,
11568 Elf_Internal_Sym newsym
= *src
;
11570 if ((ELF_ST_TYPE (newsym
.st_info
) == STT_FUNC
11571 || ELF_ST_TYPE (newsym
.st_info
) == STT_GNU_IFUNC
)
11572 && newsym
.st_shndx
!= SHN_UNDEF
)
11573 newsym
.st_value
|= newsym
.st_target_internal
;
11575 bfd_elfNN_swap_symbol_out (abfd
, &newsym
, cdst
, shndx
);
11578 /* Define the size of a GOT element for the generic mid-end. */
11581 elfNN_aarch64_got_elt_size (bfd
*abfd ATTRIBUTE_UNUSED
,
11582 struct bfd_link_info
*info
,
11583 struct elf_link_hash_entry
*h ATTRIBUTE_UNUSED
,
11584 bfd
*ibfd ATTRIBUTE_UNUSED
,
11585 unsigned long symndx ATTRIBUTE_UNUSED
)
11587 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
11589 return GOT_ENTRY_SIZE (htab
);
11592 /* Define the size of a GOT header, which is the minimum size of the GOT section
11593 when one is needed. */
11596 elfNN_aarch64_got_header_size (struct bfd_link_info
*info
)
11598 struct elf_aarch64_link_hash_table
*htab
= elf_aarch64_hash_table (info
);
11600 return GOT_ENTRY_SIZE (htab
) * GOT_RESERVED_HEADER_SLOTS
;
11603 /* Identify the 'C' in the CIE augmentation string. */
11606 elf64_aarch64_eh_frame_augmentation_char (const char aug
)
11611 /* We use this so we can override certain functions
11612 (though currently we don't). */
11614 const struct elf_size_info elfNN_aarch64_size_info
=
11616 sizeof (ElfNN_External_Ehdr
),
11617 sizeof (ElfNN_External_Phdr
),
11618 sizeof (ElfNN_External_Shdr
),
11619 sizeof (ElfNN_External_Rel
),
11620 sizeof (ElfNN_External_Rela
),
11621 sizeof (ElfNN_External_Sym
),
11622 sizeof (ElfNN_External_Dyn
),
11623 sizeof (Elf_External_Note
),
11624 4, /* Hash table entry size. */
11625 1, /* Internal relocs per external relocs. */
11626 ARCH_SIZE
, /* Arch size. */
11627 LOG_FILE_ALIGN
, /* Log_file_align. */
11628 ELFCLASSNN
, EV_CURRENT
,
11629 bfd_elfNN_write_out_phdrs
,
11630 bfd_elfNN_write_shdrs_and_ehdr
,
11631 bfd_elfNN_checksum_contents
,
11632 bfd_elfNN_write_relocs
,
11633 aarch64_elfNN_swap_symbol_in
,
11634 aarch64_elfNN_swap_symbol_out
,
11635 bfd_elfNN_slurp_reloc_table
,
11636 bfd_elfNN_slurp_symbol_table
,
11637 bfd_elfNN_swap_dyn_in
,
11638 bfd_elfNN_swap_dyn_out
,
11639 bfd_elfNN_swap_reloc_in
,
11640 bfd_elfNN_swap_reloc_out
,
11641 bfd_elfNN_swap_reloca_in
,
11642 bfd_elfNN_swap_reloca_out
11645 #define ELF_ARCH bfd_arch_aarch64
11646 #define ELF_MACHINE_CODE EM_AARCH64
11647 #define ELF_MAXPAGESIZE 0x10000
11648 #define ELF_MINPAGESIZE 0x1000
11649 #define ELF_COMMONPAGESIZE 0x1000
11651 #define bfd_elfNN_bfd_is_target_special_symbol \
11652 elfNN_aarch64_is_target_special_symbol
11654 #define bfd_elfNN_bfd_link_hash_table_create \
11655 elfNN_aarch64_link_hash_table_create
11657 #define bfd_elfNN_bfd_merge_private_bfd_data \
11658 elfNN_aarch64_merge_private_bfd_data
11660 #define bfd_elfNN_bfd_print_private_bfd_data \
11661 elfNN_aarch64_print_private_bfd_data
11663 #define bfd_elfNN_bfd_reloc_type_lookup \
11664 elfNN_aarch64_reloc_type_lookup
11666 #define bfd_elfNN_bfd_reloc_name_lookup \
11667 elfNN_aarch64_reloc_name_lookup
11669 #define bfd_elfNN_bfd_set_private_flags \
11670 elfNN_aarch64_set_private_flags
11672 #define bfd_elfNN_find_inliner_info \
11673 elfNN_aarch64_find_inliner_info
11675 #define bfd_elfNN_get_synthetic_symtab \
11676 elfNN_aarch64_get_synthetic_symtab
11678 #define bfd_elfNN_mkobject \
11679 elfNN_aarch64_mkobject
11681 #define bfd_elfNN_new_section_hook \
11682 elfNN_aarch64_new_section_hook
11684 #define elf_backend_adjust_dynamic_symbol \
11685 elfNN_aarch64_adjust_dynamic_symbol
11687 #define elf_backend_always_size_sections \
11688 elfNN_aarch64_always_size_sections
11690 #define elf_backend_check_relocs \
11691 elfNN_aarch64_check_relocs
11693 #define elf_backend_copy_indirect_symbol \
11694 elfNN_aarch64_copy_indirect_symbol
11696 #define elf_backend_merge_symbol_attribute \
11697 elfNN_aarch64_merge_symbol_attribute
11699 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
11700 to them in our hash. */
11701 #define elf_backend_create_dynamic_sections \
11702 elfNN_aarch64_create_dynamic_sections
11704 #define elf_backend_init_index_section \
11705 _bfd_elf_init_2_index_sections
11707 #define elf_backend_finish_dynamic_sections \
11708 elfNN_aarch64_finish_dynamic_sections
11710 #define elf_backend_finish_dynamic_symbol \
11711 elfNN_aarch64_finish_dynamic_symbol
11713 #define elf_backend_object_p \
11714 elfNN_aarch64_object_p
11716 #define elf_backend_output_arch_local_syms \
11717 elfNN_aarch64_output_arch_local_syms
11719 #define elf_backend_maybe_function_sym \
11720 elfNN_aarch64_maybe_function_sym
11722 #define elf_backend_plt_sym_val \
11723 elfNN_aarch64_plt_sym_val
11725 #define elf_backend_init_file_header \
11726 elfNN_aarch64_init_file_header
11728 #define elf_backend_relocate_section \
11729 elfNN_aarch64_relocate_section
11731 #define elf_backend_reloc_type_class \
11732 elfNN_aarch64_reloc_type_class
11734 #define elf_backend_section_from_shdr \
11735 elfNN_aarch64_section_from_shdr
11737 #define elf_backend_size_dynamic_sections \
11738 elfNN_aarch64_size_dynamic_sections
11740 #define elf_backend_size_info \
11741 elfNN_aarch64_size_info
11743 #define elf_backend_write_section \
11744 elfNN_aarch64_write_section
11746 #define elf_backend_symbol_processing \
11747 elfNN_aarch64_backend_symbol_processing
11749 #define elf_backend_setup_gnu_properties \
11750 elfNN_aarch64_link_setup_gnu_properties
11752 #define elf_backend_merge_gnu_properties \
11753 elfNN_aarch64_merge_gnu_properties
11755 #define elf_backend_got_header_size \
11756 elfNN_aarch64_got_header_size
11758 #define elf_backend_got_elt_size \
11759 elfNN_aarch64_got_elt_size
11761 #define elf_backend_eh_frame_augmentation_char \
11762 elf64_aarch64_eh_frame_augmentation_char
11764 #define elf_backend_can_refcount 1
11765 #define elf_backend_can_gc_sections 1
11766 #define elf_backend_plt_readonly 1
11767 #define elf_backend_want_got_plt 1
11768 #define elf_backend_want_plt_sym 0
11769 #define elf_backend_want_dynrelro 1
11770 #define elf_backend_may_use_rel_p 0
11771 #define elf_backend_may_use_rela_p 1
11772 #define elf_backend_default_use_rela_p 1
11773 #define elf_backend_rela_normal 1
11774 #define elf_backend_dtrel_excludes_plt 1
11775 #define elf_backend_default_execstack 0
11776 #define elf_backend_extern_protected_data 1
11777 #define elf_backend_hash_symbol elf_aarch64_hash_symbol
11779 #undef elf_backend_obj_attrs_section
11780 #define elf_backend_obj_attrs_section ".ARM.attributes"
11782 #include "elfNN-target.h"
11784 /* CloudABI support. */
11786 #undef TARGET_LITTLE_SYM
11787 #define TARGET_LITTLE_SYM aarch64_elfNN_le_cloudabi_vec
11788 #undef TARGET_LITTLE_NAME
11789 #define TARGET_LITTLE_NAME "elfNN-littleaarch64-cloudabi"
11790 #undef TARGET_BIG_SYM
11791 #define TARGET_BIG_SYM aarch64_elfNN_be_cloudabi_vec
11792 #undef TARGET_BIG_NAME
11793 #define TARGET_BIG_NAME "elfNN-bigaarch64-cloudabi"
11796 #define ELF_OSABI ELFOSABI_CLOUDABI
11799 #define elfNN_bed elfNN_aarch64_cloudabi_bed
11801 #include "elfNN-target.h"