]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elfnn-aarch64.c
[1/2][GAS][AARCH64]Add BFD_RELOC_AARCH64_TLSLE_LDST8/16/32/64_TPREL_LO12 support...
[thirdparty/binutils-gdb.git] / bfd / elfnn-aarch64.c
CommitLineData
cec5225b 1/* AArch64-specific support for NN-bit ELF.
219d1afa 2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
a06ea964
NC
3 Contributed by ARM Ltd.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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/>. */
20
21/* Notes on implementation:
22
23 Thread Local Store (TLS)
24
25 Overview:
26
27 The implementation currently supports both traditional TLS and TLS
28 descriptors, but only general dynamic (GD).
29
30 For traditional TLS the assembler will present us with code
31 fragments of the form:
32
33 adrp x0, :tlsgd:foo
07d6d2b8 34 R_AARCH64_TLSGD_ADR_PAGE21(foo)
a06ea964 35 add x0, :tlsgd_lo12:foo
07d6d2b8 36 R_AARCH64_TLSGD_ADD_LO12_NC(foo)
a06ea964
NC
37 bl __tls_get_addr
38 nop
39
40 For TLS descriptors the assembler will present us with code
41 fragments of the form:
42
07d6d2b8
AM
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)
a06ea964 46 .tlsdesccall foo
07d6d2b8 47 blr x1 R_AARCH64_TLSDESC_CALL(foo)
a06ea964
NC
48
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.
52
a6bb11b2 53 The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
a06ea964
NC
54 against foo indicate that 'foo' is thread local and should be accessed
55 via a TLS descriptor mechanism.
56
57 The precise instruction sequence is only relevant from the
58 perspective of linker relaxation which is currently not implemented.
59
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.
64
65 In the traditional TLS mechanism, the double GOT entry is used to
66 provide the tls_index structure, containing module and offset
a6bb11b2 67 entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
a06ea964
NC
68 on the module entry. The loader will subsequently fixup this
69 relocation with the module identity.
70
71 For global traditional TLS symbols the static linker places an
a6bb11b2 72 R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
a06ea964
NC
73 will subsequently fixup the offset. For local TLS symbols the static
74 linker fixes up offset.
75
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.
80
81 Implementation:
82
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.
86
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.
92
93 The flow:
94
cec5225b 95 elfNN_aarch64_check_relocs()
a06ea964
NC
96
97 This function is invoked for each relocation.
98
99 The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
a6bb11b2 100 R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
a06ea964
NC
101 spotted. One time creation of local symbol data structures are
102 created when the first local symbol is seen.
103
104 The reference count for a symbol is incremented. The GOT type for
105 each symbol is marked as general dynamic.
106
cec5225b 107 elfNN_aarch64_allocate_dynrelocs ()
a06ea964
NC
108
109 For each global with positive reference count we allocate a double
110 GOT slot. For a traditional TLS symbol we allocate space for two
111 relocation entries on the GOT, for a TLS descriptor symbol we
112 allocate space for one relocation on the slot. Record the GOT offset
113 for this symbol.
114
cec5225b 115 elfNN_aarch64_size_dynamic_sections ()
a06ea964
NC
116
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.
121
cec5225b 122 elfNN_aarch64_relocate_section ()
a06ea964 123
cec5225b 124 Calls elfNN_aarch64_final_link_relocate ()
a06ea964
NC
125
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.
133
cec5225b 134 elfNN_aarch64_final_link_relocate ()
a06ea964
NC
135
136 Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
137
138#include "sysdep.h"
139#include "bfd.h"
140#include "libiberty.h"
141#include "libbfd.h"
142#include "bfd_stdint.h"
143#include "elf-bfd.h"
144#include "bfdlink.h"
1419bbe5 145#include "objalloc.h"
a06ea964 146#include "elf/aarch64.h"
caed7120 147#include "elfxx-aarch64.h"
a06ea964 148
cec5225b
YZ
149#define ARCH_SIZE NN
150
151#if ARCH_SIZE == 64
152#define AARCH64_R(NAME) R_AARCH64_ ## NAME
153#define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
a6bb11b2
YZ
154#define HOWTO64(...) HOWTO (__VA_ARGS__)
155#define HOWTO32(...) EMPTY_HOWTO (0)
cec5225b 156#define LOG_FILE_ALIGN 3
f955cccf 157#define BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
cec5225b
YZ
158#endif
159
160#if ARCH_SIZE == 32
161#define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
162#define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
a6bb11b2
YZ
163#define HOWTO64(...) EMPTY_HOWTO (0)
164#define HOWTO32(...) HOWTO (__VA_ARGS__)
cec5225b 165#define LOG_FILE_ALIGN 2
07d6d2b8
AM
166#define BFD_RELOC_AARCH64_TLSDESC_LD32_LO12 BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
167#define R_AARCH64_P32_TLSDESC_ADD_LO12 R_AARCH64_P32_TLSDESC_ADD_LO12_NC
cec5225b
YZ
168#endif
169
a6bb11b2 170#define IS_AARCH64_TLS_RELOC(R_TYPE) \
4c0a9a6f
JW
171 ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
172 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
3c12b054 173 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
3e8286c0 174 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
1aa66fb1 175 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
a6bb11b2 176 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
a6bb11b2 177 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
4c0a9a6f 178 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
a6bb11b2 179 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
4c0a9a6f
JW
180 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
181 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
6ffe9a1b 182 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12 \
40fbed84 183 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12 \
753999c1 184 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC \
73f925cc 185 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
f69e4920 186 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
77a69ff8 187 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
07c9aa07
JW
188 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12 \
189 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC \
190 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12 \
191 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC \
192 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12 \
193 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC \
194 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12 \
195 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC \
6ffe9a1b
JW
196 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0 \
197 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC \
198 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1 \
199 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC \
200 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2 \
a6bb11b2 201 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
4c0a9a6f 202 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
a6bb11b2 203 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
a6bb11b2
YZ
204 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
205 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
4c0a9a6f
JW
206 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
207 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
208 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
a6bb11b2
YZ
209 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
210 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
211 || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
a06ea964
NC
212 || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
213
9331eea1 214#define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \
f955cccf
NC
215 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
216 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
4af68b9c
JW
217 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
218 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
219 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
220 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
221 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \
0484b454
RL
222 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
223 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
224 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
225 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
4af68b9c 226 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
9331eea1
JW
227 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
228 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
ac734732
RL
229 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC \
230 || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1 \
9331eea1
JW
231 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
232 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
233 || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \
259364ad
JW
234 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \
235 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \
4af68b9c 236 || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
9331eea1 237
a6bb11b2 238#define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
4c0a9a6f
JW
239 ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
240 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
f955cccf 241 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \
a6bb11b2 242 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
389b8029 243 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
4c0a9a6f 244 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
a6bb11b2 245 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
f955cccf 246 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12 \
a6bb11b2 247 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
4c0a9a6f
JW
248 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
249 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
250 || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
a06ea964 251
6353d82b 252#define ELIMINATE_COPY_RELOCS 1
a06ea964 253
a06ea964 254/* Return size of a relocation entry. HTAB is the bfd's
cec5225b
YZ
255 elf_aarch64_link_hash_entry. */
256#define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
a06ea964 257
cec5225b 258/* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
07d6d2b8
AM
259#define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
260#define PLT_ENTRY_SIZE (32)
261#define PLT_SMALL_ENTRY_SIZE (16)
262#define PLT_TLSDESC_ENTRY_SIZE (32)
a06ea964 263
2d0ca824 264/* Encoding of the nop instruction. */
a06ea964
NC
265#define INSN_NOP 0xd503201f
266
267#define aarch64_compute_jump_table_size(htab) \
268 (((htab)->root.srelplt == NULL) ? 0 \
269 : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
270
271/* The first entry in a procedure linkage table looks like this
272 if the distance between the PLTGOT and the PLT is < 4GB use
273 these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
274 in x16 and needs to work out PLTGOT[1] by using an address of
cec5225b
YZ
275 [x16,#-GOT_ENTRY_SIZE]. */
276static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
a06ea964
NC
277{
278 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
279 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
caed7120 280#if ARCH_SIZE == 64
a06ea964
NC
281 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
282 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
caed7120
YZ
283#else
284 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
285 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
286#endif
a06ea964
NC
287 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
288 0x1f, 0x20, 0x03, 0xd5, /* nop */
289 0x1f, 0x20, 0x03, 0xd5, /* nop */
290 0x1f, 0x20, 0x03, 0xd5, /* nop */
291};
292
293/* Per function entry in a procedure linkage table looks like this
294 if the distance between the PLTGOT and the PLT is < 4GB use
295 these PLT entries. */
cec5225b 296static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
a06ea964
NC
297{
298 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
caed7120 299#if ARCH_SIZE == 64
a06ea964
NC
300 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
301 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
caed7120
YZ
302#else
303 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
304 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
305#endif
a06ea964
NC
306 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
307};
308
309static const bfd_byte
cec5225b 310elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
a06ea964
NC
311{
312 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
313 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
314 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
caed7120
YZ
315#if ARCH_SIZE == 64
316 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
a06ea964 317 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
caed7120
YZ
318#else
319 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
320 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
321#endif
322 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
a06ea964
NC
323 0x1f, 0x20, 0x03, 0xd5, /* nop */
324 0x1f, 0x20, 0x03, 0xd5, /* nop */
325};
326
07d6d2b8
AM
327#define elf_info_to_howto elfNN_aarch64_info_to_howto
328#define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
a06ea964
NC
329
330#define AARCH64_ELF_ABI_VERSION 0
a06ea964
NC
331
332/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
333#define ALL_ONES (~ (bfd_vma) 0)
334
a6bb11b2
YZ
335/* Indexed by the bfd interal reloc enumerators.
336 Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
337 in reloc.c. */
a06ea964 338
a6bb11b2 339static reloc_howto_type elfNN_aarch64_howto_table[] =
a06ea964 340{
a6bb11b2 341 EMPTY_HOWTO (0),
a06ea964 342
a6bb11b2 343 /* Basic data relocations. */
a06ea964 344
b7f28d87
JW
345 /* Deprecated, but retained for backwards compatibility. */
346 HOWTO64 (R_AARCH64_NULL, /* type */
a06ea964 347 0, /* rightshift */
6346d5ca 348 3, /* size (0 = byte, 1 = short, 2 = long) */
a6bb11b2 349 0, /* bitsize */
a06ea964
NC
350 FALSE, /* pc_relative */
351 0, /* bitpos */
352 complain_overflow_dont, /* complain_on_overflow */
353 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 354 "R_AARCH64_NULL", /* name */
a06ea964
NC
355 FALSE, /* partial_inplace */
356 0, /* src_mask */
a6bb11b2 357 0, /* dst_mask */
a06ea964 358 FALSE), /* pcrel_offset */
a6bb11b2 359 HOWTO (R_AARCH64_NONE, /* type */
a06ea964 360 0, /* rightshift */
6346d5ca 361 3, /* size (0 = byte, 1 = short, 2 = long) */
a06ea964
NC
362 0, /* bitsize */
363 FALSE, /* pc_relative */
364 0, /* bitpos */
365 complain_overflow_dont, /* complain_on_overflow */
366 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 367 "R_AARCH64_NONE", /* name */
a06ea964
NC
368 FALSE, /* partial_inplace */
369 0, /* src_mask */
370 0, /* dst_mask */
371 FALSE), /* pcrel_offset */
372
373 /* .xword: (S+A) */
a6bb11b2 374 HOWTO64 (AARCH64_R (ABS64), /* type */
a06ea964
NC
375 0, /* rightshift */
376 4, /* size (4 = long long) */
377 64, /* bitsize */
378 FALSE, /* pc_relative */
379 0, /* bitpos */
380 complain_overflow_unsigned, /* complain_on_overflow */
381 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 382 AARCH64_R_STR (ABS64), /* name */
a06ea964
NC
383 FALSE, /* partial_inplace */
384 ALL_ONES, /* src_mask */
385 ALL_ONES, /* dst_mask */
386 FALSE), /* pcrel_offset */
387
388 /* .word: (S+A) */
a6bb11b2 389 HOWTO (AARCH64_R (ABS32), /* type */
a06ea964
NC
390 0, /* rightshift */
391 2, /* size (0 = byte, 1 = short, 2 = long) */
392 32, /* bitsize */
393 FALSE, /* pc_relative */
394 0, /* bitpos */
395 complain_overflow_unsigned, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 397 AARCH64_R_STR (ABS32), /* name */
a06ea964
NC
398 FALSE, /* partial_inplace */
399 0xffffffff, /* src_mask */
400 0xffffffff, /* dst_mask */
401 FALSE), /* pcrel_offset */
402
403 /* .half: (S+A) */
a6bb11b2 404 HOWTO (AARCH64_R (ABS16), /* type */
a06ea964
NC
405 0, /* rightshift */
406 1, /* size (0 = byte, 1 = short, 2 = long) */
407 16, /* bitsize */
408 FALSE, /* pc_relative */
409 0, /* bitpos */
410 complain_overflow_unsigned, /* complain_on_overflow */
411 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 412 AARCH64_R_STR (ABS16), /* name */
a06ea964
NC
413 FALSE, /* partial_inplace */
414 0xffff, /* src_mask */
415 0xffff, /* dst_mask */
416 FALSE), /* pcrel_offset */
417
418 /* .xword: (S+A-P) */
a6bb11b2 419 HOWTO64 (AARCH64_R (PREL64), /* type */
a06ea964
NC
420 0, /* rightshift */
421 4, /* size (4 = long long) */
422 64, /* bitsize */
423 TRUE, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_signed, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 427 AARCH64_R_STR (PREL64), /* name */
a06ea964
NC
428 FALSE, /* partial_inplace */
429 ALL_ONES, /* src_mask */
430 ALL_ONES, /* dst_mask */
431 TRUE), /* pcrel_offset */
432
433 /* .word: (S+A-P) */
a6bb11b2 434 HOWTO (AARCH64_R (PREL32), /* type */
a06ea964
NC
435 0, /* rightshift */
436 2, /* size (0 = byte, 1 = short, 2 = long) */
437 32, /* bitsize */
438 TRUE, /* pc_relative */
439 0, /* bitpos */
440 complain_overflow_signed, /* complain_on_overflow */
441 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 442 AARCH64_R_STR (PREL32), /* name */
a06ea964
NC
443 FALSE, /* partial_inplace */
444 0xffffffff, /* src_mask */
445 0xffffffff, /* dst_mask */
446 TRUE), /* pcrel_offset */
447
448 /* .half: (S+A-P) */
a6bb11b2 449 HOWTO (AARCH64_R (PREL16), /* type */
a06ea964
NC
450 0, /* rightshift */
451 1, /* size (0 = byte, 1 = short, 2 = long) */
452 16, /* bitsize */
453 TRUE, /* pc_relative */
454 0, /* bitpos */
455 complain_overflow_signed, /* complain_on_overflow */
456 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 457 AARCH64_R_STR (PREL16), /* name */
a06ea964
NC
458 FALSE, /* partial_inplace */
459 0xffff, /* src_mask */
460 0xffff, /* dst_mask */
461 TRUE), /* pcrel_offset */
462
463 /* Group relocations to create a 16, 32, 48 or 64 bit
464 unsigned data or abs address inline. */
465
466 /* MOVZ: ((S+A) >> 0) & 0xffff */
a6bb11b2 467 HOWTO (AARCH64_R (MOVW_UABS_G0), /* type */
a06ea964
NC
468 0, /* rightshift */
469 2, /* size (0 = byte, 1 = short, 2 = long) */
470 16, /* bitsize */
471 FALSE, /* pc_relative */
472 0, /* bitpos */
473 complain_overflow_unsigned, /* complain_on_overflow */
474 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 475 AARCH64_R_STR (MOVW_UABS_G0), /* name */
a06ea964
NC
476 FALSE, /* partial_inplace */
477 0xffff, /* src_mask */
478 0xffff, /* dst_mask */
479 FALSE), /* pcrel_offset */
480
481 /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
a6bb11b2 482 HOWTO (AARCH64_R (MOVW_UABS_G0_NC), /* type */
a06ea964
NC
483 0, /* rightshift */
484 2, /* size (0 = byte, 1 = short, 2 = long) */
485 16, /* bitsize */
486 FALSE, /* pc_relative */
487 0, /* bitpos */
488 complain_overflow_dont, /* complain_on_overflow */
489 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 490 AARCH64_R_STR (MOVW_UABS_G0_NC), /* name */
a06ea964
NC
491 FALSE, /* partial_inplace */
492 0xffff, /* src_mask */
493 0xffff, /* dst_mask */
494 FALSE), /* pcrel_offset */
495
496 /* MOVZ: ((S+A) >> 16) & 0xffff */
a6bb11b2 497 HOWTO (AARCH64_R (MOVW_UABS_G1), /* type */
a06ea964
NC
498 16, /* rightshift */
499 2, /* size (0 = byte, 1 = short, 2 = long) */
500 16, /* bitsize */
501 FALSE, /* pc_relative */
502 0, /* bitpos */
503 complain_overflow_unsigned, /* complain_on_overflow */
504 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 505 AARCH64_R_STR (MOVW_UABS_G1), /* name */
a06ea964
NC
506 FALSE, /* partial_inplace */
507 0xffff, /* src_mask */
508 0xffff, /* dst_mask */
509 FALSE), /* pcrel_offset */
510
511 /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
a6bb11b2 512 HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC), /* type */
a06ea964
NC
513 16, /* rightshift */
514 2, /* size (0 = byte, 1 = short, 2 = long) */
515 16, /* bitsize */
516 FALSE, /* pc_relative */
517 0, /* bitpos */
518 complain_overflow_dont, /* complain_on_overflow */
519 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 520 AARCH64_R_STR (MOVW_UABS_G1_NC), /* name */
a06ea964
NC
521 FALSE, /* partial_inplace */
522 0xffff, /* src_mask */
523 0xffff, /* dst_mask */
524 FALSE), /* pcrel_offset */
525
526 /* MOVZ: ((S+A) >> 32) & 0xffff */
a6bb11b2 527 HOWTO64 (AARCH64_R (MOVW_UABS_G2), /* type */
a06ea964
NC
528 32, /* rightshift */
529 2, /* size (0 = byte, 1 = short, 2 = long) */
530 16, /* bitsize */
531 FALSE, /* pc_relative */
532 0, /* bitpos */
533 complain_overflow_unsigned, /* complain_on_overflow */
534 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 535 AARCH64_R_STR (MOVW_UABS_G2), /* name */
a06ea964
NC
536 FALSE, /* partial_inplace */
537 0xffff, /* src_mask */
538 0xffff, /* dst_mask */
539 FALSE), /* pcrel_offset */
540
541 /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
a6bb11b2 542 HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC), /* type */
a06ea964
NC
543 32, /* rightshift */
544 2, /* size (0 = byte, 1 = short, 2 = long) */
545 16, /* bitsize */
546 FALSE, /* pc_relative */
547 0, /* bitpos */
548 complain_overflow_dont, /* complain_on_overflow */
549 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 550 AARCH64_R_STR (MOVW_UABS_G2_NC), /* name */
a06ea964
NC
551 FALSE, /* partial_inplace */
552 0xffff, /* src_mask */
553 0xffff, /* dst_mask */
554 FALSE), /* pcrel_offset */
555
556 /* MOVZ: ((S+A) >> 48) & 0xffff */
a6bb11b2 557 HOWTO64 (AARCH64_R (MOVW_UABS_G3), /* type */
a06ea964
NC
558 48, /* rightshift */
559 2, /* size (0 = byte, 1 = short, 2 = long) */
560 16, /* bitsize */
561 FALSE, /* pc_relative */
562 0, /* bitpos */
563 complain_overflow_unsigned, /* complain_on_overflow */
564 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 565 AARCH64_R_STR (MOVW_UABS_G3), /* name */
a06ea964
NC
566 FALSE, /* partial_inplace */
567 0xffff, /* src_mask */
568 0xffff, /* dst_mask */
569 FALSE), /* pcrel_offset */
570
571 /* Group relocations to create high part of a 16, 32, 48 or 64 bit
572 signed data or abs address inline. Will change instruction
573 to MOVN or MOVZ depending on sign of calculated value. */
574
575 /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
a6bb11b2 576 HOWTO (AARCH64_R (MOVW_SABS_G0), /* type */
a06ea964
NC
577 0, /* rightshift */
578 2, /* size (0 = byte, 1 = short, 2 = long) */
c5e3a364 579 17, /* bitsize */
a06ea964
NC
580 FALSE, /* pc_relative */
581 0, /* bitpos */
582 complain_overflow_signed, /* complain_on_overflow */
583 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 584 AARCH64_R_STR (MOVW_SABS_G0), /* name */
a06ea964
NC
585 FALSE, /* partial_inplace */
586 0xffff, /* src_mask */
587 0xffff, /* dst_mask */
588 FALSE), /* pcrel_offset */
589
590 /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
a6bb11b2 591 HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
a06ea964
NC
592 16, /* rightshift */
593 2, /* size (0 = byte, 1 = short, 2 = long) */
c5e3a364 594 17, /* bitsize */
a06ea964
NC
595 FALSE, /* pc_relative */
596 0, /* bitpos */
597 complain_overflow_signed, /* complain_on_overflow */
598 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 599 AARCH64_R_STR (MOVW_SABS_G1), /* name */
a06ea964
NC
600 FALSE, /* partial_inplace */
601 0xffff, /* src_mask */
602 0xffff, /* dst_mask */
603 FALSE), /* pcrel_offset */
604
605 /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
a6bb11b2 606 HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
a06ea964
NC
607 32, /* rightshift */
608 2, /* size (0 = byte, 1 = short, 2 = long) */
c5e3a364 609 17, /* bitsize */
a06ea964
NC
610 FALSE, /* pc_relative */
611 0, /* bitpos */
612 complain_overflow_signed, /* complain_on_overflow */
613 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 614 AARCH64_R_STR (MOVW_SABS_G2), /* name */
a06ea964
NC
615 FALSE, /* partial_inplace */
616 0xffff, /* src_mask */
617 0xffff, /* dst_mask */
618 FALSE), /* pcrel_offset */
619
32247401
RL
620 /* Group relocations to create a 16, 32, 48 or 64 bit
621 PC relative address inline. */
622
623 /* MOV[NZ]: ((S+A-P) >> 0) & 0xffff */
624 HOWTO64 (AARCH64_R (MOVW_PREL_G0), /* type */
625 0, /* rightshift */
626 2, /* size (0 = byte, 1 = short, 2 = long) */
627 17, /* bitsize */
628 TRUE, /* pc_relative */
629 0, /* bitpos */
630 complain_overflow_signed, /* complain_on_overflow */
631 bfd_elf_generic_reloc, /* special_function */
632 AARCH64_R_STR (MOVW_PREL_G0), /* name */
633 FALSE, /* partial_inplace */
634 0xffff, /* src_mask */
635 0xffff, /* dst_mask */
636 TRUE), /* pcrel_offset */
637
638 /* MOVK: ((S+A-P) >> 0) & 0xffff [no overflow check] */
639 HOWTO64 (AARCH64_R (MOVW_PREL_G0_NC), /* type */
640 0, /* rightshift */
641 2, /* size (0 = byte, 1 = short, 2 = long) */
642 16, /* bitsize */
643 TRUE, /* pc_relative */
644 0, /* bitpos */
645 complain_overflow_dont, /* complain_on_overflow */
646 bfd_elf_generic_reloc, /* special_function */
647 AARCH64_R_STR (MOVW_PREL_G0_NC), /* name */
648 FALSE, /* partial_inplace */
649 0xffff, /* src_mask */
650 0xffff, /* dst_mask */
651 TRUE), /* pcrel_offset */
652
653 /* MOV[NZ]: ((S+A-P) >> 16) & 0xffff */
654 HOWTO64 (AARCH64_R (MOVW_PREL_G1), /* type */
655 16, /* rightshift */
656 2, /* size (0 = byte, 1 = short, 2 = long) */
657 17, /* bitsize */
658 TRUE, /* pc_relative */
659 0, /* bitpos */
660 complain_overflow_signed, /* complain_on_overflow */
661 bfd_elf_generic_reloc, /* special_function */
662 AARCH64_R_STR (MOVW_PREL_G1), /* name */
663 FALSE, /* partial_inplace */
664 0xffff, /* src_mask */
665 0xffff, /* dst_mask */
666 TRUE), /* pcrel_offset */
667
668 /* MOVK: ((S+A-P) >> 16) & 0xffff [no overflow check] */
669 HOWTO64 (AARCH64_R (MOVW_PREL_G1_NC), /* type */
670 16, /* rightshift */
671 2, /* size (0 = byte, 1 = short, 2 = long) */
672 16, /* bitsize */
673 TRUE, /* pc_relative */
674 0, /* bitpos */
675 complain_overflow_dont, /* complain_on_overflow */
676 bfd_elf_generic_reloc, /* special_function */
677 AARCH64_R_STR (MOVW_PREL_G1_NC), /* name */
678 FALSE, /* partial_inplace */
679 0xffff, /* src_mask */
680 0xffff, /* dst_mask */
681 TRUE), /* pcrel_offset */
682
683 /* MOV[NZ]: ((S+A-P) >> 32) & 0xffff */
684 HOWTO64 (AARCH64_R (MOVW_PREL_G2), /* type */
685 32, /* rightshift */
686 2, /* size (0 = byte, 1 = short, 2 = long) */
687 17, /* bitsize */
688 TRUE, /* pc_relative */
689 0, /* bitpos */
690 complain_overflow_signed, /* complain_on_overflow */
691 bfd_elf_generic_reloc, /* special_function */
692 AARCH64_R_STR (MOVW_PREL_G2), /* name */
693 FALSE, /* partial_inplace */
694 0xffff, /* src_mask */
695 0xffff, /* dst_mask */
696 TRUE), /* pcrel_offset */
697
698 /* MOVK: ((S+A-P) >> 32) & 0xffff [no overflow check] */
699 HOWTO64 (AARCH64_R (MOVW_PREL_G2_NC), /* type */
700 32, /* rightshift */
701 2, /* size (0 = byte, 1 = short, 2 = long) */
702 16, /* bitsize */
703 TRUE, /* pc_relative */
704 0, /* bitpos */
705 complain_overflow_dont, /* complain_on_overflow */
706 bfd_elf_generic_reloc, /* special_function */
707 AARCH64_R_STR (MOVW_PREL_G2_NC), /* name */
708 FALSE, /* partial_inplace */
709 0xffff, /* src_mask */
710 0xffff, /* dst_mask */
711 TRUE), /* pcrel_offset */
712
713 /* MOV[NZ]: ((S+A-P) >> 48) & 0xffff */
714 HOWTO64 (AARCH64_R (MOVW_PREL_G3), /* type */
715 48, /* rightshift */
716 2, /* size (0 = byte, 1 = short, 2 = long) */
717 16, /* bitsize */
718 TRUE, /* pc_relative */
719 0, /* bitpos */
720 complain_overflow_dont, /* complain_on_overflow */
721 bfd_elf_generic_reloc, /* special_function */
722 AARCH64_R_STR (MOVW_PREL_G3), /* name */
723 FALSE, /* partial_inplace */
724 0xffff, /* src_mask */
725 0xffff, /* dst_mask */
726 TRUE), /* pcrel_offset */
727
a06ea964
NC
728/* Relocations to generate 19, 21 and 33 bit PC-relative load/store
729 addresses: PG(x) is (x & ~0xfff). */
730
731 /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
a6bb11b2 732 HOWTO (AARCH64_R (LD_PREL_LO19), /* type */
a06ea964
NC
733 2, /* rightshift */
734 2, /* size (0 = byte, 1 = short, 2 = long) */
735 19, /* bitsize */
736 TRUE, /* pc_relative */
737 0, /* bitpos */
738 complain_overflow_signed, /* complain_on_overflow */
739 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 740 AARCH64_R_STR (LD_PREL_LO19), /* name */
a06ea964
NC
741 FALSE, /* partial_inplace */
742 0x7ffff, /* src_mask */
743 0x7ffff, /* dst_mask */
744 TRUE), /* pcrel_offset */
745
746 /* ADR: (S+A-P) & 0x1fffff */
a6bb11b2 747 HOWTO (AARCH64_R (ADR_PREL_LO21), /* type */
a06ea964
NC
748 0, /* rightshift */
749 2, /* size (0 = byte, 1 = short, 2 = long) */
750 21, /* bitsize */
751 TRUE, /* pc_relative */
752 0, /* bitpos */
753 complain_overflow_signed, /* complain_on_overflow */
754 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 755 AARCH64_R_STR (ADR_PREL_LO21), /* name */
a06ea964
NC
756 FALSE, /* partial_inplace */
757 0x1fffff, /* src_mask */
758 0x1fffff, /* dst_mask */
759 TRUE), /* pcrel_offset */
760
761 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
a6bb11b2 762 HOWTO (AARCH64_R (ADR_PREL_PG_HI21), /* type */
a06ea964
NC
763 12, /* rightshift */
764 2, /* size (0 = byte, 1 = short, 2 = long) */
765 21, /* bitsize */
766 TRUE, /* pc_relative */
767 0, /* bitpos */
768 complain_overflow_signed, /* complain_on_overflow */
769 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 770 AARCH64_R_STR (ADR_PREL_PG_HI21), /* name */
a06ea964
NC
771 FALSE, /* partial_inplace */
772 0x1fffff, /* src_mask */
773 0x1fffff, /* dst_mask */
774 TRUE), /* pcrel_offset */
775
776 /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
a6bb11b2 777 HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC), /* type */
a06ea964
NC
778 12, /* rightshift */
779 2, /* size (0 = byte, 1 = short, 2 = long) */
780 21, /* bitsize */
781 TRUE, /* pc_relative */
782 0, /* bitpos */
783 complain_overflow_dont, /* complain_on_overflow */
784 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 785 AARCH64_R_STR (ADR_PREL_PG_HI21_NC), /* name */
a06ea964
NC
786 FALSE, /* partial_inplace */
787 0x1fffff, /* src_mask */
788 0x1fffff, /* dst_mask */
789 TRUE), /* pcrel_offset */
790
791 /* ADD: (S+A) & 0xfff [no overflow check] */
a6bb11b2 792 HOWTO (AARCH64_R (ADD_ABS_LO12_NC), /* type */
a06ea964
NC
793 0, /* rightshift */
794 2, /* size (0 = byte, 1 = short, 2 = long) */
795 12, /* bitsize */
796 FALSE, /* pc_relative */
797 10, /* bitpos */
798 complain_overflow_dont, /* complain_on_overflow */
799 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 800 AARCH64_R_STR (ADD_ABS_LO12_NC), /* name */
a06ea964
NC
801 FALSE, /* partial_inplace */
802 0x3ffc00, /* src_mask */
803 0x3ffc00, /* dst_mask */
804 FALSE), /* pcrel_offset */
805
806 /* LD/ST8: (S+A) & 0xfff */
a6bb11b2 807 HOWTO (AARCH64_R (LDST8_ABS_LO12_NC), /* type */
a06ea964
NC
808 0, /* rightshift */
809 2, /* size (0 = byte, 1 = short, 2 = long) */
810 12, /* bitsize */
811 FALSE, /* pc_relative */
812 0, /* bitpos */
813 complain_overflow_dont, /* complain_on_overflow */
814 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 815 AARCH64_R_STR (LDST8_ABS_LO12_NC), /* name */
a06ea964
NC
816 FALSE, /* partial_inplace */
817 0xfff, /* src_mask */
818 0xfff, /* dst_mask */
819 FALSE), /* pcrel_offset */
820
821 /* Relocations for control-flow instructions. */
822
823 /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
a6bb11b2 824 HOWTO (AARCH64_R (TSTBR14), /* type */
a06ea964
NC
825 2, /* rightshift */
826 2, /* size (0 = byte, 1 = short, 2 = long) */
827 14, /* bitsize */
828 TRUE, /* pc_relative */
829 0, /* bitpos */
830 complain_overflow_signed, /* complain_on_overflow */
831 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 832 AARCH64_R_STR (TSTBR14), /* name */
a06ea964
NC
833 FALSE, /* partial_inplace */
834 0x3fff, /* src_mask */
835 0x3fff, /* dst_mask */
836 TRUE), /* pcrel_offset */
837
838 /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
a6bb11b2 839 HOWTO (AARCH64_R (CONDBR19), /* type */
a06ea964
NC
840 2, /* rightshift */
841 2, /* size (0 = byte, 1 = short, 2 = long) */
842 19, /* bitsize */
843 TRUE, /* pc_relative */
844 0, /* bitpos */
845 complain_overflow_signed, /* complain_on_overflow */
846 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 847 AARCH64_R_STR (CONDBR19), /* name */
a06ea964
NC
848 FALSE, /* partial_inplace */
849 0x7ffff, /* src_mask */
850 0x7ffff, /* dst_mask */
851 TRUE), /* pcrel_offset */
852
a06ea964 853 /* B: ((S+A-P) >> 2) & 0x3ffffff */
a6bb11b2 854 HOWTO (AARCH64_R (JUMP26), /* type */
a06ea964
NC
855 2, /* rightshift */
856 2, /* size (0 = byte, 1 = short, 2 = long) */
857 26, /* bitsize */
858 TRUE, /* pc_relative */
859 0, /* bitpos */
860 complain_overflow_signed, /* complain_on_overflow */
861 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 862 AARCH64_R_STR (JUMP26), /* name */
a06ea964
NC
863 FALSE, /* partial_inplace */
864 0x3ffffff, /* src_mask */
865 0x3ffffff, /* dst_mask */
866 TRUE), /* pcrel_offset */
867
868 /* BL: ((S+A-P) >> 2) & 0x3ffffff */
a6bb11b2 869 HOWTO (AARCH64_R (CALL26), /* type */
a06ea964
NC
870 2, /* rightshift */
871 2, /* size (0 = byte, 1 = short, 2 = long) */
872 26, /* bitsize */
873 TRUE, /* pc_relative */
874 0, /* bitpos */
875 complain_overflow_signed, /* complain_on_overflow */
876 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 877 AARCH64_R_STR (CALL26), /* name */
a06ea964
NC
878 FALSE, /* partial_inplace */
879 0x3ffffff, /* src_mask */
880 0x3ffffff, /* dst_mask */
881 TRUE), /* pcrel_offset */
882
883 /* LD/ST16: (S+A) & 0xffe */
a6bb11b2 884 HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */
a06ea964
NC
885 1, /* rightshift */
886 2, /* size (0 = byte, 1 = short, 2 = long) */
887 12, /* bitsize */
888 FALSE, /* pc_relative */
889 0, /* bitpos */
890 complain_overflow_dont, /* complain_on_overflow */
891 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 892 AARCH64_R_STR (LDST16_ABS_LO12_NC), /* name */
a06ea964
NC
893 FALSE, /* partial_inplace */
894 0xffe, /* src_mask */
895 0xffe, /* dst_mask */
896 FALSE), /* pcrel_offset */
897
898 /* LD/ST32: (S+A) & 0xffc */
a6bb11b2 899 HOWTO (AARCH64_R (LDST32_ABS_LO12_NC), /* type */
a06ea964
NC
900 2, /* rightshift */
901 2, /* size (0 = byte, 1 = short, 2 = long) */
902 12, /* bitsize */
903 FALSE, /* pc_relative */
904 0, /* bitpos */
905 complain_overflow_dont, /* complain_on_overflow */
906 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 907 AARCH64_R_STR (LDST32_ABS_LO12_NC), /* name */
a06ea964
NC
908 FALSE, /* partial_inplace */
909 0xffc, /* src_mask */
910 0xffc, /* dst_mask */
911 FALSE), /* pcrel_offset */
912
913 /* LD/ST64: (S+A) & 0xff8 */
a6bb11b2 914 HOWTO (AARCH64_R (LDST64_ABS_LO12_NC), /* type */
a06ea964
NC
915 3, /* rightshift */
916 2, /* size (0 = byte, 1 = short, 2 = long) */
917 12, /* bitsize */
918 FALSE, /* pc_relative */
919 0, /* bitpos */
920 complain_overflow_dont, /* complain_on_overflow */
921 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 922 AARCH64_R_STR (LDST64_ABS_LO12_NC), /* name */
a06ea964
NC
923 FALSE, /* partial_inplace */
924 0xff8, /* src_mask */
925 0xff8, /* dst_mask */
926 FALSE), /* pcrel_offset */
927
a06ea964 928 /* LD/ST128: (S+A) & 0xff0 */
a6bb11b2 929 HOWTO (AARCH64_R (LDST128_ABS_LO12_NC), /* type */
a06ea964
NC
930 4, /* rightshift */
931 2, /* size (0 = byte, 1 = short, 2 = long) */
932 12, /* bitsize */
933 FALSE, /* pc_relative */
934 0, /* bitpos */
935 complain_overflow_dont, /* complain_on_overflow */
936 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 937 AARCH64_R_STR (LDST128_ABS_LO12_NC), /* name */
a06ea964
NC
938 FALSE, /* partial_inplace */
939 0xff0, /* src_mask */
940 0xff0, /* dst_mask */
941 FALSE), /* pcrel_offset */
942
f41aef5f
RE
943 /* Set a load-literal immediate field to bits
944 0x1FFFFC of G(S)-P */
a6bb11b2 945 HOWTO (AARCH64_R (GOT_LD_PREL19), /* type */
f41aef5f
RE
946 2, /* rightshift */
947 2, /* size (0 = byte,1 = short,2 = long) */
948 19, /* bitsize */
949 TRUE, /* pc_relative */
950 0, /* bitpos */
951 complain_overflow_signed, /* complain_on_overflow */
952 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 953 AARCH64_R_STR (GOT_LD_PREL19), /* name */
f41aef5f
RE
954 FALSE, /* partial_inplace */
955 0xffffe0, /* src_mask */
956 0xffffe0, /* dst_mask */
957 TRUE), /* pcrel_offset */
958
a06ea964
NC
959 /* Get to the page for the GOT entry for the symbol
960 (G(S) - P) using an ADRP instruction. */
a6bb11b2 961 HOWTO (AARCH64_R (ADR_GOT_PAGE), /* type */
a06ea964
NC
962 12, /* rightshift */
963 2, /* size (0 = byte, 1 = short, 2 = long) */
964 21, /* bitsize */
965 TRUE, /* pc_relative */
966 0, /* bitpos */
967 complain_overflow_dont, /* complain_on_overflow */
968 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 969 AARCH64_R_STR (ADR_GOT_PAGE), /* name */
a06ea964
NC
970 FALSE, /* partial_inplace */
971 0x1fffff, /* src_mask */
972 0x1fffff, /* dst_mask */
973 TRUE), /* pcrel_offset */
974
a6bb11b2
YZ
975 /* LD64: GOT offset G(S) & 0xff8 */
976 HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC), /* type */
a06ea964
NC
977 3, /* rightshift */
978 2, /* size (0 = byte, 1 = short, 2 = long) */
979 12, /* bitsize */
980 FALSE, /* pc_relative */
981 0, /* bitpos */
982 complain_overflow_dont, /* complain_on_overflow */
983 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 984 AARCH64_R_STR (LD64_GOT_LO12_NC), /* name */
a06ea964
NC
985 FALSE, /* partial_inplace */
986 0xff8, /* src_mask */
987 0xff8, /* dst_mask */
a6bb11b2 988 FALSE), /* pcrel_offset */
a06ea964 989
a6bb11b2
YZ
990 /* LD32: GOT offset G(S) & 0xffc */
991 HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC), /* type */
992 2, /* rightshift */
993 2, /* size (0 = byte, 1 = short, 2 = long) */
994 12, /* bitsize */
995 FALSE, /* pc_relative */
996 0, /* bitpos */
997 complain_overflow_dont, /* complain_on_overflow */
998 bfd_elf_generic_reloc, /* special_function */
999 AARCH64_R_STR (LD32_GOT_LO12_NC), /* name */
1000 FALSE, /* partial_inplace */
1001 0xffc, /* src_mask */
1002 0xffc, /* dst_mask */
1003 FALSE), /* pcrel_offset */
a06ea964 1004
ca632371
RL
1005 /* Lower 16 bits of GOT offset for the symbol. */
1006 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G0_NC), /* type */
1007 0, /* rightshift */
1008 2, /* size (0 = byte, 1 = short, 2 = long) */
1009 16, /* bitsize */
1010 FALSE, /* pc_relative */
1011 0, /* bitpos */
1012 complain_overflow_dont, /* complain_on_overflow */
1013 bfd_elf_generic_reloc, /* special_function */
1014 AARCH64_R_STR (MOVW_GOTOFF_G0_NC), /* name */
1015 FALSE, /* partial_inplace */
1016 0xffff, /* src_mask */
1017 0xffff, /* dst_mask */
1018 FALSE), /* pcrel_offset */
1019
654248e7
RL
1020 /* Higher 16 bits of GOT offset for the symbol. */
1021 HOWTO64 (AARCH64_R (MOVW_GOTOFF_G1), /* type */
1022 16, /* rightshift */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1024 16, /* bitsize */
1025 FALSE, /* pc_relative */
1026 0, /* bitpos */
1027 complain_overflow_unsigned, /* complain_on_overflow */
1028 bfd_elf_generic_reloc, /* special_function */
1029 AARCH64_R_STR (MOVW_GOTOFF_G1), /* name */
1030 FALSE, /* partial_inplace */
1031 0xffff, /* src_mask */
1032 0xffff, /* dst_mask */
1033 FALSE), /* pcrel_offset */
1034
87f5fbcc
RL
1035 /* LD64: GOT offset for the symbol. */
1036 HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15), /* type */
1037 3, /* rightshift */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1039 12, /* bitsize */
1040 FALSE, /* pc_relative */
1041 0, /* bitpos */
1042 complain_overflow_unsigned, /* complain_on_overflow */
1043 bfd_elf_generic_reloc, /* special_function */
1044 AARCH64_R_STR (LD64_GOTOFF_LO15), /* name */
1045 FALSE, /* partial_inplace */
1046 0x7ff8, /* src_mask */
1047 0x7ff8, /* dst_mask */
1048 FALSE), /* pcrel_offset */
1049
3d715ce4
JW
1050 /* LD32: GOT offset to the page address of GOT table.
1051 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
1052 HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14), /* type */
1053 2, /* rightshift */
1054 2, /* size (0 = byte, 1 = short, 2 = long) */
1055 12, /* bitsize */
1056 FALSE, /* pc_relative */
1057 0, /* bitpos */
1058 complain_overflow_unsigned, /* complain_on_overflow */
1059 bfd_elf_generic_reloc, /* special_function */
1060 AARCH64_R_STR (LD32_GOTPAGE_LO14), /* name */
1061 FALSE, /* partial_inplace */
1062 0x5ffc, /* src_mask */
1063 0x5ffc, /* dst_mask */
1064 FALSE), /* pcrel_offset */
1065
a921b5bd
JW
1066 /* LD64: GOT offset to the page address of GOT table.
1067 (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x7ff8. */
1068 HOWTO64 (AARCH64_R (LD64_GOTPAGE_LO15), /* type */
1069 3, /* rightshift */
1070 2, /* size (0 = byte, 1 = short, 2 = long) */
1071 12, /* bitsize */
1072 FALSE, /* pc_relative */
1073 0, /* bitpos */
1074 complain_overflow_unsigned, /* complain_on_overflow */
1075 bfd_elf_generic_reloc, /* special_function */
1076 AARCH64_R_STR (LD64_GOTPAGE_LO15), /* name */
1077 FALSE, /* partial_inplace */
1078 0x7ff8, /* src_mask */
1079 0x7ff8, /* dst_mask */
1080 FALSE), /* pcrel_offset */
1081
a06ea964
NC
1082 /* Get to the page for the GOT entry for the symbol
1083 (G(S) - P) using an ADRP instruction. */
a6bb11b2 1084 HOWTO (AARCH64_R (TLSGD_ADR_PAGE21), /* type */
a06ea964
NC
1085 12, /* rightshift */
1086 2, /* size (0 = byte, 1 = short, 2 = long) */
1087 21, /* bitsize */
1088 TRUE, /* pc_relative */
1089 0, /* bitpos */
1090 complain_overflow_dont, /* complain_on_overflow */
1091 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1092 AARCH64_R_STR (TLSGD_ADR_PAGE21), /* name */
a06ea964
NC
1093 FALSE, /* partial_inplace */
1094 0x1fffff, /* src_mask */
1095 0x1fffff, /* dst_mask */
1096 TRUE), /* pcrel_offset */
1097
3c12b054
MS
1098 HOWTO (AARCH64_R (TLSGD_ADR_PREL21), /* type */
1099 0, /* rightshift */
1100 2, /* size (0 = byte, 1 = short, 2 = long) */
1101 21, /* bitsize */
1102 TRUE, /* pc_relative */
1103 0, /* bitpos */
1104 complain_overflow_dont, /* complain_on_overflow */
1105 bfd_elf_generic_reloc, /* special_function */
1106 AARCH64_R_STR (TLSGD_ADR_PREL21), /* name */
1107 FALSE, /* partial_inplace */
1108 0x1fffff, /* src_mask */
1109 0x1fffff, /* dst_mask */
1110 TRUE), /* pcrel_offset */
1111
a06ea964 1112 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
a6bb11b2 1113 HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC), /* type */
a06ea964
NC
1114 0, /* rightshift */
1115 2, /* size (0 = byte, 1 = short, 2 = long) */
1116 12, /* bitsize */
1117 FALSE, /* pc_relative */
1118 0, /* bitpos */
1119 complain_overflow_dont, /* complain_on_overflow */
1120 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1121 AARCH64_R_STR (TLSGD_ADD_LO12_NC), /* name */
a06ea964
NC
1122 FALSE, /* partial_inplace */
1123 0xfff, /* src_mask */
1124 0xfff, /* dst_mask */
1125 FALSE), /* pcrel_offset */
1126
3e8286c0
RL
1127 /* Lower 16 bits of GOT offset to tls_index. */
1128 HOWTO64 (AARCH64_R (TLSGD_MOVW_G0_NC), /* type */
1129 0, /* rightshift */
1130 2, /* size (0 = byte, 1 = short, 2 = long) */
1131 16, /* bitsize */
1132 FALSE, /* pc_relative */
1133 0, /* bitpos */
1134 complain_overflow_dont, /* complain_on_overflow */
1135 bfd_elf_generic_reloc, /* special_function */
1136 AARCH64_R_STR (TLSGD_MOVW_G0_NC), /* name */
1137 FALSE, /* partial_inplace */
1138 0xffff, /* src_mask */
1139 0xffff, /* dst_mask */
1140 FALSE), /* pcrel_offset */
1141
1aa66fb1
RL
1142 /* Higher 16 bits of GOT offset to tls_index. */
1143 HOWTO64 (AARCH64_R (TLSGD_MOVW_G1), /* type */
1144 16, /* rightshift */
1145 2, /* size (0 = byte, 1 = short, 2 = long) */
1146 16, /* bitsize */
1147 FALSE, /* pc_relative */
1148 0, /* bitpos */
1149 complain_overflow_unsigned, /* complain_on_overflow */
1150 bfd_elf_generic_reloc, /* special_function */
1151 AARCH64_R_STR (TLSGD_MOVW_G1), /* name */
1152 FALSE, /* partial_inplace */
1153 0xffff, /* src_mask */
1154 0xffff, /* dst_mask */
1155 FALSE), /* pcrel_offset */
1156
a6bb11b2 1157 HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21), /* type */
a06ea964
NC
1158 12, /* rightshift */
1159 2, /* size (0 = byte, 1 = short, 2 = long) */
1160 21, /* bitsize */
1161 FALSE, /* pc_relative */
1162 0, /* bitpos */
1163 complain_overflow_dont, /* complain_on_overflow */
1164 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1165 AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21), /* name */
a06ea964
NC
1166 FALSE, /* partial_inplace */
1167 0x1fffff, /* src_mask */
1168 0x1fffff, /* dst_mask */
1169 FALSE), /* pcrel_offset */
1170
a6bb11b2 1171 HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC), /* type */
a06ea964
NC
1172 3, /* rightshift */
1173 2, /* size (0 = byte, 1 = short, 2 = long) */
1174 12, /* bitsize */
1175 FALSE, /* pc_relative */
1176 0, /* bitpos */
1177 complain_overflow_dont, /* complain_on_overflow */
1178 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1179 AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC), /* name */
a06ea964
NC
1180 FALSE, /* partial_inplace */
1181 0xff8, /* src_mask */
1182 0xff8, /* dst_mask */
1183 FALSE), /* pcrel_offset */
1184
a6bb11b2
YZ
1185 HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC), /* type */
1186 2, /* rightshift */
1187 2, /* size (0 = byte, 1 = short, 2 = long) */
1188 12, /* bitsize */
1189 FALSE, /* pc_relative */
1190 0, /* bitpos */
1191 complain_overflow_dont, /* complain_on_overflow */
1192 bfd_elf_generic_reloc, /* special_function */
1193 AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC), /* name */
1194 FALSE, /* partial_inplace */
1195 0xffc, /* src_mask */
1196 0xffc, /* dst_mask */
1197 FALSE), /* pcrel_offset */
1198
1199 HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19), /* type */
bb3f9ed8 1200 2, /* rightshift */
a06ea964 1201 2, /* size (0 = byte, 1 = short, 2 = long) */
043bf05a 1202 19, /* bitsize */
a06ea964
NC
1203 FALSE, /* pc_relative */
1204 0, /* bitpos */
1205 complain_overflow_dont, /* complain_on_overflow */
1206 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1207 AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19), /* name */
a06ea964
NC
1208 FALSE, /* partial_inplace */
1209 0x1ffffc, /* src_mask */
1210 0x1ffffc, /* dst_mask */
1211 FALSE), /* pcrel_offset */
1212
3b957e5b
RL
1213 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC), /* type */
1214 0, /* rightshift */
1215 2, /* size (0 = byte, 1 = short, 2 = long) */
1216 16, /* bitsize */
1217 FALSE, /* pc_relative */
1218 0, /* bitpos */
1219 complain_overflow_dont, /* complain_on_overflow */
1220 bfd_elf_generic_reloc, /* special_function */
1221 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC), /* name */
1222 FALSE, /* partial_inplace */
1223 0xffff, /* src_mask */
1224 0xffff, /* dst_mask */
1225 FALSE), /* pcrel_offset */
1226
1227 HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
1228 16, /* rightshift */
1229 2, /* size (0 = byte, 1 = short, 2 = long) */
1230 16, /* bitsize */
1231 FALSE, /* pc_relative */
1232 0, /* bitpos */
1233 complain_overflow_unsigned, /* complain_on_overflow */
1234 bfd_elf_generic_reloc, /* special_function */
1235 AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1), /* name */
1236 FALSE, /* partial_inplace */
1237 0xffff, /* src_mask */
1238 0xffff, /* dst_mask */
1239 FALSE), /* pcrel_offset */
1240
49df5539
JW
1241 /* ADD: bit[23:12] of byte offset to module TLS base address. */
1242 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12), /* type */
1243 12, /* rightshift */
1244 2, /* size (0 = byte, 1 = short, 2 = long) */
1245 12, /* bitsize */
1246 FALSE, /* pc_relative */
1247 0, /* bitpos */
1248 complain_overflow_unsigned, /* complain_on_overflow */
1249 bfd_elf_generic_reloc, /* special_function */
1250 AARCH64_R_STR (TLSLD_ADD_DTPREL_HI12), /* name */
1251 FALSE, /* partial_inplace */
1252 0xfff, /* src_mask */
1253 0xfff, /* dst_mask */
1254 FALSE), /* pcrel_offset */
1255
70151fb5
JW
1256 /* Unsigned 12 bit byte offset to module TLS base address. */
1257 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12), /* type */
1258 0, /* rightshift */
1259 2, /* size (0 = byte, 1 = short, 2 = long) */
1260 12, /* bitsize */
1261 FALSE, /* pc_relative */
1262 0, /* bitpos */
1263 complain_overflow_unsigned, /* complain_on_overflow */
1264 bfd_elf_generic_reloc, /* special_function */
1265 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12), /* name */
1266 FALSE, /* partial_inplace */
1267 0xfff, /* src_mask */
1268 0xfff, /* dst_mask */
1269 FALSE), /* pcrel_offset */
13289c10
JW
1270
1271 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12. */
1272 HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_LO12_NC), /* type */
1273 0, /* rightshift */
1274 2, /* size (0 = byte, 1 = short, 2 = long) */
1275 12, /* bitsize */
1276 FALSE, /* pc_relative */
1277 0, /* bitpos */
1278 complain_overflow_dont, /* complain_on_overflow */
1279 bfd_elf_generic_reloc, /* special_function */
1280 AARCH64_R_STR (TLSLD_ADD_DTPREL_LO12_NC), /* name */
1281 FALSE, /* partial_inplace */
1282 0xfff, /* src_mask */
1283 0xfff, /* dst_mask */
1284 FALSE), /* pcrel_offset */
70151fb5 1285
a12fad50
JW
1286 /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
1287 HOWTO (AARCH64_R (TLSLD_ADD_LO12_NC), /* type */
1288 0, /* rightshift */
1289 2, /* size (0 = byte, 1 = short, 2 = long) */
1290 12, /* bitsize */
1291 FALSE, /* pc_relative */
1292 0, /* bitpos */
1293 complain_overflow_dont, /* complain_on_overflow */
1294 bfd_elf_generic_reloc, /* special_function */
1295 AARCH64_R_STR (TLSLD_ADD_LO12_NC), /* name */
1296 FALSE, /* partial_inplace */
1297 0xfff, /* src_mask */
1298 0xfff, /* dst_mask */
1299 FALSE), /* pcrel_offset */
1300
1107e076
JW
1301 /* Get to the page for the GOT entry for the symbol
1302 (G(S) - P) using an ADRP instruction. */
1303 HOWTO (AARCH64_R (TLSLD_ADR_PAGE21), /* type */
1304 12, /* rightshift */
1305 2, /* size (0 = byte, 1 = short, 2 = long) */
1306 21, /* bitsize */
1307 TRUE, /* pc_relative */
1308 0, /* bitpos */
1309 complain_overflow_signed, /* complain_on_overflow */
1310 bfd_elf_generic_reloc, /* special_function */
1311 AARCH64_R_STR (TLSLD_ADR_PAGE21), /* name */
1312 FALSE, /* partial_inplace */
1313 0x1fffff, /* src_mask */
1314 0x1fffff, /* dst_mask */
1315 TRUE), /* pcrel_offset */
1316
6c37fedc
JW
1317 HOWTO (AARCH64_R (TLSLD_ADR_PREL21), /* type */
1318 0, /* rightshift */
1319 2, /* size (0 = byte, 1 = short, 2 = long) */
1320 21, /* bitsize */
1321 TRUE, /* pc_relative */
1322 0, /* bitpos */
1323 complain_overflow_signed, /* complain_on_overflow */
1324 bfd_elf_generic_reloc, /* special_function */
1325 AARCH64_R_STR (TLSLD_ADR_PREL21), /* name */
1326 FALSE, /* partial_inplace */
1327 0x1fffff, /* src_mask */
1328 0x1fffff, /* dst_mask */
1329 TRUE), /* pcrel_offset */
1330
4c562523
JW
1331 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1332 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12), /* type */
1333 1, /* rightshift */
1334 2, /* size (0 = byte, 1 = short, 2 = long) */
1335 11, /* bitsize */
1336 FALSE, /* pc_relative */
1337 10, /* bitpos */
1338 complain_overflow_unsigned, /* complain_on_overflow */
1339 bfd_elf_generic_reloc, /* special_function */
1340 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12), /* name */
1341 FALSE, /* partial_inplace */
1342 0x1ffc00, /* src_mask */
1343 0x1ffc00, /* dst_mask */
1344 FALSE), /* pcrel_offset */
1345
1346 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12, but no overflow check. */
1347 HOWTO64 (AARCH64_R (TLSLD_LDST16_DTPREL_LO12_NC), /* type */
1348 1, /* rightshift */
1349 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 11, /* bitsize */
1351 FALSE, /* pc_relative */
1352 10, /* bitpos */
1353 complain_overflow_dont, /* complain_on_overflow */
1354 bfd_elf_generic_reloc, /* special_function */
1355 AARCH64_R_STR (TLSLD_LDST16_DTPREL_LO12_NC), /* name */
1356 FALSE, /* partial_inplace */
1357 0x1ffc00, /* src_mask */
1358 0x1ffc00, /* dst_mask */
1359 FALSE), /* pcrel_offset */
1360
1361 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1362 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12), /* type */
1363 2, /* rightshift */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1365 10, /* bitsize */
1366 FALSE, /* pc_relative */
1367 10, /* bitpos */
1368 complain_overflow_unsigned, /* complain_on_overflow */
1369 bfd_elf_generic_reloc, /* special_function */
1370 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12), /* name */
1371 FALSE, /* partial_inplace */
1372 0x3ffc00, /* src_mask */
1373 0x3ffc00, /* dst_mask */
1374 FALSE), /* pcrel_offset */
1375
1376 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no overflow check. */
1377 HOWTO64 (AARCH64_R (TLSLD_LDST32_DTPREL_LO12_NC), /* type */
1378 2, /* rightshift */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1380 10, /* bitsize */
1381 FALSE, /* pc_relative */
1382 10, /* bitpos */
1383 complain_overflow_dont, /* complain_on_overflow */
1384 bfd_elf_generic_reloc, /* special_function */
1385 AARCH64_R_STR (TLSLD_LDST32_DTPREL_LO12_NC), /* name */
1386 FALSE, /* partial_inplace */
1387 0xffc00, /* src_mask */
1388 0xffc00, /* dst_mask */
1389 FALSE), /* pcrel_offset */
1390
1391 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1392 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12), /* type */
1393 3, /* rightshift */
1394 2, /* size (0 = byte, 1 = short, 2 = long) */
1395 9, /* bitsize */
1396 FALSE, /* pc_relative */
1397 10, /* bitpos */
1398 complain_overflow_unsigned, /* complain_on_overflow */
1399 bfd_elf_generic_reloc, /* special_function */
1400 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12), /* name */
1401 FALSE, /* partial_inplace */
1402 0x3ffc00, /* src_mask */
1403 0x3ffc00, /* dst_mask */
1404 FALSE), /* pcrel_offset */
1405
1406 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12, but no overflow check. */
1407 HOWTO64 (AARCH64_R (TLSLD_LDST64_DTPREL_LO12_NC), /* type */
1408 3, /* rightshift */
1409 2, /* size (0 = byte, 1 = short, 2 = long) */
1410 9, /* bitsize */
1411 FALSE, /* pc_relative */
1412 10, /* bitpos */
1413 complain_overflow_dont, /* complain_on_overflow */
1414 bfd_elf_generic_reloc, /* special_function */
1415 AARCH64_R_STR (TLSLD_LDST64_DTPREL_LO12_NC), /* name */
1416 FALSE, /* partial_inplace */
1417 0x7fc00, /* src_mask */
1418 0x7fc00, /* dst_mask */
1419 FALSE), /* pcrel_offset */
1420
1421 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1422 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12), /* type */
1423 0, /* rightshift */
1424 2, /* size (0 = byte, 1 = short, 2 = long) */
1425 12, /* bitsize */
1426 FALSE, /* pc_relative */
1427 10, /* bitpos */
1428 complain_overflow_unsigned, /* complain_on_overflow */
1429 bfd_elf_generic_reloc, /* special_function */
1430 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12), /* name */
1431 FALSE, /* partial_inplace */
1432 0x3ffc00, /* src_mask */
1433 0x3ffc00, /* dst_mask */
1434 FALSE), /* pcrel_offset */
1435
1436 /* Same as BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12, but no overflow check. */
1437 HOWTO64 (AARCH64_R (TLSLD_LDST8_DTPREL_LO12_NC), /* type */
1438 0, /* rightshift */
1439 2, /* size (0 = byte, 1 = short, 2 = long) */
1440 12, /* bitsize */
1441 FALSE, /* pc_relative */
1442 10, /* bitpos */
1443 complain_overflow_dont, /* complain_on_overflow */
1444 bfd_elf_generic_reloc, /* special_function */
1445 AARCH64_R_STR (TLSLD_LDST8_DTPREL_LO12_NC), /* name */
1446 FALSE, /* partial_inplace */
1447 0x3ffc00, /* src_mask */
1448 0x3ffc00, /* dst_mask */
1449 FALSE), /* pcrel_offset */
1450
49df5539
JW
1451 /* MOVZ: bit[15:0] of byte offset to module TLS base address. */
1452 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0), /* type */
1453 0, /* rightshift */
1454 2, /* size (0 = byte, 1 = short, 2 = long) */
1455 16, /* bitsize */
1456 FALSE, /* pc_relative */
1457 0, /* bitpos */
1458 complain_overflow_unsigned, /* complain_on_overflow */
1459 bfd_elf_generic_reloc, /* special_function */
1460 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0), /* name */
1461 FALSE, /* partial_inplace */
1462 0xffff, /* src_mask */
1463 0xffff, /* dst_mask */
1464 FALSE), /* pcrel_offset */
1465
1466 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0. */
1467 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G0_NC), /* type */
1468 0, /* rightshift */
1469 2, /* size (0 = byte, 1 = short, 2 = long) */
1470 16, /* bitsize */
1471 FALSE, /* pc_relative */
1472 0, /* bitpos */
1473 complain_overflow_dont, /* complain_on_overflow */
1474 bfd_elf_generic_reloc, /* special_function */
1475 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G0_NC), /* name */
1476 FALSE, /* partial_inplace */
1477 0xffff, /* src_mask */
1478 0xffff, /* dst_mask */
1479 FALSE), /* pcrel_offset */
1480
1481 /* MOVZ: bit[31:16] of byte offset to module TLS base address. */
1482 HOWTO (AARCH64_R (TLSLD_MOVW_DTPREL_G1), /* type */
1483 16, /* rightshift */
1484 2, /* size (0 = byte, 1 = short, 2 = long) */
1485 16, /* bitsize */
1486 FALSE, /* pc_relative */
1487 0, /* bitpos */
1488 complain_overflow_unsigned, /* complain_on_overflow */
1489 bfd_elf_generic_reloc, /* special_function */
1490 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1), /* name */
1491 FALSE, /* partial_inplace */
1492 0xffff, /* src_mask */
1493 0xffff, /* dst_mask */
1494 FALSE), /* pcrel_offset */
1495
1496 /* No overflow check version of BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1. */
1497 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G1_NC), /* type */
1498 16, /* rightshift */
1499 2, /* size (0 = byte, 1 = short, 2 = long) */
1500 16, /* bitsize */
1501 FALSE, /* pc_relative */
1502 0, /* bitpos */
1503 complain_overflow_dont, /* complain_on_overflow */
1504 bfd_elf_generic_reloc, /* special_function */
1505 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G1_NC), /* name */
1506 FALSE, /* partial_inplace */
1507 0xffff, /* src_mask */
1508 0xffff, /* dst_mask */
1509 FALSE), /* pcrel_offset */
1510
1511 /* MOVZ: bit[47:32] of byte offset to module TLS base address. */
1512 HOWTO64 (AARCH64_R (TLSLD_MOVW_DTPREL_G2), /* type */
1513 32, /* rightshift */
1514 2, /* size (0 = byte, 1 = short, 2 = long) */
1515 16, /* bitsize */
1516 FALSE, /* pc_relative */
1517 0, /* bitpos */
1518 complain_overflow_unsigned, /* complain_on_overflow */
1519 bfd_elf_generic_reloc, /* special_function */
1520 AARCH64_R_STR (TLSLD_MOVW_DTPREL_G2), /* name */
1521 FALSE, /* partial_inplace */
1522 0xffff, /* src_mask */
1523 0xffff, /* dst_mask */
1524 FALSE), /* pcrel_offset */
1525
a6bb11b2 1526 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
bb3f9ed8 1527 32, /* rightshift */
a06ea964 1528 2, /* size (0 = byte, 1 = short, 2 = long) */
07875fbc 1529 16, /* bitsize */
a06ea964
NC
1530 FALSE, /* pc_relative */
1531 0, /* bitpos */
0172429c 1532 complain_overflow_unsigned, /* complain_on_overflow */
a06ea964 1533 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1534 AARCH64_R_STR (TLSLE_MOVW_TPREL_G2), /* name */
a06ea964
NC
1535 FALSE, /* partial_inplace */
1536 0xffff, /* src_mask */
1537 0xffff, /* dst_mask */
1538 FALSE), /* pcrel_offset */
1539
a6bb11b2 1540 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1), /* type */
bb3f9ed8 1541 16, /* rightshift */
a06ea964 1542 2, /* size (0 = byte, 1 = short, 2 = long) */
07875fbc 1543 16, /* bitsize */
a06ea964
NC
1544 FALSE, /* pc_relative */
1545 0, /* bitpos */
1546 complain_overflow_dont, /* complain_on_overflow */
1547 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1548 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1), /* name */
a06ea964
NC
1549 FALSE, /* partial_inplace */
1550 0xffff, /* src_mask */
1551 0xffff, /* dst_mask */
1552 FALSE), /* pcrel_offset */
1553
a6bb11b2 1554 HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC), /* type */
bb3f9ed8 1555 16, /* rightshift */
a06ea964 1556 2, /* size (0 = byte, 1 = short, 2 = long) */
07875fbc 1557 16, /* bitsize */
a06ea964
NC
1558 FALSE, /* pc_relative */
1559 0, /* bitpos */
1560 complain_overflow_dont, /* complain_on_overflow */
1561 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1562 AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC), /* name */
a06ea964
NC
1563 FALSE, /* partial_inplace */
1564 0xffff, /* src_mask */
1565 0xffff, /* dst_mask */
1566 FALSE), /* pcrel_offset */
1567
a6bb11b2 1568 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0), /* type */
a06ea964
NC
1569 0, /* rightshift */
1570 2, /* size (0 = byte, 1 = short, 2 = long) */
07875fbc 1571 16, /* bitsize */
a06ea964
NC
1572 FALSE, /* pc_relative */
1573 0, /* bitpos */
1574 complain_overflow_dont, /* complain_on_overflow */
1575 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1576 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0), /* name */
a06ea964
NC
1577 FALSE, /* partial_inplace */
1578 0xffff, /* src_mask */
1579 0xffff, /* dst_mask */
1580 FALSE), /* pcrel_offset */
1581
a6bb11b2 1582 HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC), /* type */
a06ea964
NC
1583 0, /* rightshift */
1584 2, /* size (0 = byte, 1 = short, 2 = long) */
07875fbc 1585 16, /* bitsize */
a06ea964
NC
1586 FALSE, /* pc_relative */
1587 0, /* bitpos */
1588 complain_overflow_dont, /* complain_on_overflow */
1589 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1590 AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC), /* name */
a06ea964
NC
1591 FALSE, /* partial_inplace */
1592 0xffff, /* src_mask */
1593 0xffff, /* dst_mask */
1594 FALSE), /* pcrel_offset */
1595
a6bb11b2 1596 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12), /* type */
bb3f9ed8 1597 12, /* rightshift */
a06ea964
NC
1598 2, /* size (0 = byte, 1 = short, 2 = long) */
1599 12, /* bitsize */
1600 FALSE, /* pc_relative */
1601 0, /* bitpos */
bab91cce 1602 complain_overflow_unsigned, /* complain_on_overflow */
a06ea964 1603 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1604 AARCH64_R_STR (TLSLE_ADD_TPREL_HI12), /* name */
a06ea964
NC
1605 FALSE, /* partial_inplace */
1606 0xfff, /* src_mask */
1607 0xfff, /* dst_mask */
1608 FALSE), /* pcrel_offset */
1609
a6bb11b2 1610 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12), /* type */
a06ea964
NC
1611 0, /* rightshift */
1612 2, /* size (0 = byte, 1 = short, 2 = long) */
1613 12, /* bitsize */
1614 FALSE, /* pc_relative */
1615 0, /* bitpos */
36e6c140 1616 complain_overflow_unsigned, /* complain_on_overflow */
a06ea964 1617 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1618 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12), /* name */
a06ea964
NC
1619 FALSE, /* partial_inplace */
1620 0xfff, /* src_mask */
1621 0xfff, /* dst_mask */
1622 FALSE), /* pcrel_offset */
1623
a6bb11b2 1624 HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC), /* type */
a06ea964
NC
1625 0, /* rightshift */
1626 2, /* size (0 = byte, 1 = short, 2 = long) */
1627 12, /* bitsize */
1628 FALSE, /* pc_relative */
1629 0, /* bitpos */
1630 complain_overflow_dont, /* complain_on_overflow */
1631 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1632 AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC), /* name */
a06ea964
NC
1633 FALSE, /* partial_inplace */
1634 0xfff, /* src_mask */
1635 0xfff, /* dst_mask */
1636 FALSE), /* pcrel_offset */
a06ea964 1637
84f1b9fb
RL
1638 /* LD/ST16: bit[11:1] of byte offset to module TLS base address. */
1639 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12), /* type */
1640 1, /* rightshift */
1641 2, /* size (0 = byte, 1 = short, 2 = long) */
1642 11, /* bitsize */
1643 FALSE, /* pc_relative */
1644 10, /* bitpos */
1645 complain_overflow_unsigned, /* complain_on_overflow */
1646 bfd_elf_generic_reloc, /* special_function */
1647 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12), /* name */
1648 FALSE, /* partial_inplace */
1649 0x1ffc00, /* src_mask */
1650 0x1ffc00, /* dst_mask */
1651 FALSE), /* pcrel_offset */
1652
1653 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check. */
1654 HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12_NC), /* type */
1655 1, /* rightshift */
1656 2, /* size (0 = byte, 1 = short, 2 = long) */
1657 11, /* bitsize */
1658 FALSE, /* pc_relative */
1659 10, /* bitpos */
1660 complain_overflow_dont, /* complain_on_overflow */
1661 bfd_elf_generic_reloc, /* special_function */
1662 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12_NC), /* name */
1663 FALSE, /* partial_inplace */
1664 0x1ffc00, /* src_mask */
1665 0x1ffc00, /* dst_mask */
1666 FALSE), /* pcrel_offset */
1667
1668 /* LD/ST32: bit[11:2] of byte offset to module TLS base address. */
1669 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12), /* type */
1670 2, /* rightshift */
1671 2, /* size (0 = byte, 1 = short, 2 = long) */
1672 10, /* bitsize */
1673 FALSE, /* pc_relative */
1674 10, /* bitpos */
1675 complain_overflow_unsigned, /* complain_on_overflow */
1676 bfd_elf_generic_reloc, /* special_function */
1677 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12), /* name */
1678 FALSE, /* partial_inplace */
1679 0xffc00, /* src_mask */
1680 0xffc00, /* dst_mask */
1681 FALSE), /* pcrel_offset */
1682
1683 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check. */
1684 HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12_NC), /* type */
1685 2, /* rightshift */
1686 2, /* size (0 = byte, 1 = short, 2 = long) */
1687 10, /* bitsize */
1688 FALSE, /* pc_relative */
1689 10, /* bitpos */
1690 complain_overflow_dont, /* complain_on_overflow */
1691 bfd_elf_generic_reloc, /* special_function */
1692 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12_NC), /* name */
1693 FALSE, /* partial_inplace */
1694 0xffc00, /* src_mask */
1695 0xffc00, /* dst_mask */
1696 FALSE), /* pcrel_offset */
1697
1698 /* LD/ST64: bit[11:3] of byte offset to module TLS base address. */
1699 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12), /* type */
1700 3, /* rightshift */
1701 2, /* size (0 = byte, 1 = short, 2 = long) */
1702 9, /* bitsize */
1703 FALSE, /* pc_relative */
1704 10, /* bitpos */
1705 complain_overflow_unsigned, /* complain_on_overflow */
1706 bfd_elf_generic_reloc, /* special_function */
1707 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12), /* name */
1708 FALSE, /* partial_inplace */
1709 0x7fc00, /* src_mask */
1710 0x7fc00, /* dst_mask */
1711 FALSE), /* pcrel_offset */
1712
1713 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check. */
1714 HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12_NC), /* type */
1715 3, /* rightshift */
1716 2, /* size (0 = byte, 1 = short, 2 = long) */
1717 9, /* bitsize */
1718 FALSE, /* pc_relative */
1719 10, /* bitpos */
1720 complain_overflow_dont, /* complain_on_overflow */
1721 bfd_elf_generic_reloc, /* special_function */
1722 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12_NC), /* name */
1723 FALSE, /* partial_inplace */
1724 0x7fc00, /* src_mask */
1725 0x7fc00, /* dst_mask */
1726 FALSE), /* pcrel_offset */
1727
1728 /* LD/ST8: bit[11:0] of byte offset to module TLS base address. */
1729 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12), /* type */
1730 0, /* rightshift */
1731 2, /* size (0 = byte, 1 = short, 2 = long) */
1732 12, /* bitsize */
1733 FALSE, /* pc_relative */
1734 10, /* bitpos */
1735 complain_overflow_unsigned, /* complain_on_overflow */
1736 bfd_elf_generic_reloc, /* special_function */
1737 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12), /* name */
1738 FALSE, /* partial_inplace */
1739 0x3ffc00, /* src_mask */
1740 0x3ffc00, /* dst_mask */
1741 FALSE), /* pcrel_offset */
1742
1743 /* Same as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check. */
1744 HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12_NC), /* type */
1745 0, /* rightshift */
1746 2, /* size (0 = byte, 1 = short, 2 = long) */
1747 12, /* bitsize */
1748 FALSE, /* pc_relative */
1749 10, /* bitpos */
1750 complain_overflow_dont, /* complain_on_overflow */
1751 bfd_elf_generic_reloc, /* special_function */
1752 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12_NC), /* name */
1753 FALSE, /* partial_inplace */
1754 0x3ffc00, /* src_mask */
1755 0x3ffc00, /* dst_mask */
1756 FALSE), /* pcrel_offset */
1757
a6bb11b2 1758 HOWTO (AARCH64_R (TLSDESC_LD_PREL19), /* type */
bb3f9ed8 1759 2, /* rightshift */
a06ea964 1760 2, /* size (0 = byte, 1 = short, 2 = long) */
1ada945d 1761 19, /* bitsize */
a06ea964
NC
1762 TRUE, /* pc_relative */
1763 0, /* bitpos */
1764 complain_overflow_dont, /* complain_on_overflow */
1765 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1766 AARCH64_R_STR (TLSDESC_LD_PREL19), /* name */
a06ea964 1767 FALSE, /* partial_inplace */
1ada945d
MS
1768 0x0ffffe0, /* src_mask */
1769 0x0ffffe0, /* dst_mask */
a06ea964
NC
1770 TRUE), /* pcrel_offset */
1771
a6bb11b2 1772 HOWTO (AARCH64_R (TLSDESC_ADR_PREL21), /* type */
a06ea964
NC
1773 0, /* rightshift */
1774 2, /* size (0 = byte, 1 = short, 2 = long) */
1775 21, /* bitsize */
1776 TRUE, /* pc_relative */
1777 0, /* bitpos */
1778 complain_overflow_dont, /* complain_on_overflow */
1779 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1780 AARCH64_R_STR (TLSDESC_ADR_PREL21), /* name */
a06ea964
NC
1781 FALSE, /* partial_inplace */
1782 0x1fffff, /* src_mask */
1783 0x1fffff, /* dst_mask */
1784 TRUE), /* pcrel_offset */
1785
1786 /* Get to the page for the GOT entry for the symbol
1787 (G(S) - P) using an ADRP instruction. */
a6bb11b2 1788 HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21), /* type */
a06ea964
NC
1789 12, /* rightshift */
1790 2, /* size (0 = byte, 1 = short, 2 = long) */
1791 21, /* bitsize */
1792 TRUE, /* pc_relative */
1793 0, /* bitpos */
1794 complain_overflow_dont, /* complain_on_overflow */
1795 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1796 AARCH64_R_STR (TLSDESC_ADR_PAGE21), /* name */
a06ea964
NC
1797 FALSE, /* partial_inplace */
1798 0x1fffff, /* src_mask */
1799 0x1fffff, /* dst_mask */
1800 TRUE), /* pcrel_offset */
1801
a6bb11b2 1802 /* LD64: GOT offset G(S) & 0xff8. */
f955cccf 1803 HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12), /* type */
a06ea964
NC
1804 3, /* rightshift */
1805 2, /* size (0 = byte, 1 = short, 2 = long) */
1806 12, /* bitsize */
1807 FALSE, /* pc_relative */
1808 0, /* bitpos */
1809 complain_overflow_dont, /* complain_on_overflow */
1810 bfd_elf_generic_reloc, /* special_function */
f955cccf 1811 AARCH64_R_STR (TLSDESC_LD64_LO12), /* name */
a06ea964 1812 FALSE, /* partial_inplace */
a6bb11b2
YZ
1813 0xff8, /* src_mask */
1814 0xff8, /* dst_mask */
1815 FALSE), /* pcrel_offset */
1816
1817 /* LD32: GOT offset G(S) & 0xffc. */
1818 HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC), /* type */
1819 2, /* rightshift */
1820 2, /* size (0 = byte, 1 = short, 2 = long) */
1821 12, /* bitsize */
1822 FALSE, /* pc_relative */
1823 0, /* bitpos */
1824 complain_overflow_dont, /* complain_on_overflow */
1825 bfd_elf_generic_reloc, /* special_function */
1826 AARCH64_R_STR (TLSDESC_LD32_LO12_NC), /* name */
1827 FALSE, /* partial_inplace */
1828 0xffc, /* src_mask */
1829 0xffc, /* dst_mask */
a06ea964
NC
1830 FALSE), /* pcrel_offset */
1831
1832 /* ADD: GOT offset G(S) & 0xfff. */
f955cccf 1833 HOWTO (AARCH64_R (TLSDESC_ADD_LO12), /* type */
a06ea964
NC
1834 0, /* rightshift */
1835 2, /* size (0 = byte, 1 = short, 2 = long) */
1836 12, /* bitsize */
1837 FALSE, /* pc_relative */
1838 0, /* bitpos */
f955cccf 1839 complain_overflow_dont,/* complain_on_overflow */
a06ea964 1840 bfd_elf_generic_reloc, /* special_function */
f955cccf 1841 AARCH64_R_STR (TLSDESC_ADD_LO12), /* name */
a06ea964
NC
1842 FALSE, /* partial_inplace */
1843 0xfff, /* src_mask */
1844 0xfff, /* dst_mask */
1845 FALSE), /* pcrel_offset */
1846
a6bb11b2 1847 HOWTO64 (AARCH64_R (TLSDESC_OFF_G1), /* type */
bb3f9ed8 1848 16, /* rightshift */
a06ea964
NC
1849 2, /* size (0 = byte, 1 = short, 2 = long) */
1850 12, /* bitsize */
1851 FALSE, /* pc_relative */
1852 0, /* bitpos */
43a357f9 1853 complain_overflow_unsigned, /* complain_on_overflow */
a06ea964 1854 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1855 AARCH64_R_STR (TLSDESC_OFF_G1), /* name */
a06ea964
NC
1856 FALSE, /* partial_inplace */
1857 0xffff, /* src_mask */
1858 0xffff, /* dst_mask */
1859 FALSE), /* pcrel_offset */
1860
a6bb11b2 1861 HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC), /* type */
a06ea964
NC
1862 0, /* rightshift */
1863 2, /* size (0 = byte, 1 = short, 2 = long) */
1864 12, /* bitsize */
1865 FALSE, /* pc_relative */
1866 0, /* bitpos */
1867 complain_overflow_dont, /* complain_on_overflow */
1868 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1869 AARCH64_R_STR (TLSDESC_OFF_G0_NC), /* name */
a06ea964
NC
1870 FALSE, /* partial_inplace */
1871 0xffff, /* src_mask */
1872 0xffff, /* dst_mask */
1873 FALSE), /* pcrel_offset */
1874
a6bb11b2 1875 HOWTO64 (AARCH64_R (TLSDESC_LDR), /* type */
a06ea964
NC
1876 0, /* rightshift */
1877 2, /* size (0 = byte, 1 = short, 2 = long) */
1878 12, /* bitsize */
1879 FALSE, /* pc_relative */
1880 0, /* bitpos */
1881 complain_overflow_dont, /* complain_on_overflow */
1882 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1883 AARCH64_R_STR (TLSDESC_LDR), /* name */
a06ea964
NC
1884 FALSE, /* partial_inplace */
1885 0x0, /* src_mask */
1886 0x0, /* dst_mask */
1887 FALSE), /* pcrel_offset */
1888
a6bb11b2 1889 HOWTO64 (AARCH64_R (TLSDESC_ADD), /* type */
a06ea964
NC
1890 0, /* rightshift */
1891 2, /* size (0 = byte, 1 = short, 2 = long) */
1892 12, /* bitsize */
1893 FALSE, /* pc_relative */
1894 0, /* bitpos */
1895 complain_overflow_dont, /* complain_on_overflow */
1896 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1897 AARCH64_R_STR (TLSDESC_ADD), /* name */
a06ea964
NC
1898 FALSE, /* partial_inplace */
1899 0x0, /* src_mask */
1900 0x0, /* dst_mask */
1901 FALSE), /* pcrel_offset */
1902
a6bb11b2 1903 HOWTO (AARCH64_R (TLSDESC_CALL), /* type */
a06ea964
NC
1904 0, /* rightshift */
1905 2, /* size (0 = byte, 1 = short, 2 = long) */
7366006f 1906 0, /* bitsize */
a06ea964
NC
1907 FALSE, /* pc_relative */
1908 0, /* bitpos */
1909 complain_overflow_dont, /* complain_on_overflow */
1910 bfd_elf_generic_reloc, /* special_function */
a6bb11b2 1911 AARCH64_R_STR (TLSDESC_CALL), /* name */
a06ea964
NC
1912 FALSE, /* partial_inplace */
1913 0x0, /* src_mask */
1914 0x0, /* dst_mask */
1915 FALSE), /* pcrel_offset */
a6bb11b2
YZ
1916
1917 HOWTO (AARCH64_R (COPY), /* type */
1918 0, /* rightshift */
1919 2, /* size (0 = byte, 1 = short, 2 = long) */
1920 64, /* bitsize */
1921 FALSE, /* pc_relative */
1922 0, /* bitpos */
1923 complain_overflow_bitfield, /* complain_on_overflow */
1924 bfd_elf_generic_reloc, /* special_function */
1925 AARCH64_R_STR (COPY), /* name */
1926 TRUE, /* partial_inplace */
1927 0xffffffff, /* src_mask */
1928 0xffffffff, /* dst_mask */
1929 FALSE), /* pcrel_offset */
1930
1931 HOWTO (AARCH64_R (GLOB_DAT), /* type */
1932 0, /* rightshift */
1933 2, /* size (0 = byte, 1 = short, 2 = long) */
1934 64, /* bitsize */
1935 FALSE, /* pc_relative */
1936 0, /* bitpos */
1937 complain_overflow_bitfield, /* complain_on_overflow */
1938 bfd_elf_generic_reloc, /* special_function */
1939 AARCH64_R_STR (GLOB_DAT), /* name */
1940 TRUE, /* partial_inplace */
1941 0xffffffff, /* src_mask */
1942 0xffffffff, /* dst_mask */
1943 FALSE), /* pcrel_offset */
1944
1945 HOWTO (AARCH64_R (JUMP_SLOT), /* type */
1946 0, /* rightshift */
1947 2, /* size (0 = byte, 1 = short, 2 = long) */
1948 64, /* bitsize */
1949 FALSE, /* pc_relative */
1950 0, /* bitpos */
1951 complain_overflow_bitfield, /* complain_on_overflow */
1952 bfd_elf_generic_reloc, /* special_function */
1953 AARCH64_R_STR (JUMP_SLOT), /* name */
1954 TRUE, /* partial_inplace */
1955 0xffffffff, /* src_mask */
1956 0xffffffff, /* dst_mask */
1957 FALSE), /* pcrel_offset */
1958
1959 HOWTO (AARCH64_R (RELATIVE), /* type */
1960 0, /* rightshift */
1961 2, /* size (0 = byte, 1 = short, 2 = long) */
1962 64, /* bitsize */
1963 FALSE, /* pc_relative */
1964 0, /* bitpos */
1965 complain_overflow_bitfield, /* complain_on_overflow */
1966 bfd_elf_generic_reloc, /* special_function */
1967 AARCH64_R_STR (RELATIVE), /* name */
1968 TRUE, /* partial_inplace */
1969 ALL_ONES, /* src_mask */
1970 ALL_ONES, /* dst_mask */
1971 FALSE), /* pcrel_offset */
1972
1973 HOWTO (AARCH64_R (TLS_DTPMOD), /* type */
1974 0, /* rightshift */
1975 2, /* size (0 = byte, 1 = short, 2 = long) */
1976 64, /* bitsize */
1977 FALSE, /* pc_relative */
1978 0, /* bitpos */
1979 complain_overflow_dont, /* complain_on_overflow */
1980 bfd_elf_generic_reloc, /* special_function */
da0781dc
YZ
1981#if ARCH_SIZE == 64
1982 AARCH64_R_STR (TLS_DTPMOD64), /* name */
1983#else
a6bb11b2 1984 AARCH64_R_STR (TLS_DTPMOD), /* name */
da0781dc 1985#endif
a6bb11b2
YZ
1986 FALSE, /* partial_inplace */
1987 0, /* src_mask */
1988 ALL_ONES, /* dst_mask */
1989 FALSE), /* pc_reloffset */
1990
1991 HOWTO (AARCH64_R (TLS_DTPREL), /* type */
1992 0, /* rightshift */
1993 2, /* size (0 = byte, 1 = short, 2 = long) */
1994 64, /* bitsize */
1995 FALSE, /* pc_relative */
1996 0, /* bitpos */
1997 complain_overflow_dont, /* complain_on_overflow */
1998 bfd_elf_generic_reloc, /* special_function */
da0781dc
YZ
1999#if ARCH_SIZE == 64
2000 AARCH64_R_STR (TLS_DTPREL64), /* name */
2001#else
a6bb11b2 2002 AARCH64_R_STR (TLS_DTPREL), /* name */
da0781dc 2003#endif
a6bb11b2
YZ
2004 FALSE, /* partial_inplace */
2005 0, /* src_mask */
2006 ALL_ONES, /* dst_mask */
2007 FALSE), /* pcrel_offset */
2008
2009 HOWTO (AARCH64_R (TLS_TPREL), /* type */
2010 0, /* rightshift */
2011 2, /* size (0 = byte, 1 = short, 2 = long) */
2012 64, /* bitsize */
2013 FALSE, /* pc_relative */
2014 0, /* bitpos */
2015 complain_overflow_dont, /* complain_on_overflow */
2016 bfd_elf_generic_reloc, /* special_function */
da0781dc
YZ
2017#if ARCH_SIZE == 64
2018 AARCH64_R_STR (TLS_TPREL64), /* name */
2019#else
a6bb11b2 2020 AARCH64_R_STR (TLS_TPREL), /* name */
da0781dc 2021#endif
a6bb11b2
YZ
2022 FALSE, /* partial_inplace */
2023 0, /* src_mask */
2024 ALL_ONES, /* dst_mask */
2025 FALSE), /* pcrel_offset */
2026
2027 HOWTO (AARCH64_R (TLSDESC), /* type */
2028 0, /* rightshift */
2029 2, /* size (0 = byte, 1 = short, 2 = long) */
2030 64, /* bitsize */
2031 FALSE, /* pc_relative */
2032 0, /* bitpos */
2033 complain_overflow_dont, /* complain_on_overflow */
2034 bfd_elf_generic_reloc, /* special_function */
2035 AARCH64_R_STR (TLSDESC), /* name */
2036 FALSE, /* partial_inplace */
2037 0, /* src_mask */
2038 ALL_ONES, /* dst_mask */
2039 FALSE), /* pcrel_offset */
2040
2041 HOWTO (AARCH64_R (IRELATIVE), /* type */
2042 0, /* rightshift */
2043 2, /* size (0 = byte, 1 = short, 2 = long) */
2044 64, /* bitsize */
2045 FALSE, /* pc_relative */
2046 0, /* bitpos */
2047 complain_overflow_bitfield, /* complain_on_overflow */
2048 bfd_elf_generic_reloc, /* special_function */
2049 AARCH64_R_STR (IRELATIVE), /* name */
2050 FALSE, /* partial_inplace */
2051 0, /* src_mask */
2052 ALL_ONES, /* dst_mask */
2053 FALSE), /* pcrel_offset */
2054
2055 EMPTY_HOWTO (0),
a06ea964
NC
2056};
2057
a6bb11b2
YZ
2058static reloc_howto_type elfNN_aarch64_howto_none =
2059 HOWTO (R_AARCH64_NONE, /* type */
2060 0, /* rightshift */
6346d5ca 2061 3, /* size (0 = byte, 1 = short, 2 = long) */
a6bb11b2
YZ
2062 0, /* bitsize */
2063 FALSE, /* pc_relative */
2064 0, /* bitpos */
2065 complain_overflow_dont,/* complain_on_overflow */
2066 bfd_elf_generic_reloc, /* special_function */
2067 "R_AARCH64_NONE", /* name */
2068 FALSE, /* partial_inplace */
2069 0, /* src_mask */
2070 0, /* dst_mask */
2071 FALSE); /* pcrel_offset */
2072
2073/* Given HOWTO, return the bfd internal relocation enumerator. */
2074
2075static bfd_reloc_code_real_type
2076elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type *howto)
2077{
2078 const int size
2079 = (int) ARRAY_SIZE (elfNN_aarch64_howto_table);
2080 const ptrdiff_t offset
2081 = howto - elfNN_aarch64_howto_table;
2082
2083 if (offset > 0 && offset < size - 1)
2084 return BFD_RELOC_AARCH64_RELOC_START + offset;
2085
2086 if (howto == &elfNN_aarch64_howto_none)
2087 return BFD_RELOC_AARCH64_NONE;
2088
2089 return BFD_RELOC_AARCH64_RELOC_START;
2090}
2091
2092/* Given R_TYPE, return the bfd internal relocation enumerator. */
2093
2094static bfd_reloc_code_real_type
0aa13fee 2095elfNN_aarch64_bfd_reloc_from_type (bfd *abfd, unsigned int r_type)
a6bb11b2
YZ
2096{
2097 static bfd_boolean initialized_p = FALSE;
2098 /* Indexed by R_TYPE, values are offsets in the howto_table. */
2099 static unsigned int offsets[R_AARCH64_end];
2100
535b785f 2101 if (!initialized_p)
a6bb11b2
YZ
2102 {
2103 unsigned int i;
2104
2105 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
2106 if (elfNN_aarch64_howto_table[i].type != 0)
2107 offsets[elfNN_aarch64_howto_table[i].type] = i;
2108
2109 initialized_p = TRUE;
2110 }
2111
2112 if (r_type == R_AARCH64_NONE || r_type == R_AARCH64_NULL)
2113 return BFD_RELOC_AARCH64_NONE;
2114
5860e3f8
NC
2115 /* PR 17512: file: b371e70a. */
2116 if (r_type >= R_AARCH64_end)
2117 {
0aa13fee
AM
2118 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
2119 abfd, r_type);
5860e3f8
NC
2120 bfd_set_error (bfd_error_bad_value);
2121 return BFD_RELOC_AARCH64_NONE;
2122 }
2123
a6bb11b2
YZ
2124 return BFD_RELOC_AARCH64_RELOC_START + offsets[r_type];
2125}
2126
2127struct elf_aarch64_reloc_map
2128{
2129 bfd_reloc_code_real_type from;
2130 bfd_reloc_code_real_type to;
2131};
2132
2133/* Map bfd generic reloc to AArch64-specific reloc. */
2134static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map[] =
2135{
2136 {BFD_RELOC_NONE, BFD_RELOC_AARCH64_NONE},
2137
2138 /* Basic data relocations. */
2139 {BFD_RELOC_CTOR, BFD_RELOC_AARCH64_NN},
2140 {BFD_RELOC_64, BFD_RELOC_AARCH64_64},
2141 {BFD_RELOC_32, BFD_RELOC_AARCH64_32},
2142 {BFD_RELOC_16, BFD_RELOC_AARCH64_16},
2143 {BFD_RELOC_64_PCREL, BFD_RELOC_AARCH64_64_PCREL},
2144 {BFD_RELOC_32_PCREL, BFD_RELOC_AARCH64_32_PCREL},
2145 {BFD_RELOC_16_PCREL, BFD_RELOC_AARCH64_16_PCREL},
2146};
2147
2148/* Given the bfd internal relocation enumerator in CODE, return the
2149 corresponding howto entry. */
2150
2151static reloc_howto_type *
2152elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
2153{
2154 unsigned int i;
2155
2156 /* Convert bfd generic reloc to AArch64-specific reloc. */
2157 if (code < BFD_RELOC_AARCH64_RELOC_START
2158 || code > BFD_RELOC_AARCH64_RELOC_END)
2159 for (i = 0; i < ARRAY_SIZE (elf_aarch64_reloc_map); i++)
2160 if (elf_aarch64_reloc_map[i].from == code)
2161 {
2162 code = elf_aarch64_reloc_map[i].to;
2163 break;
2164 }
2165
2166 if (code > BFD_RELOC_AARCH64_RELOC_START
2167 && code < BFD_RELOC_AARCH64_RELOC_END)
2168 if (elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START].type)
2169 return &elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START];
2170
54757ed1
AP
2171 if (code == BFD_RELOC_AARCH64_NONE)
2172 return &elfNN_aarch64_howto_none;
2173
a6bb11b2
YZ
2174 return NULL;
2175}
2176
a06ea964 2177static reloc_howto_type *
0aa13fee 2178elfNN_aarch64_howto_from_type (bfd *abfd, unsigned int r_type)
a06ea964 2179{
a6bb11b2
YZ
2180 bfd_reloc_code_real_type val;
2181 reloc_howto_type *howto;
2182
cec5225b
YZ
2183#if ARCH_SIZE == 32
2184 if (r_type > 256)
2185 {
2186 bfd_set_error (bfd_error_bad_value);
2187 return NULL;
2188 }
2189#endif
2190
a6bb11b2
YZ
2191 if (r_type == R_AARCH64_NONE)
2192 return &elfNN_aarch64_howto_none;
a06ea964 2193
0aa13fee 2194 val = elfNN_aarch64_bfd_reloc_from_type (abfd, r_type);
a6bb11b2 2195 howto = elfNN_aarch64_howto_from_bfd_reloc (val);
a06ea964 2196
a6bb11b2
YZ
2197 if (howto != NULL)
2198 return howto;
a06ea964 2199
a06ea964
NC
2200 bfd_set_error (bfd_error_bad_value);
2201 return NULL;
2202}
2203
f3185997 2204static bfd_boolean
0aa13fee 2205elfNN_aarch64_info_to_howto (bfd *abfd, arelent *bfd_reloc,
a06ea964
NC
2206 Elf_Internal_Rela *elf_reloc)
2207{
2208 unsigned int r_type;
2209
cec5225b 2210 r_type = ELFNN_R_TYPE (elf_reloc->r_info);
0aa13fee 2211 bfd_reloc->howto = elfNN_aarch64_howto_from_type (abfd, r_type);
f3185997
NC
2212
2213 if (bfd_reloc->howto == NULL)
2214 {
2215 /* xgettext:c-format */
2216 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
2217 return FALSE;
2218 }
2219 return TRUE;
a06ea964
NC
2220}
2221
a06ea964 2222static reloc_howto_type *
cec5225b 2223elfNN_aarch64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
a06ea964
NC
2224 bfd_reloc_code_real_type code)
2225{
a6bb11b2 2226 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (code);
a06ea964 2227
a6bb11b2
YZ
2228 if (howto != NULL)
2229 return howto;
a06ea964
NC
2230
2231 bfd_set_error (bfd_error_bad_value);
2232 return NULL;
2233}
2234
2235static reloc_howto_type *
cec5225b 2236elfNN_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
a06ea964
NC
2237 const char *r_name)
2238{
2239 unsigned int i;
2240
a6bb11b2
YZ
2241 for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
2242 if (elfNN_aarch64_howto_table[i].name != NULL
2243 && strcasecmp (elfNN_aarch64_howto_table[i].name, r_name) == 0)
2244 return &elfNN_aarch64_howto_table[i];
a06ea964
NC
2245
2246 return NULL;
2247}
2248
07d6d2b8
AM
2249#define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
2250#define TARGET_LITTLE_NAME "elfNN-littleaarch64"
2251#define TARGET_BIG_SYM aarch64_elfNN_be_vec
2252#define TARGET_BIG_NAME "elfNN-bigaarch64"
a06ea964 2253
a06ea964
NC
2254/* The linker script knows the section names for placement.
2255 The entry_names are used to do simple name mangling on the stubs.
2256 Given a function name, and its type, the stub can be found. The
2257 name can be changed. The only requirement is the %s be present. */
2258#define STUB_ENTRY_NAME "__%s_veneer"
2259
2260/* The name of the dynamic interpreter. This is put in the .interp
2261 section. */
2262#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
2263
2264#define AARCH64_MAX_FWD_BRANCH_OFFSET \
2265 (((1 << 25) - 1) << 2)
2266#define AARCH64_MAX_BWD_BRANCH_OFFSET \
2267 (-((1 << 25) << 2))
2268
2269#define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
2270#define AARCH64_MIN_ADRP_IMM (-(1 << 20))
2271
2272static int
2273aarch64_valid_for_adrp_p (bfd_vma value, bfd_vma place)
2274{
2275 bfd_signed_vma offset = (bfd_signed_vma) (PG (value) - PG (place)) >> 12;
2276 return offset <= AARCH64_MAX_ADRP_IMM && offset >= AARCH64_MIN_ADRP_IMM;
2277}
2278
2279static int
2280aarch64_valid_branch_p (bfd_vma value, bfd_vma place)
2281{
2282 bfd_signed_vma offset = (bfd_signed_vma) (value - place);
2283 return (offset <= AARCH64_MAX_FWD_BRANCH_OFFSET
2284 && offset >= AARCH64_MAX_BWD_BRANCH_OFFSET);
2285}
2286
2287static const uint32_t aarch64_adrp_branch_stub [] =
2288{
2289 0x90000010, /* adrp ip0, X */
2290 /* R_AARCH64_ADR_HI21_PCREL(X) */
2291 0x91000210, /* add ip0, ip0, :lo12:X */
2292 /* R_AARCH64_ADD_ABS_LO12_NC(X) */
2293 0xd61f0200, /* br ip0 */
2294};
2295
2296static const uint32_t aarch64_long_branch_stub[] =
2297{
cec5225b 2298#if ARCH_SIZE == 64
a06ea964 2299 0x58000090, /* ldr ip0, 1f */
cec5225b
YZ
2300#else
2301 0x18000090, /* ldr wip0, 1f */
2302#endif
a06ea964
NC
2303 0x10000011, /* adr ip1, #0 */
2304 0x8b110210, /* add ip0, ip0, ip1 */
2305 0xd61f0200, /* br ip0 */
cec5225b
YZ
2306 0x00000000, /* 1: .xword or .word
2307 R_AARCH64_PRELNN(X) + 12
a06ea964
NC
2308 */
2309 0x00000000,
2310};
2311
68fcca92
JW
2312static const uint32_t aarch64_erratum_835769_stub[] =
2313{
2314 0x00000000, /* Placeholder for multiply accumulate. */
2315 0x14000000, /* b <label> */
2316};
2317
4106101c
MS
2318static const uint32_t aarch64_erratum_843419_stub[] =
2319{
2320 0x00000000, /* Placeholder for LDR instruction. */
2321 0x14000000, /* b <label> */
2322};
2323
a06ea964
NC
2324/* Section name for stubs is the associated section name plus this
2325 string. */
2326#define STUB_SUFFIX ".stub"
2327
cec5225b 2328enum elf_aarch64_stub_type
a06ea964
NC
2329{
2330 aarch64_stub_none,
2331 aarch64_stub_adrp_branch,
2332 aarch64_stub_long_branch,
68fcca92 2333 aarch64_stub_erratum_835769_veneer,
4106101c 2334 aarch64_stub_erratum_843419_veneer,
a06ea964
NC
2335};
2336
cec5225b 2337struct elf_aarch64_stub_hash_entry
a06ea964
NC
2338{
2339 /* Base hash table entry structure. */
2340 struct bfd_hash_entry root;
2341
2342 /* The stub section. */
2343 asection *stub_sec;
2344
2345 /* Offset within stub_sec of the beginning of this stub. */
2346 bfd_vma stub_offset;
2347
2348 /* Given the symbol's value and its section we can determine its final
2349 value when building the stubs (so the stub knows where to jump). */
2350 bfd_vma target_value;
2351 asection *target_section;
2352
cec5225b 2353 enum elf_aarch64_stub_type stub_type;
a06ea964
NC
2354
2355 /* The symbol table entry, if any, that this was derived from. */
cec5225b 2356 struct elf_aarch64_link_hash_entry *h;
a06ea964
NC
2357
2358 /* Destination symbol type */
2359 unsigned char st_type;
2360
2361 /* Where this stub is being called from, or, in the case of combined
2362 stub sections, the first input section in the group. */
2363 asection *id_sec;
2364
2365 /* The name for the local symbol at the start of this stub. The
2366 stub name in the hash table has to be unique; this does not, so
2367 it can be friendlier. */
2368 char *output_name;
68fcca92
JW
2369
2370 /* The instruction which caused this stub to be generated (only valid for
2371 erratum 835769 workaround stubs at present). */
2372 uint32_t veneered_insn;
4106101c
MS
2373
2374 /* In an erratum 843419 workaround stub, the ADRP instruction offset. */
2375 bfd_vma adrp_offset;
a06ea964
NC
2376};
2377
2378/* Used to build a map of a section. This is required for mixed-endian
2379 code/data. */
2380
cec5225b 2381typedef struct elf_elf_section_map
a06ea964
NC
2382{
2383 bfd_vma vma;
2384 char type;
2385}
cec5225b 2386elf_aarch64_section_map;
a06ea964
NC
2387
2388
2389typedef struct _aarch64_elf_section_data
2390{
2391 struct bfd_elf_section_data elf;
2392 unsigned int mapcount;
2393 unsigned int mapsize;
cec5225b 2394 elf_aarch64_section_map *map;
a06ea964
NC
2395}
2396_aarch64_elf_section_data;
2397
cec5225b 2398#define elf_aarch64_section_data(sec) \
a06ea964
NC
2399 ((_aarch64_elf_section_data *) elf_section_data (sec))
2400
4e8516b2
AP
2401/* The size of the thread control block which is defined to be two pointers. */
2402#define TCB_SIZE (ARCH_SIZE/8)*2
a06ea964
NC
2403
2404struct elf_aarch64_local_symbol
2405{
2406 unsigned int got_type;
2407 bfd_signed_vma got_refcount;
2408 bfd_vma got_offset;
2409
2410 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
2411 offset is from the end of the jump table and reserved entries
2412 within the PLTGOT.
2413
2414 The magic value (bfd_vma) -1 indicates that an offset has not be
2415 allocated. */
2416 bfd_vma tlsdesc_got_jump_table_offset;
2417};
2418
2419struct elf_aarch64_obj_tdata
2420{
2421 struct elf_obj_tdata root;
2422
2423 /* local symbol descriptors */
2424 struct elf_aarch64_local_symbol *locals;
2425
2426 /* Zero to warn when linking objects with incompatible enum sizes. */
2427 int no_enum_size_warning;
2428
2429 /* Zero to warn when linking objects with incompatible wchar_t sizes. */
2430 int no_wchar_size_warning;
2431};
2432
2433#define elf_aarch64_tdata(bfd) \
2434 ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
2435
cec5225b 2436#define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
a06ea964
NC
2437
2438#define is_aarch64_elf(bfd) \
2439 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
2440 && elf_tdata (bfd) != NULL \
2441 && elf_object_id (bfd) == AARCH64_ELF_DATA)
2442
2443static bfd_boolean
cec5225b 2444elfNN_aarch64_mkobject (bfd *abfd)
a06ea964
NC
2445{
2446 return bfd_elf_allocate_object (abfd, sizeof (struct elf_aarch64_obj_tdata),
2447 AARCH64_ELF_DATA);
2448}
2449
cec5225b
YZ
2450#define elf_aarch64_hash_entry(ent) \
2451 ((struct elf_aarch64_link_hash_entry *)(ent))
a06ea964
NC
2452
2453#define GOT_UNKNOWN 0
2454#define GOT_NORMAL 1
2455#define GOT_TLS_GD 2
2456#define GOT_TLS_IE 4
2457#define GOT_TLSDESC_GD 8
2458
2459#define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
2460
2461/* AArch64 ELF linker hash entry. */
cec5225b 2462struct elf_aarch64_link_hash_entry
a06ea964
NC
2463{
2464 struct elf_link_hash_entry root;
2465
2466 /* Track dynamic relocs copied for this symbol. */
2467 struct elf_dyn_relocs *dyn_relocs;
2468
a06ea964
NC
2469 /* Since PLT entries have variable size, we need to record the
2470 index into .got.plt instead of recomputing it from the PLT
2471 offset. */
2472 bfd_signed_vma plt_got_offset;
2473
2474 /* Bit mask representing the type of GOT entry(s) if any required by
2475 this symbol. */
2476 unsigned int got_type;
2477
2478 /* A pointer to the most recently used stub hash entry against this
2479 symbol. */
cec5225b 2480 struct elf_aarch64_stub_hash_entry *stub_cache;
a06ea964
NC
2481
2482 /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
2483 is from the end of the jump table and reserved entries within the PLTGOT.
2484
2485 The magic value (bfd_vma) -1 indicates that an offset has not
2486 be allocated. */
2487 bfd_vma tlsdesc_got_jump_table_offset;
2488};
2489
2490static unsigned int
cec5225b 2491elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry *h,
a06ea964
NC
2492 bfd *abfd,
2493 unsigned long r_symndx)
2494{
2495 if (h)
cec5225b 2496 return elf_aarch64_hash_entry (h)->got_type;
a06ea964 2497
cec5225b 2498 if (! elf_aarch64_locals (abfd))
a06ea964
NC
2499 return GOT_UNKNOWN;
2500
cec5225b 2501 return elf_aarch64_locals (abfd)[r_symndx].got_type;
a06ea964
NC
2502}
2503
a06ea964 2504/* Get the AArch64 elf linker hash table from a link_info structure. */
cec5225b
YZ
2505#define elf_aarch64_hash_table(info) \
2506 ((struct elf_aarch64_link_hash_table *) ((info)->hash))
a06ea964
NC
2507
2508#define aarch64_stub_hash_lookup(table, string, create, copy) \
cec5225b 2509 ((struct elf_aarch64_stub_hash_entry *) \
a06ea964
NC
2510 bfd_hash_lookup ((table), (string), (create), (copy)))
2511
2512/* AArch64 ELF linker hash table. */
cec5225b 2513struct elf_aarch64_link_hash_table
a06ea964
NC
2514{
2515 /* The main hash table. */
2516 struct elf_link_hash_table root;
2517
2518 /* Nonzero to force PIC branch veneers. */
2519 int pic_veneer;
2520
68fcca92
JW
2521 /* Fix erratum 835769. */
2522 int fix_erratum_835769;
2523
4106101c
MS
2524 /* Fix erratum 843419. */
2525 int fix_erratum_843419;
2526
2527 /* Enable ADRP->ADR rewrite for erratum 843419 workaround. */
2528 int fix_erratum_843419_adr;
2529
1f56df9d
JW
2530 /* Don't apply link-time values for dynamic relocations. */
2531 int no_apply_dynamic_relocs;
2532
a06ea964
NC
2533 /* The number of bytes in the initial entry in the PLT. */
2534 bfd_size_type plt_header_size;
2535
2536 /* The number of bytes in the subsequent PLT etries. */
2537 bfd_size_type plt_entry_size;
2538
a06ea964
NC
2539 /* Small local sym cache. */
2540 struct sym_cache sym_cache;
2541
2542 /* For convenience in allocate_dynrelocs. */
2543 bfd *obfd;
2544
2545 /* The amount of space used by the reserved portion of the sgotplt
2546 section, plus whatever space is used by the jump slots. */
2547 bfd_vma sgotplt_jump_table_size;
2548
2549 /* The stub hash table. */
2550 struct bfd_hash_table stub_hash_table;
2551
2552 /* Linker stub bfd. */
2553 bfd *stub_bfd;
2554
2555 /* Linker call-backs. */
2556 asection *(*add_stub_section) (const char *, asection *);
2557 void (*layout_sections_again) (void);
2558
2559 /* Array to keep track of which stub sections have been created, and
2560 information on stub grouping. */
2561 struct map_stub
2562 {
2563 /* This is the section to which stubs in the group will be
2564 attached. */
2565 asection *link_sec;
2566 /* The stub section. */
2567 asection *stub_sec;
2568 } *stub_group;
2569
cec5225b 2570 /* Assorted information used by elfNN_aarch64_size_stubs. */
a06ea964 2571 unsigned int bfd_count;
7292b3ac 2572 unsigned int top_index;
a06ea964
NC
2573 asection **input_list;
2574
2575 /* The offset into splt of the PLT entry for the TLS descriptor
2576 resolver. Special values are 0, if not necessary (or not found
2577 to be necessary yet), and -1 if needed but not determined
2578 yet. */
2579 bfd_vma tlsdesc_plt;
2580
2581 /* The GOT offset for the lazy trampoline. Communicated to the
2582 loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
2583 indicates an offset is not allocated. */
2584 bfd_vma dt_tlsdesc_got;
1419bbe5
WN
2585
2586 /* Used by local STT_GNU_IFUNC symbols. */
2587 htab_t loc_hash_table;
2588 void * loc_hash_memory;
a06ea964
NC
2589};
2590
a06ea964
NC
2591/* Create an entry in an AArch64 ELF linker hash table. */
2592
2593static struct bfd_hash_entry *
cec5225b 2594elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
a06ea964
NC
2595 struct bfd_hash_table *table,
2596 const char *string)
2597{
cec5225b
YZ
2598 struct elf_aarch64_link_hash_entry *ret =
2599 (struct elf_aarch64_link_hash_entry *) entry;
a06ea964
NC
2600
2601 /* Allocate the structure if it has not already been allocated by a
2602 subclass. */
2603 if (ret == NULL)
2604 ret = bfd_hash_allocate (table,
cec5225b 2605 sizeof (struct elf_aarch64_link_hash_entry));
a06ea964
NC
2606 if (ret == NULL)
2607 return (struct bfd_hash_entry *) ret;
2608
2609 /* Call the allocation method of the superclass. */
cec5225b 2610 ret = ((struct elf_aarch64_link_hash_entry *)
a06ea964
NC
2611 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2612 table, string));
2613 if (ret != NULL)
2614 {
2615 ret->dyn_relocs = NULL;
a06ea964
NC
2616 ret->got_type = GOT_UNKNOWN;
2617 ret->plt_got_offset = (bfd_vma) - 1;
2618 ret->stub_cache = NULL;
2619 ret->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
2620 }
2621
2622 return (struct bfd_hash_entry *) ret;
2623}
2624
2625/* Initialize an entry in the stub hash table. */
2626
2627static struct bfd_hash_entry *
2628stub_hash_newfunc (struct bfd_hash_entry *entry,
2629 struct bfd_hash_table *table, const char *string)
2630{
2631 /* Allocate the structure if it has not already been allocated by a
2632 subclass. */
2633 if (entry == NULL)
2634 {
2635 entry = bfd_hash_allocate (table,
2636 sizeof (struct
cec5225b 2637 elf_aarch64_stub_hash_entry));
a06ea964
NC
2638 if (entry == NULL)
2639 return entry;
2640 }
2641
2642 /* Call the allocation method of the superclass. */
2643 entry = bfd_hash_newfunc (entry, table, string);
2644 if (entry != NULL)
2645 {
cec5225b 2646 struct elf_aarch64_stub_hash_entry *eh;
a06ea964
NC
2647
2648 /* Initialize the local fields. */
cec5225b 2649 eh = (struct elf_aarch64_stub_hash_entry *) entry;
4106101c 2650 eh->adrp_offset = 0;
a06ea964
NC
2651 eh->stub_sec = NULL;
2652 eh->stub_offset = 0;
2653 eh->target_value = 0;
2654 eh->target_section = NULL;
2655 eh->stub_type = aarch64_stub_none;
2656 eh->h = NULL;
2657 eh->id_sec = NULL;
2658 }
2659
2660 return entry;
2661}
2662
1419bbe5
WN
2663/* Compute a hash of a local hash entry. We use elf_link_hash_entry
2664 for local symbol so that we can handle local STT_GNU_IFUNC symbols
2665 as global symbol. We reuse indx and dynstr_index for local symbol
2666 hash since they aren't used by global symbols in this backend. */
2667
2668static hashval_t
2669elfNN_aarch64_local_htab_hash (const void *ptr)
2670{
2671 struct elf_link_hash_entry *h
2672 = (struct elf_link_hash_entry *) ptr;
2673 return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
2674}
2675
2676/* Compare local hash entries. */
2677
2678static int
2679elfNN_aarch64_local_htab_eq (const void *ptr1, const void *ptr2)
2680{
2681 struct elf_link_hash_entry *h1
2682 = (struct elf_link_hash_entry *) ptr1;
2683 struct elf_link_hash_entry *h2
2684 = (struct elf_link_hash_entry *) ptr2;
2685
2686 return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
2687}
2688
2689/* Find and/or create a hash entry for local symbol. */
2690
2691static struct elf_link_hash_entry *
2692elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table *htab,
2693 bfd *abfd, const Elf_Internal_Rela *rel,
2694 bfd_boolean create)
2695{
2696 struct elf_aarch64_link_hash_entry e, *ret;
2697 asection *sec = abfd->sections;
2698 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
2699 ELFNN_R_SYM (rel->r_info));
2700 void **slot;
2701
2702 e.root.indx = sec->id;
2703 e.root.dynstr_index = ELFNN_R_SYM (rel->r_info);
2704 slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
2705 create ? INSERT : NO_INSERT);
2706
2707 if (!slot)
2708 return NULL;
2709
2710 if (*slot)
2711 {
2712 ret = (struct elf_aarch64_link_hash_entry *) *slot;
2713 return &ret->root;
2714 }
2715
2716 ret = (struct elf_aarch64_link_hash_entry *)
2717 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
2718 sizeof (struct elf_aarch64_link_hash_entry));
2719 if (ret)
2720 {
2721 memset (ret, 0, sizeof (*ret));
2722 ret->root.indx = sec->id;
2723 ret->root.dynstr_index = ELFNN_R_SYM (rel->r_info);
2724 ret->root.dynindx = -1;
2725 *slot = ret;
2726 }
2727 return &ret->root;
2728}
a06ea964
NC
2729
2730/* Copy the extra info we tack onto an elf_link_hash_entry. */
2731
2732static void
cec5225b 2733elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
a06ea964
NC
2734 struct elf_link_hash_entry *dir,
2735 struct elf_link_hash_entry *ind)
2736{
cec5225b 2737 struct elf_aarch64_link_hash_entry *edir, *eind;
a06ea964 2738
cec5225b
YZ
2739 edir = (struct elf_aarch64_link_hash_entry *) dir;
2740 eind = (struct elf_aarch64_link_hash_entry *) ind;
a06ea964
NC
2741
2742 if (eind->dyn_relocs != NULL)
2743 {
2744 if (edir->dyn_relocs != NULL)
2745 {
2746 struct elf_dyn_relocs **pp;
2747 struct elf_dyn_relocs *p;
2748
2749 /* Add reloc counts against the indirect sym to the direct sym
2750 list. Merge any entries against the same section. */
2751 for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
2752 {
2753 struct elf_dyn_relocs *q;
2754
2755 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2756 if (q->sec == p->sec)
2757 {
2758 q->pc_count += p->pc_count;
2759 q->count += p->count;
2760 *pp = p->next;
2761 break;
2762 }
2763 if (q == NULL)
2764 pp = &p->next;
2765 }
2766 *pp = edir->dyn_relocs;
2767 }
2768
2769 edir->dyn_relocs = eind->dyn_relocs;
2770 eind->dyn_relocs = NULL;
2771 }
2772
a06ea964
NC
2773 if (ind->root.type == bfd_link_hash_indirect)
2774 {
2775 /* Copy over PLT info. */
2776 if (dir->got.refcount <= 0)
2777 {
2778 edir->got_type = eind->got_type;
2779 eind->got_type = GOT_UNKNOWN;
2780 }
2781 }
2782
2783 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2784}
2785
68faa637
AM
2786/* Destroy an AArch64 elf linker hash table. */
2787
2788static void
d495ab0d 2789elfNN_aarch64_link_hash_table_free (bfd *obfd)
68faa637
AM
2790{
2791 struct elf_aarch64_link_hash_table *ret
d495ab0d 2792 = (struct elf_aarch64_link_hash_table *) obfd->link.hash;
68faa637
AM
2793
2794 if (ret->loc_hash_table)
2795 htab_delete (ret->loc_hash_table);
2796 if (ret->loc_hash_memory)
2797 objalloc_free ((struct objalloc *) ret->loc_hash_memory);
2798
2799 bfd_hash_table_free (&ret->stub_hash_table);
d495ab0d 2800 _bfd_elf_link_hash_table_free (obfd);
68faa637
AM
2801}
2802
a06ea964
NC
2803/* Create an AArch64 elf linker hash table. */
2804
2805static struct bfd_link_hash_table *
cec5225b 2806elfNN_aarch64_link_hash_table_create (bfd *abfd)
a06ea964 2807{
cec5225b
YZ
2808 struct elf_aarch64_link_hash_table *ret;
2809 bfd_size_type amt = sizeof (struct elf_aarch64_link_hash_table);
a06ea964 2810
7bf52ea2 2811 ret = bfd_zmalloc (amt);
a06ea964
NC
2812 if (ret == NULL)
2813 return NULL;
2814
2815 if (!_bfd_elf_link_hash_table_init
cec5225b
YZ
2816 (&ret->root, abfd, elfNN_aarch64_link_hash_newfunc,
2817 sizeof (struct elf_aarch64_link_hash_entry), AARCH64_ELF_DATA))
a06ea964
NC
2818 {
2819 free (ret);
2820 return NULL;
2821 }
2822
a06ea964
NC
2823 ret->plt_header_size = PLT_ENTRY_SIZE;
2824 ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
a06ea964 2825 ret->obfd = abfd;
a06ea964
NC
2826 ret->dt_tlsdesc_got = (bfd_vma) - 1;
2827
2828 if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
cec5225b 2829 sizeof (struct elf_aarch64_stub_hash_entry)))
a06ea964 2830 {
d495ab0d 2831 _bfd_elf_link_hash_table_free (abfd);
a06ea964
NC
2832 return NULL;
2833 }
2834
1419bbe5
WN
2835 ret->loc_hash_table = htab_try_create (1024,
2836 elfNN_aarch64_local_htab_hash,
2837 elfNN_aarch64_local_htab_eq,
2838 NULL);
2839 ret->loc_hash_memory = objalloc_create ();
2840 if (!ret->loc_hash_table || !ret->loc_hash_memory)
2841 {
d495ab0d 2842 elfNN_aarch64_link_hash_table_free (abfd);
1419bbe5
WN
2843 return NULL;
2844 }
d495ab0d 2845 ret->root.root.hash_table_free = elfNN_aarch64_link_hash_table_free;
1419bbe5 2846
a06ea964
NC
2847 return &ret->root.root;
2848}
2849
1d75a8e2
NC
2850/* Perform relocation R_TYPE. Returns TRUE upon success, FALSE otherwise. */
2851
a06ea964
NC
2852static bfd_boolean
2853aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
2854 bfd_vma offset, bfd_vma value)
2855{
2856 reloc_howto_type *howto;
2857 bfd_vma place;
2858
0aa13fee 2859 howto = elfNN_aarch64_howto_from_type (input_bfd, r_type);
a06ea964
NC
2860 place = (input_section->output_section->vma + input_section->output_offset
2861 + offset);
caed7120 2862
0aa13fee 2863 r_type = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
caed7120
YZ
2864 value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE);
2865 return _bfd_aarch64_elf_put_addend (input_bfd,
2866 input_section->contents + offset, r_type,
1d75a8e2 2867 howto, value) == bfd_reloc_ok;
a06ea964
NC
2868}
2869
cec5225b 2870static enum elf_aarch64_stub_type
a06ea964
NC
2871aarch64_select_branch_stub (bfd_vma value, bfd_vma place)
2872{
2873 if (aarch64_valid_for_adrp_p (value, place))
2874 return aarch64_stub_adrp_branch;
2875 return aarch64_stub_long_branch;
2876}
2877
2878/* Determine the type of stub needed, if any, for a call. */
2879
cec5225b 2880static enum elf_aarch64_stub_type
9a228467 2881aarch64_type_of_stub (asection *input_sec,
a06ea964 2882 const Elf_Internal_Rela *rel,
f678ded7 2883 asection *sym_sec,
a06ea964 2884 unsigned char st_type,
a06ea964
NC
2885 bfd_vma destination)
2886{
2887 bfd_vma location;
2888 bfd_signed_vma branch_offset;
2889 unsigned int r_type;
cec5225b 2890 enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
a06ea964 2891
f678ded7 2892 if (st_type != STT_FUNC
2f340668 2893 && (sym_sec == input_sec))
a06ea964
NC
2894 return stub_type;
2895
a06ea964
NC
2896 /* Determine where the call point is. */
2897 location = (input_sec->output_offset
2898 + input_sec->output_section->vma + rel->r_offset);
2899
2900 branch_offset = (bfd_signed_vma) (destination - location);
2901
cec5225b 2902 r_type = ELFNN_R_TYPE (rel->r_info);
a06ea964
NC
2903
2904 /* We don't want to redirect any old unconditional jump in this way,
2905 only one which is being used for a sibcall, where it is
2906 acceptable for the IP0 and IP1 registers to be clobbered. */
a6bb11b2 2907 if ((r_type == AARCH64_R (CALL26) || r_type == AARCH64_R (JUMP26))
a06ea964
NC
2908 && (branch_offset > AARCH64_MAX_FWD_BRANCH_OFFSET
2909 || branch_offset < AARCH64_MAX_BWD_BRANCH_OFFSET))
2910 {
2911 stub_type = aarch64_stub_long_branch;
2912 }
2913
2914 return stub_type;
2915}
2916
2917/* Build a name for an entry in the stub hash table. */
2918
2919static char *
cec5225b 2920elfNN_aarch64_stub_name (const asection *input_section,
a06ea964 2921 const asection *sym_sec,
cec5225b 2922 const struct elf_aarch64_link_hash_entry *hash,
a06ea964
NC
2923 const Elf_Internal_Rela *rel)
2924{
2925 char *stub_name;
2926 bfd_size_type len;
2927
2928 if (hash)
2929 {
2930 len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
2931 stub_name = bfd_malloc (len);
2932 if (stub_name != NULL)
2933 snprintf (stub_name, len, "%08x_%s+%" BFD_VMA_FMT "x",
2934 (unsigned int) input_section->id,
2935 hash->root.root.root.string,
2936 rel->r_addend);
2937 }
2938 else
2939 {
2940 len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
2941 stub_name = bfd_malloc (len);
2942 if (stub_name != NULL)
2943 snprintf (stub_name, len, "%08x_%x:%x+%" BFD_VMA_FMT "x",
2944 (unsigned int) input_section->id,
2945 (unsigned int) sym_sec->id,
cec5225b 2946 (unsigned int) ELFNN_R_SYM (rel->r_info),
a06ea964
NC
2947 rel->r_addend);
2948 }
2949
2950 return stub_name;
2951}
2952
7f784814
JW
2953/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For
2954 executable PLT slots where the executable never takes the address of those
2955 functions, the function symbols are not added to the hash table. */
2956
2957static bfd_boolean
2958elf_aarch64_hash_symbol (struct elf_link_hash_entry *h)
2959{
2960 if (h->plt.offset != (bfd_vma) -1
2961 && !h->def_regular
2962 && !h->pointer_equality_needed)
2963 return FALSE;
2964
2965 return _bfd_elf_hash_symbol (h);
2966}
2967
2968
a06ea964
NC
2969/* Look up an entry in the stub hash. Stub entries are cached because
2970 creating the stub name takes a bit of time. */
2971
cec5225b
YZ
2972static struct elf_aarch64_stub_hash_entry *
2973elfNN_aarch64_get_stub_entry (const asection *input_section,
a06ea964
NC
2974 const asection *sym_sec,
2975 struct elf_link_hash_entry *hash,
2976 const Elf_Internal_Rela *rel,
cec5225b 2977 struct elf_aarch64_link_hash_table *htab)
a06ea964 2978{
cec5225b
YZ
2979 struct elf_aarch64_stub_hash_entry *stub_entry;
2980 struct elf_aarch64_link_hash_entry *h =
2981 (struct elf_aarch64_link_hash_entry *) hash;
a06ea964
NC
2982 const asection *id_sec;
2983
2984 if ((input_section->flags & SEC_CODE) == 0)
2985 return NULL;
2986
2987 /* If this input section is part of a group of sections sharing one
2988 stub section, then use the id of the first section in the group.
2989 Stub names need to include a section id, as there may well be
2990 more than one stub used to reach say, printf, and we need to
2991 distinguish between them. */
2992 id_sec = htab->stub_group[input_section->id].link_sec;
2993
2994 if (h != NULL && h->stub_cache != NULL
2995 && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
2996 {
2997 stub_entry = h->stub_cache;
2998 }
2999 else
3000 {
3001 char *stub_name;
3002
cec5225b 3003 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, h, rel);
a06ea964
NC
3004 if (stub_name == NULL)
3005 return NULL;
3006
3007 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
3008 stub_name, FALSE, FALSE);
3009 if (h != NULL)
3010 h->stub_cache = stub_entry;
3011
3012 free (stub_name);
3013 }
3014
3015 return stub_entry;
3016}
3017
a06ea964 3018
66585675
MS
3019/* Create a stub section. */
3020
3021static asection *
3022_bfd_aarch64_create_stub_section (asection *section,
3023 struct elf_aarch64_link_hash_table *htab)
3024{
3025 size_t namelen;
3026 bfd_size_type len;
3027 char *s_name;
3028
3029 namelen = strlen (section->name);
3030 len = namelen + sizeof (STUB_SUFFIX);
3031 s_name = bfd_alloc (htab->stub_bfd, len);
3032 if (s_name == NULL)
3033 return NULL;
3034
3035 memcpy (s_name, section->name, namelen);
3036 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
3037 return (*htab->add_stub_section) (s_name, section);
3038}
3039
3040
fc6d53be
MS
3041/* Find or create a stub section for a link section.
3042
3043 Fix or create the stub section used to collect stubs attached to
3044 the specified link section. */
3045
3046static asection *
3047_bfd_aarch64_get_stub_for_link_section (asection *link_section,
3048 struct elf_aarch64_link_hash_table *htab)
3049{
3050 if (htab->stub_group[link_section->id].stub_sec == NULL)
3051 htab->stub_group[link_section->id].stub_sec
3052 = _bfd_aarch64_create_stub_section (link_section, htab);
3053 return htab->stub_group[link_section->id].stub_sec;
3054}
3055
3056
ef857521
MS
3057/* Find or create a stub section in the stub group for an input
3058 section. */
3059
3060static asection *
3061_bfd_aarch64_create_or_find_stub_sec (asection *section,
3062 struct elf_aarch64_link_hash_table *htab)
a06ea964 3063{
fc6d53be
MS
3064 asection *link_sec = htab->stub_group[section->id].link_sec;
3065 return _bfd_aarch64_get_stub_for_link_section (link_sec, htab);
ef857521
MS
3066}
3067
3068
3069/* Add a new stub entry in the stub group associated with an input
3070 section to the stub hash. Not all fields of the new stub entry are
3071 initialised. */
3072
3073static struct elf_aarch64_stub_hash_entry *
3074_bfd_aarch64_add_stub_entry_in_group (const char *stub_name,
3075 asection *section,
3076 struct elf_aarch64_link_hash_table *htab)
3077{
3078 asection *link_sec;
3079 asection *stub_sec;
3080 struct elf_aarch64_stub_hash_entry *stub_entry;
3081
3082 link_sec = htab->stub_group[section->id].link_sec;
3083 stub_sec = _bfd_aarch64_create_or_find_stub_sec (section, htab);
3084
a06ea964
NC
3085 /* Enter this entry into the linker stub hash table. */
3086 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3087 TRUE, FALSE);
3088 if (stub_entry == NULL)
3089 {
695344c0 3090 /* xgettext:c-format */
871b3ab2 3091 _bfd_error_handler (_("%pB: cannot create stub entry %s"),
4eca0228 3092 section->owner, stub_name);
a06ea964
NC
3093 return NULL;
3094 }
3095
3096 stub_entry->stub_sec = stub_sec;
3097 stub_entry->stub_offset = 0;
3098 stub_entry->id_sec = link_sec;
3099
3100 return stub_entry;
3101}
3102
4106101c
MS
3103/* Add a new stub entry in the final stub section to the stub hash.
3104 Not all fields of the new stub entry are initialised. */
3105
3106static struct elf_aarch64_stub_hash_entry *
3107_bfd_aarch64_add_stub_entry_after (const char *stub_name,
3108 asection *link_section,
3109 struct elf_aarch64_link_hash_table *htab)
3110{
3111 asection *stub_sec;
3112 struct elf_aarch64_stub_hash_entry *stub_entry;
3113
3114 stub_sec = _bfd_aarch64_get_stub_for_link_section (link_section, htab);
3115 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3116 TRUE, FALSE);
3117 if (stub_entry == NULL)
3118 {
4eca0228 3119 _bfd_error_handler (_("cannot create stub entry %s"), stub_name);
4106101c
MS
3120 return NULL;
3121 }
3122
3123 stub_entry->stub_sec = stub_sec;
3124 stub_entry->stub_offset = 0;
3125 stub_entry->id_sec = link_section;
3126
3127 return stub_entry;
3128}
3129
3130
a06ea964
NC
3131static bfd_boolean
3132aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
3133 void *in_arg ATTRIBUTE_UNUSED)
3134{
cec5225b 3135 struct elf_aarch64_stub_hash_entry *stub_entry;
a06ea964
NC
3136 asection *stub_sec;
3137 bfd *stub_bfd;
3138 bfd_byte *loc;
3139 bfd_vma sym_value;
68fcca92
JW
3140 bfd_vma veneered_insn_loc;
3141 bfd_vma veneer_entry_loc;
3142 bfd_signed_vma branch_offset = 0;
a06ea964
NC
3143 unsigned int template_size;
3144 const uint32_t *template;
3145 unsigned int i;
3146
3147 /* Massage our args to the form they really have. */
cec5225b 3148 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
a06ea964
NC
3149
3150 stub_sec = stub_entry->stub_sec;
3151
3152 /* Make a note of the offset within the stubs for this entry. */
3153 stub_entry->stub_offset = stub_sec->size;
3154 loc = stub_sec->contents + stub_entry->stub_offset;
3155
3156 stub_bfd = stub_sec->owner;
3157
3158 /* This is the address of the stub destination. */
3159 sym_value = (stub_entry->target_value
3160 + stub_entry->target_section->output_offset
3161 + stub_entry->target_section->output_section->vma);
3162
3163 if (stub_entry->stub_type == aarch64_stub_long_branch)
3164 {
3165 bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
3166 + stub_sec->output_offset);
3167
3168 /* See if we can relax the stub. */
3169 if (aarch64_valid_for_adrp_p (sym_value, place))
3170 stub_entry->stub_type = aarch64_select_branch_stub (sym_value, place);
3171 }
3172
3173 switch (stub_entry->stub_type)
3174 {
3175 case aarch64_stub_adrp_branch:
3176 template = aarch64_adrp_branch_stub;
3177 template_size = sizeof (aarch64_adrp_branch_stub);
3178 break;
3179 case aarch64_stub_long_branch:
3180 template = aarch64_long_branch_stub;
3181 template_size = sizeof (aarch64_long_branch_stub);
3182 break;
68fcca92
JW
3183 case aarch64_stub_erratum_835769_veneer:
3184 template = aarch64_erratum_835769_stub;
3185 template_size = sizeof (aarch64_erratum_835769_stub);
3186 break;
4106101c
MS
3187 case aarch64_stub_erratum_843419_veneer:
3188 template = aarch64_erratum_843419_stub;
3189 template_size = sizeof (aarch64_erratum_843419_stub);
3190 break;
a06ea964 3191 default:
8e2fe09f 3192 abort ();
a06ea964
NC
3193 }
3194
3195 for (i = 0; i < (template_size / sizeof template[0]); i++)
3196 {
3197 bfd_putl32 (template[i], loc);
3198 loc += 4;
3199 }
3200
3201 template_size = (template_size + 7) & ~7;
3202 stub_sec->size += template_size;
3203
3204 switch (stub_entry->stub_type)
3205 {
3206 case aarch64_stub_adrp_branch:
1d75a8e2
NC
3207 if (!aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
3208 stub_entry->stub_offset, sym_value))
a06ea964
NC
3209 /* The stub would not have been relaxed if the offset was out
3210 of range. */
3211 BFD_FAIL ();
3212
1d75a8e2
NC
3213 if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC), stub_bfd, stub_sec,
3214 stub_entry->stub_offset + 4, sym_value))
93ca8569 3215 BFD_FAIL ();
a06ea964
NC
3216 break;
3217
3218 case aarch64_stub_long_branch:
3219 /* We want the value relative to the address 12 bytes back from the
07d6d2b8 3220 value itself. */
1d75a8e2
NC
3221 if (!aarch64_relocate (AARCH64_R (PRELNN), stub_bfd, stub_sec,
3222 stub_entry->stub_offset + 16, sym_value + 12))
93ca8569 3223 BFD_FAIL ();
a06ea964 3224 break;
68fcca92
JW
3225
3226 case aarch64_stub_erratum_835769_veneer:
3227 veneered_insn_loc = stub_entry->target_section->output_section->vma
3228 + stub_entry->target_section->output_offset
3229 + stub_entry->target_value;
3230 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
3231 + stub_entry->stub_sec->output_offset
3232 + stub_entry->stub_offset;
3233 branch_offset = veneered_insn_loc - veneer_entry_loc;
3234 branch_offset >>= 2;
3235 branch_offset &= 0x3ffffff;
3236 bfd_putl32 (stub_entry->veneered_insn,
3237 stub_sec->contents + stub_entry->stub_offset);
3238 bfd_putl32 (template[1] | branch_offset,
3239 stub_sec->contents + stub_entry->stub_offset + 4);
3240 break;
3241
4106101c 3242 case aarch64_stub_erratum_843419_veneer:
1d75a8e2
NC
3243 if (!aarch64_relocate (AARCH64_R (JUMP26), stub_bfd, stub_sec,
3244 stub_entry->stub_offset + 4, sym_value + 4))
4106101c
MS
3245 BFD_FAIL ();
3246 break;
3247
a06ea964 3248 default:
8e2fe09f 3249 abort ();
a06ea964
NC
3250 }
3251
3252 return TRUE;
3253}
3254
3255/* As above, but don't actually build the stub. Just bump offset so
3256 we know stub section sizes. */
3257
3258static bfd_boolean
3259aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
3260 void *in_arg ATTRIBUTE_UNUSED)
3261{
cec5225b 3262 struct elf_aarch64_stub_hash_entry *stub_entry;
a06ea964
NC
3263 int size;
3264
3265 /* Massage our args to the form they really have. */
cec5225b 3266 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
a06ea964
NC
3267
3268 switch (stub_entry->stub_type)
3269 {
3270 case aarch64_stub_adrp_branch:
3271 size = sizeof (aarch64_adrp_branch_stub);
3272 break;
3273 case aarch64_stub_long_branch:
3274 size = sizeof (aarch64_long_branch_stub);
3275 break;
68fcca92
JW
3276 case aarch64_stub_erratum_835769_veneer:
3277 size = sizeof (aarch64_erratum_835769_stub);
3278 break;
4106101c
MS
3279 case aarch64_stub_erratum_843419_veneer:
3280 size = sizeof (aarch64_erratum_843419_stub);
3281 break;
a06ea964 3282 default:
8e2fe09f 3283 abort ();
a06ea964
NC
3284 }
3285
3286 size = (size + 7) & ~7;
3287 stub_entry->stub_sec->size += size;
3288 return TRUE;
3289}
3290
3291/* External entry points for sizing and building linker stubs. */
3292
3293/* Set up various things so that we can make a list of input sections
3294 for each output section included in the link. Returns -1 on error,
3295 0 when no stubs will be needed, and 1 on success. */
3296
3297int
cec5225b 3298elfNN_aarch64_setup_section_lists (bfd *output_bfd,
a06ea964
NC
3299 struct bfd_link_info *info)
3300{
3301 bfd *input_bfd;
3302 unsigned int bfd_count;
7292b3ac 3303 unsigned int top_id, top_index;
a06ea964
NC
3304 asection *section;
3305 asection **input_list, **list;
3306 bfd_size_type amt;
cec5225b
YZ
3307 struct elf_aarch64_link_hash_table *htab =
3308 elf_aarch64_hash_table (info);
a06ea964
NC
3309
3310 if (!is_elf_hash_table (htab))
3311 return 0;
3312
3313 /* Count the number of input BFDs and find the top input section id. */
3314 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
c72f2fb2 3315 input_bfd != NULL; input_bfd = input_bfd->link.next)
a06ea964
NC
3316 {
3317 bfd_count += 1;
3318 for (section = input_bfd->sections;
3319 section != NULL; section = section->next)
3320 {
3321 if (top_id < section->id)
3322 top_id = section->id;
3323 }
3324 }
3325 htab->bfd_count = bfd_count;
3326
3327 amt = sizeof (struct map_stub) * (top_id + 1);
3328 htab->stub_group = bfd_zmalloc (amt);
3329 if (htab->stub_group == NULL)
3330 return -1;
3331
3332 /* We can't use output_bfd->section_count here to find the top output
3333 section index as some sections may have been removed, and
3334 _bfd_strip_section_from_output doesn't renumber the indices. */
3335 for (section = output_bfd->sections, top_index = 0;
3336 section != NULL; section = section->next)
3337 {
3338 if (top_index < section->index)
3339 top_index = section->index;
3340 }
3341
3342 htab->top_index = top_index;
3343 amt = sizeof (asection *) * (top_index + 1);
3344 input_list = bfd_malloc (amt);
3345 htab->input_list = input_list;
3346 if (input_list == NULL)
3347 return -1;
3348
3349 /* For sections we aren't interested in, mark their entries with a
3350 value we can check later. */
3351 list = input_list + top_index;
3352 do
3353 *list = bfd_abs_section_ptr;
3354 while (list-- != input_list);
3355
3356 for (section = output_bfd->sections;
3357 section != NULL; section = section->next)
3358 {
3359 if ((section->flags & SEC_CODE) != 0)
3360 input_list[section->index] = NULL;
3361 }
3362
3363 return 1;
3364}
3365
cec5225b 3366/* Used by elfNN_aarch64_next_input_section and group_sections. */
a06ea964
NC
3367#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
3368
3369/* The linker repeatedly calls this function for each input section,
3370 in the order that input sections are linked into output sections.
3371 Build lists of input sections to determine groupings between which
3372 we may insert linker stubs. */
3373
3374void
cec5225b 3375elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec)
a06ea964 3376{
cec5225b
YZ
3377 struct elf_aarch64_link_hash_table *htab =
3378 elf_aarch64_hash_table (info);
a06ea964
NC
3379
3380 if (isec->output_section->index <= htab->top_index)
3381 {
3382 asection **list = htab->input_list + isec->output_section->index;
3383
3384 if (*list != bfd_abs_section_ptr)
3385 {
3386 /* Steal the link_sec pointer for our list. */
3387 /* This happens to make the list in reverse order,
3388 which is what we want. */
3389 PREV_SEC (isec) = *list;
3390 *list = isec;
3391 }
3392 }
3393}
3394
3395/* See whether we can group stub sections together. Grouping stub
3396 sections may result in fewer stubs. More importantly, we need to
3397 put all .init* and .fini* stubs at the beginning of the .init or
3398 .fini output sections respectively, because glibc splits the
3399 _init and _fini functions into multiple parts. Putting a stub in
3400 the middle of a function is not a good idea. */
3401
3402static void
cec5225b 3403group_sections (struct elf_aarch64_link_hash_table *htab,
a06ea964
NC
3404 bfd_size_type stub_group_size,
3405 bfd_boolean stubs_always_before_branch)
3406{
3407 asection **list = htab->input_list + htab->top_index;
3408
3409 do
3410 {
3411 asection *tail = *list;
3412
3413 if (tail == bfd_abs_section_ptr)
3414 continue;
3415
3416 while (tail != NULL)
3417 {
3418 asection *curr;
3419 asection *prev;
3420 bfd_size_type total;
3421
3422 curr = tail;
3423 total = tail->size;
3424 while ((prev = PREV_SEC (curr)) != NULL
3425 && ((total += curr->output_offset - prev->output_offset)
3426 < stub_group_size))
3427 curr = prev;
3428
3429 /* OK, the size from the start of CURR to the end is less
3430 than stub_group_size and thus can be handled by one stub
3431 section. (Or the tail section is itself larger than
3432 stub_group_size, in which case we may be toast.)
3433 We should really be keeping track of the total size of
3434 stubs added here, as stubs contribute to the final output
3435 section size. */
3436 do
3437 {
3438 prev = PREV_SEC (tail);
3439 /* Set up this stub group. */
3440 htab->stub_group[tail->id].link_sec = curr;
3441 }
3442 while (tail != curr && (tail = prev) != NULL);
3443
3444 /* But wait, there's more! Input sections up to stub_group_size
3445 bytes before the stub section can be handled by it too. */
3446 if (!stubs_always_before_branch)
3447 {
3448 total = 0;
3449 while (prev != NULL
3450 && ((total += tail->output_offset - prev->output_offset)
3451 < stub_group_size))
3452 {
3453 tail = prev;
3454 prev = PREV_SEC (tail);
3455 htab->stub_group[tail->id].link_sec = curr;
3456 }
3457 }
3458 tail = prev;
3459 }
3460 }
3461 while (list-- != htab->input_list);
3462
3463 free (htab->input_list);
3464}
3465
3466#undef PREV_SEC
3467
68fcca92
JW
3468#define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
3469
3470#define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
3471#define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
3472#define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
3473#define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
3474#define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
3475#define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
3476
3477#define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
3478#define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
3479#define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
3480#define AARCH64_ZR 0x1f
3481
3482/* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
3483 LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
3484
3485#define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
3486#define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
3487#define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
3488#define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
3489#define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
3490#define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
3491#define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
3492#define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
3493#define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
3494#define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
3495#define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
3496#define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
3497#define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
3498#define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
3499#define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
3500#define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
3501#define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
3502#define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
3503
3d14faea
MS
3504/* Classify an INSN if it is indeed a load/store.
3505
3506 Return TRUE if INSN is a LD/ST instruction otherwise return FALSE.
3507
3508 For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
3509 is set equal to RT.
3510
2d0ca824 3511 For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned. */
68fcca92
JW
3512
3513static bfd_boolean
3d14faea 3514aarch64_mem_op_p (uint32_t insn, unsigned int *rt, unsigned int *rt2,
68fcca92
JW
3515 bfd_boolean *pair, bfd_boolean *load)
3516{
3517 uint32_t opcode;
3518 unsigned int r;
3519 uint32_t opc = 0;
3520 uint32_t v = 0;
3521 uint32_t opc_v = 0;
3522
de194d85 3523 /* Bail out quickly if INSN doesn't fall into the load-store
68fcca92
JW
3524 encoding space. */
3525 if (!AARCH64_LDST (insn))
3526 return FALSE;
3527
3528 *pair = FALSE;
3529 *load = FALSE;
3530 if (AARCH64_LDST_EX (insn))
3531 {
3532 *rt = AARCH64_RT (insn);
3d14faea 3533 *rt2 = *rt;
68fcca92 3534 if (AARCH64_BIT (insn, 21) == 1)
07d6d2b8 3535 {
68fcca92 3536 *pair = TRUE;
3d14faea 3537 *rt2 = AARCH64_RT2 (insn);
68fcca92
JW
3538 }
3539 *load = AARCH64_LD (insn);
3540 return TRUE;
3541 }
3542 else if (AARCH64_LDST_NAP (insn)
3543 || AARCH64_LDSTP_PI (insn)
3544 || AARCH64_LDSTP_O (insn)
3545 || AARCH64_LDSTP_PRE (insn))
3546 {
3547 *pair = TRUE;
3548 *rt = AARCH64_RT (insn);
3d14faea 3549 *rt2 = AARCH64_RT2 (insn);
68fcca92
JW
3550 *load = AARCH64_LD (insn);
3551 return TRUE;
3552 }
3553 else if (AARCH64_LDST_PCREL (insn)
3554 || AARCH64_LDST_UI (insn)
3555 || AARCH64_LDST_PIIMM (insn)
3556 || AARCH64_LDST_U (insn)
3557 || AARCH64_LDST_PREIMM (insn)
3558 || AARCH64_LDST_RO (insn)
3559 || AARCH64_LDST_UIMM (insn))
3560 {
3561 *rt = AARCH64_RT (insn);
3d14faea 3562 *rt2 = *rt;
68fcca92
JW
3563 if (AARCH64_LDST_PCREL (insn))
3564 *load = TRUE;
3565 opc = AARCH64_BITS (insn, 22, 2);
3566 v = AARCH64_BIT (insn, 26);
3567 opc_v = opc | (v << 2);
3568 *load = (opc_v == 1 || opc_v == 2 || opc_v == 3
3569 || opc_v == 5 || opc_v == 7);
3570 return TRUE;
3571 }
3572 else if (AARCH64_LDST_SIMD_M (insn)
3573 || AARCH64_LDST_SIMD_M_PI (insn))
3574 {
3575 *rt = AARCH64_RT (insn);
3576 *load = AARCH64_BIT (insn, 22);
3577 opcode = (insn >> 12) & 0xf;
3578 switch (opcode)
3579 {
3580 case 0:
3581 case 2:
3d14faea 3582 *rt2 = *rt + 3;
68fcca92
JW
3583 break;
3584
3585 case 4:
3586 case 6:
3d14faea 3587 *rt2 = *rt + 2;
68fcca92
JW
3588 break;
3589
3590 case 7:
3d14faea 3591 *rt2 = *rt;
68fcca92
JW
3592 break;
3593
3594 case 8:
3595 case 10:
3d14faea 3596 *rt2 = *rt + 1;
68fcca92
JW
3597 break;
3598
3599 default:
3600 return FALSE;
3601 }
3602 return TRUE;
3603 }
3604 else if (AARCH64_LDST_SIMD_S (insn)
3605 || AARCH64_LDST_SIMD_S_PI (insn))
3606 {
3607 *rt = AARCH64_RT (insn);
3608 r = (insn >> 21) & 1;
3609 *load = AARCH64_BIT (insn, 22);
3610 opcode = (insn >> 13) & 0x7;
3611 switch (opcode)
3612 {
3613 case 0:
3614 case 2:
3615 case 4:
3d14faea 3616 *rt2 = *rt + r;
68fcca92
JW
3617 break;
3618
3619 case 1:
3620 case 3:
3621 case 5:
3d14faea 3622 *rt2 = *rt + (r == 0 ? 2 : 3);
68fcca92
JW
3623 break;
3624
3625 case 6:
3d14faea 3626 *rt2 = *rt + r;
68fcca92
JW
3627 break;
3628
3629 case 7:
3d14faea 3630 *rt2 = *rt + (r == 0 ? 2 : 3);
68fcca92
JW
3631 break;
3632
3633 default:
3634 return FALSE;
3635 }
3636 return TRUE;
3637 }
3638
3639 return FALSE;
3640}
3641
3642/* Return TRUE if INSN is multiply-accumulate. */
3643
3644static bfd_boolean
3645aarch64_mlxl_p (uint32_t insn)
3646{
3647 uint32_t op31 = AARCH64_OP31 (insn);
3648
3649 if (AARCH64_MAC (insn)
3650 && (op31 == 0 || op31 == 1 || op31 == 5)
3651 /* Exclude MUL instructions which are encoded as a multiple accumulate
3652 with RA = XZR. */
3653 && AARCH64_RA (insn) != AARCH64_ZR)
3654 return TRUE;
3655
3656 return FALSE;
3657}
3658
3659/* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
3660 it is possible for a 64-bit multiply-accumulate instruction to generate an
3661 incorrect result. The details are quite complex and hard to
3662 determine statically, since branches in the code may exist in some
3663 circumstances, but all cases end with a memory (load, store, or
3664 prefetch) instruction followed immediately by the multiply-accumulate
3665 operation. We employ a linker patching technique, by moving the potentially
3666 affected multiply-accumulate instruction into a patch region and replacing
3667 the original instruction with a branch to the patch. This function checks
3668 if INSN_1 is the memory operation followed by a multiply-accumulate
3669 operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
3670 if INSN_1 and INSN_2 are safe. */
3671
3672static bfd_boolean
3673aarch64_erratum_sequence (uint32_t insn_1, uint32_t insn_2)
3674{
3675 uint32_t rt;
3d14faea 3676 uint32_t rt2;
68fcca92
JW
3677 uint32_t rn;
3678 uint32_t rm;
3679 uint32_t ra;
3680 bfd_boolean pair;
3681 bfd_boolean load;
3682
3683 if (aarch64_mlxl_p (insn_2)
3d14faea 3684 && aarch64_mem_op_p (insn_1, &rt, &rt2, &pair, &load))
68fcca92
JW
3685 {
3686 /* Any SIMD memory op is independent of the subsequent MLA
3687 by definition of the erratum. */
3688 if (AARCH64_BIT (insn_1, 26))
3689 return TRUE;
3690
3691 /* If not SIMD, check for integer memory ops and MLA relationship. */
3692 rn = AARCH64_RN (insn_2);
3693 ra = AARCH64_RA (insn_2);
3694 rm = AARCH64_RM (insn_2);
3695
3696 /* If this is a load and there's a true(RAW) dependency, we are safe
3697 and this is not an erratum sequence. */
3698 if (load &&
3699 (rt == rn || rt == rm || rt == ra
3d14faea 3700 || (pair && (rt2 == rn || rt2 == rm || rt2 == ra))))
68fcca92
JW
3701 return FALSE;
3702
3703 /* We conservatively put out stubs for all other cases (including
3704 writebacks). */
3705 return TRUE;
3706 }
3707
3708 return FALSE;
3709}
3710
520c7b56
JW
3711/* Used to order a list of mapping symbols by address. */
3712
3713static int
3714elf_aarch64_compare_mapping (const void *a, const void *b)
3715{
3716 const elf_aarch64_section_map *amap = (const elf_aarch64_section_map *) a;
3717 const elf_aarch64_section_map *bmap = (const elf_aarch64_section_map *) b;
3718
3719 if (amap->vma > bmap->vma)
3720 return 1;
3721 else if (amap->vma < bmap->vma)
3722 return -1;
3723 else if (amap->type > bmap->type)
3724 /* Ensure results do not depend on the host qsort for objects with
3725 multiple mapping symbols at the same address by sorting on type
3726 after vma. */
3727 return 1;
3728 else if (amap->type < bmap->type)
3729 return -1;
3730 else
3731 return 0;
3732}
3733
2144188d 3734
35fee8b7
MS
3735static char *
3736_bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes)
3737{
3738 char *stub_name = (char *) bfd_malloc
3739 (strlen ("__erratum_835769_veneer_") + 16);
3740 sprintf (stub_name,"__erratum_835769_veneer_%d", num_fixes);
3741 return stub_name;
3742}
3743
4106101c 3744/* Scan for Cortex-A53 erratum 835769 sequence.
2144188d
MS
3745
3746 Return TRUE else FALSE on abnormal termination. */
3747
68fcca92 3748static bfd_boolean
5421cc6e
MS
3749_bfd_aarch64_erratum_835769_scan (bfd *input_bfd,
3750 struct bfd_link_info *info,
3751 unsigned int *num_fixes_p)
68fcca92
JW
3752{
3753 asection *section;
3754 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
68fcca92 3755 unsigned int num_fixes = *num_fixes_p;
68fcca92
JW
3756
3757 if (htab == NULL)
2144188d 3758 return TRUE;
68fcca92
JW
3759
3760 for (section = input_bfd->sections;
3761 section != NULL;
3762 section = section->next)
3763 {
3764 bfd_byte *contents = NULL;
3765 struct _aarch64_elf_section_data *sec_data;
3766 unsigned int span;
3767
3768 if (elf_section_type (section) != SHT_PROGBITS
3769 || (elf_section_flags (section) & SHF_EXECINSTR) == 0
3770 || (section->flags & SEC_EXCLUDE) != 0
3771 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
3772 || (section->output_section == bfd_abs_section_ptr))
3773 continue;
3774
3775 if (elf_section_data (section)->this_hdr.contents != NULL)
3776 contents = elf_section_data (section)->this_hdr.contents;
3777 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
2144188d 3778 return FALSE;
68fcca92
JW
3779
3780 sec_data = elf_aarch64_section_data (section);
520c7b56
JW
3781
3782 qsort (sec_data->map, sec_data->mapcount,
3783 sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
3784
68fcca92
JW
3785 for (span = 0; span < sec_data->mapcount; span++)
3786 {
3787 unsigned int span_start = sec_data->map[span].vma;
3788 unsigned int span_end = ((span == sec_data->mapcount - 1)
3789 ? sec_data->map[0].vma + section->size
3790 : sec_data->map[span + 1].vma);
3791 unsigned int i;
3792 char span_type = sec_data->map[span].type;
3793
3794 if (span_type == 'd')
3795 continue;
3796
3797 for (i = span_start; i + 4 < span_end; i += 4)
3798 {
3799 uint32_t insn_1 = bfd_getl32 (contents + i);
3800 uint32_t insn_2 = bfd_getl32 (contents + i + 4);
3801
3802 if (aarch64_erratum_sequence (insn_1, insn_2))
3803 {
5421cc6e 3804 struct elf_aarch64_stub_hash_entry *stub_entry;
35fee8b7
MS
3805 char *stub_name = _bfd_aarch64_erratum_835769_stub_name (num_fixes);
3806 if (! stub_name)
2144188d 3807 return FALSE;
68fcca92 3808
5421cc6e
MS
3809 stub_entry = _bfd_aarch64_add_stub_entry_in_group (stub_name,
3810 section,
3811 htab);
3812 if (! stub_entry)
3813 return FALSE;
68fcca92 3814
5421cc6e
MS
3815 stub_entry->stub_type = aarch64_stub_erratum_835769_veneer;
3816 stub_entry->target_section = section;
3817 stub_entry->target_value = i + 4;
3818 stub_entry->veneered_insn = insn_2;
3819 stub_entry->output_name = stub_name;
68fcca92
JW
3820 num_fixes++;
3821 }
3822 }
3823 }
3824 if (elf_section_data (section)->this_hdr.contents == NULL)
3825 free (contents);
3826 }
3827
357d1523
MS
3828 *num_fixes_p = num_fixes;
3829
2144188d 3830 return TRUE;
68fcca92
JW
3831}
3832
13f622ec 3833
4106101c
MS
3834/* Test if instruction INSN is ADRP. */
3835
3836static bfd_boolean
3837_bfd_aarch64_adrp_p (uint32_t insn)
3838{
3839 return ((insn & 0x9f000000) == 0x90000000);
3840}
3841
3842
3843/* Helper predicate to look for cortex-a53 erratum 843419 sequence 1. */
3844
3845static bfd_boolean
3846_bfd_aarch64_erratum_843419_sequence_p (uint32_t insn_1, uint32_t insn_2,
3847 uint32_t insn_3)
3848{
3849 uint32_t rt;
3850 uint32_t rt2;
3851 bfd_boolean pair;
3852 bfd_boolean load;
3853
3854 return (aarch64_mem_op_p (insn_2, &rt, &rt2, &pair, &load)
3855 && (!pair
3856 || (pair && !load))
3857 && AARCH64_LDST_UIMM (insn_3)
3858 && AARCH64_RN (insn_3) == AARCH64_RD (insn_1));
3859}
3860
3861
3862/* Test for the presence of Cortex-A53 erratum 843419 instruction sequence.
3863
3864 Return TRUE if section CONTENTS at offset I contains one of the
3865 erratum 843419 sequences, otherwise return FALSE. If a sequence is
3866 seen set P_VENEER_I to the offset of the final LOAD/STORE
3867 instruction in the sequence.
3868 */
3869
3870static bfd_boolean
3871_bfd_aarch64_erratum_843419_p (bfd_byte *contents, bfd_vma vma,
3872 bfd_vma i, bfd_vma span_end,
3873 bfd_vma *p_veneer_i)
3874{
3875 uint32_t insn_1 = bfd_getl32 (contents + i);
3876
3877 if (!_bfd_aarch64_adrp_p (insn_1))
3878 return FALSE;
3879
3880 if (span_end < i + 12)
3881 return FALSE;
3882
3883 uint32_t insn_2 = bfd_getl32 (contents + i + 4);
3884 uint32_t insn_3 = bfd_getl32 (contents + i + 8);
3885
3886 if ((vma & 0xfff) != 0xff8 && (vma & 0xfff) != 0xffc)
3887 return FALSE;
3888
3889 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1, insn_2, insn_3))
3890 {
3891 *p_veneer_i = i + 8;
3892 return TRUE;
3893 }
3894
3895 if (span_end < i + 16)
3896 return FALSE;
3897
3898 uint32_t insn_4 = bfd_getl32 (contents + i + 12);
3899
3900 if (_bfd_aarch64_erratum_843419_sequence_p (insn_1, insn_2, insn_4))
3901 {
3902 *p_veneer_i = i + 12;
3903 return TRUE;
3904 }
3905
3906 return FALSE;
3907}
3908
3909
13f622ec
MS
3910/* Resize all stub sections. */
3911
3912static void
3913_bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table *htab)
3914{
3915 asection *section;
3916
3917 /* OK, we've added some stubs. Find out the new size of the
3918 stub sections. */
3919 for (section = htab->stub_bfd->sections;
3920 section != NULL; section = section->next)
3921 {
3922 /* Ignore non-stub sections. */
3923 if (!strstr (section->name, STUB_SUFFIX))
3924 continue;
3925 section->size = 0;
3926 }
3927
3928 bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
13f622ec 3929
61865519
MS
3930 for (section = htab->stub_bfd->sections;
3931 section != NULL; section = section->next)
3932 {
3933 if (!strstr (section->name, STUB_SUFFIX))
3934 continue;
3935
9a2ebffd
JW
3936 /* Add space for a branch. Add 8 bytes to keep section 8 byte aligned,
3937 as long branch stubs contain a 64-bit address. */
61865519 3938 if (section->size)
9a2ebffd 3939 section->size += 8;
4106101c
MS
3940
3941 /* Ensure all stub sections have a size which is a multiple of
3942 4096. This is important in order to ensure that the insertion
3943 of stub sections does not in itself move existing code around
3944 in such a way that new errata sequences are created. */
3945 if (htab->fix_erratum_843419)
3946 if (section->size)
3947 section->size = BFD_ALIGN (section->size, 0x1000);
3948 }
3949}
3950
9a2ebffd 3951/* Construct an erratum 843419 workaround stub name. */
4106101c
MS
3952
3953static char *
3954_bfd_aarch64_erratum_843419_stub_name (asection *input_section,
3955 bfd_vma offset)
3956{
3957 const bfd_size_type len = 8 + 4 + 1 + 8 + 1 + 16 + 1;
3958 char *stub_name = bfd_malloc (len);
3959
3960 if (stub_name != NULL)
3961 snprintf (stub_name, len, "e843419@%04x_%08x_%" BFD_VMA_FMT "x",
3962 input_section->owner->id,
3963 input_section->id,
3964 offset);
3965 return stub_name;
3966}
3967
3968/* Build a stub_entry structure describing an 843419 fixup.
3969
3970 The stub_entry constructed is populated with the bit pattern INSN
3971 of the instruction located at OFFSET within input SECTION.
3972
3973 Returns TRUE on success. */
3974
3975static bfd_boolean
3976_bfd_aarch64_erratum_843419_fixup (uint32_t insn,
3977 bfd_vma adrp_offset,
3978 bfd_vma ldst_offset,
3979 asection *section,
3980 struct bfd_link_info *info)
3981{
3982 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
3983 char *stub_name;
3984 struct elf_aarch64_stub_hash_entry *stub_entry;
3985
3986 stub_name = _bfd_aarch64_erratum_843419_stub_name (section, ldst_offset);
3987 stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3988 FALSE, FALSE);
3989 if (stub_entry)
3990 {
3991 free (stub_name);
3992 return TRUE;
3993 }
3994
3995 /* We always place an 843419 workaround veneer in the stub section
3996 attached to the input section in which an erratum sequence has
3997 been found. This ensures that later in the link process (in
3998 elfNN_aarch64_write_section) when we copy the veneered
3999 instruction from the input section into the stub section the
4000 copied instruction will have had any relocations applied to it.
4001 If we placed workaround veneers in any other stub section then we
4002 could not assume that all relocations have been processed on the
4003 corresponding input section at the point we output the stub
4004 section.
4005 */
4006
4007 stub_entry = _bfd_aarch64_add_stub_entry_after (stub_name, section, htab);
4008 if (stub_entry == NULL)
4009 {
4010 free (stub_name);
4011 return FALSE;
4012 }
4013
4014 stub_entry->adrp_offset = adrp_offset;
4015 stub_entry->target_value = ldst_offset;
4016 stub_entry->target_section = section;
4017 stub_entry->stub_type = aarch64_stub_erratum_843419_veneer;
4018 stub_entry->veneered_insn = insn;
4019 stub_entry->output_name = stub_name;
4020
4021 return TRUE;
4022}
4023
4024
4025/* Scan an input section looking for the signature of erratum 843419.
4026
4027 Scans input SECTION in INPUT_BFD looking for erratum 843419
4028 signatures, for each signature found a stub_entry is created
4029 describing the location of the erratum for subsequent fixup.
4030
4031 Return TRUE on successful scan, FALSE on failure to scan.
4032 */
4033
4034static bfd_boolean
4035_bfd_aarch64_erratum_843419_scan (bfd *input_bfd, asection *section,
4036 struct bfd_link_info *info)
4037{
4038 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
4039
4040 if (htab == NULL)
4041 return TRUE;
4042
4043 if (elf_section_type (section) != SHT_PROGBITS
4044 || (elf_section_flags (section) & SHF_EXECINSTR) == 0
4045 || (section->flags & SEC_EXCLUDE) != 0
4046 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
4047 || (section->output_section == bfd_abs_section_ptr))
4048 return TRUE;
4049
4050 do
4051 {
4052 bfd_byte *contents = NULL;
4053 struct _aarch64_elf_section_data *sec_data;
4054 unsigned int span;
4055
4056 if (elf_section_data (section)->this_hdr.contents != NULL)
4057 contents = elf_section_data (section)->this_hdr.contents;
4058 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
4059 return FALSE;
4060
4061 sec_data = elf_aarch64_section_data (section);
4062
4063 qsort (sec_data->map, sec_data->mapcount,
4064 sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
4065
4066 for (span = 0; span < sec_data->mapcount; span++)
4067 {
4068 unsigned int span_start = sec_data->map[span].vma;
4069 unsigned int span_end = ((span == sec_data->mapcount - 1)
4070 ? sec_data->map[0].vma + section->size
4071 : sec_data->map[span + 1].vma);
4072 unsigned int i;
4073 char span_type = sec_data->map[span].type;
4074
4075 if (span_type == 'd')
4076 continue;
4077
4078 for (i = span_start; i + 8 < span_end; i += 4)
4079 {
4080 bfd_vma vma = (section->output_section->vma
4081 + section->output_offset
4082 + i);
4083 bfd_vma veneer_i;
4084
4085 if (_bfd_aarch64_erratum_843419_p
4086 (contents, vma, i, span_end, &veneer_i))
4087 {
4088 uint32_t insn = bfd_getl32 (contents + veneer_i);
4089
4090 if (!_bfd_aarch64_erratum_843419_fixup (insn, i, veneer_i,
4091 section, info))
4092 return FALSE;
4093 }
4094 }
4095 }
4096
4097 if (elf_section_data (section)->this_hdr.contents == NULL)
4098 free (contents);
61865519 4099 }
4106101c
MS
4100 while (0);
4101
4102 return TRUE;
61865519 4103}
13f622ec 4104
4106101c 4105
a06ea964
NC
4106/* Determine and set the size of the stub section for a final link.
4107
4108 The basic idea here is to examine all the relocations looking for
4109 PC-relative calls to a target that is unreachable with a "bl"
4110 instruction. */
4111
4112bfd_boolean
cec5225b 4113elfNN_aarch64_size_stubs (bfd *output_bfd,
a06ea964
NC
4114 bfd *stub_bfd,
4115 struct bfd_link_info *info,
4116 bfd_signed_vma group_size,
4117 asection * (*add_stub_section) (const char *,
4118 asection *),
4119 void (*layout_sections_again) (void))
4120{
4121 bfd_size_type stub_group_size;
4122 bfd_boolean stubs_always_before_branch;
5421cc6e 4123 bfd_boolean stub_changed = FALSE;
cec5225b 4124 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
68fcca92 4125 unsigned int num_erratum_835769_fixes = 0;
a06ea964
NC
4126
4127 /* Propagate mach to stub bfd, because it may not have been
4128 finalized when we created stub_bfd. */
4129 bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
4130 bfd_get_mach (output_bfd));
4131
4132 /* Stash our params away. */
4133 htab->stub_bfd = stub_bfd;
4134 htab->add_stub_section = add_stub_section;
4135 htab->layout_sections_again = layout_sections_again;
4136 stubs_always_before_branch = group_size < 0;
4137 if (group_size < 0)
4138 stub_group_size = -group_size;
4139 else
4140 stub_group_size = group_size;
4141
4142 if (stub_group_size == 1)
4143 {
4144 /* Default values. */
b9eead84 4145 /* AArch64 branch range is +-128MB. The value used is 1MB less. */
a06ea964
NC
4146 stub_group_size = 127 * 1024 * 1024;
4147 }
4148
4149 group_sections (htab, stub_group_size, stubs_always_before_branch);
4150
4106101c
MS
4151 (*htab->layout_sections_again) ();
4152
5421cc6e
MS
4153 if (htab->fix_erratum_835769)
4154 {
4155 bfd *input_bfd;
4156
4157 for (input_bfd = info->input_bfds;
4158 input_bfd != NULL; input_bfd = input_bfd->link.next)
4159 if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info,
4160 &num_erratum_835769_fixes))
4161 return FALSE;
4162
4106101c
MS
4163 _bfd_aarch64_resize_stubs (htab);
4164 (*htab->layout_sections_again) ();
4165 }
4166
4167 if (htab->fix_erratum_843419)
4168 {
4169 bfd *input_bfd;
4170
4171 for (input_bfd = info->input_bfds;
4172 input_bfd != NULL;
4173 input_bfd = input_bfd->link.next)
4174 {
4175 asection *section;
4176
4177 for (section = input_bfd->sections;
4178 section != NULL;
4179 section = section->next)
4180 if (!_bfd_aarch64_erratum_843419_scan (input_bfd, section, info))
4181 return FALSE;
4182 }
4183
4184 _bfd_aarch64_resize_stubs (htab);
4185 (*htab->layout_sections_again) ();
5421cc6e
MS
4186 }
4187
a06ea964
NC
4188 while (1)
4189 {
4190 bfd *input_bfd;
a06ea964 4191
9b9971aa
MS
4192 for (input_bfd = info->input_bfds;
4193 input_bfd != NULL; input_bfd = input_bfd->link.next)
a06ea964
NC
4194 {
4195 Elf_Internal_Shdr *symtab_hdr;
4196 asection *section;
4197 Elf_Internal_Sym *local_syms = NULL;
4198
4199 /* We'll need the symbol table in a second. */
4200 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4201 if (symtab_hdr->sh_info == 0)
4202 continue;
4203
4204 /* Walk over each section attached to the input bfd. */
4205 for (section = input_bfd->sections;
4206 section != NULL; section = section->next)
4207 {
4208 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
4209
4210 /* If there aren't any relocs, then there's nothing more
4211 to do. */
4212 if ((section->flags & SEC_RELOC) == 0
4213 || section->reloc_count == 0
4214 || (section->flags & SEC_CODE) == 0)
4215 continue;
4216
4217 /* If this section is a link-once section that will be
4218 discarded, then don't create any stubs. */
4219 if (section->output_section == NULL
4220 || section->output_section->owner != output_bfd)
4221 continue;
4222
4223 /* Get the relocs. */
4224 internal_relocs
4225 = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
4226 NULL, info->keep_memory);
4227 if (internal_relocs == NULL)
4228 goto error_ret_free_local;
4229
4230 /* Now examine each relocation. */
4231 irela = internal_relocs;
4232 irelaend = irela + section->reloc_count;
4233 for (; irela < irelaend; irela++)
4234 {
4235 unsigned int r_type, r_indx;
cec5225b
YZ
4236 enum elf_aarch64_stub_type stub_type;
4237 struct elf_aarch64_stub_hash_entry *stub_entry;
a06ea964
NC
4238 asection *sym_sec;
4239 bfd_vma sym_value;
4240 bfd_vma destination;
cec5225b 4241 struct elf_aarch64_link_hash_entry *hash;
a06ea964
NC
4242 const char *sym_name;
4243 char *stub_name;
4244 const asection *id_sec;
4245 unsigned char st_type;
4246 bfd_size_type len;
4247
cec5225b
YZ
4248 r_type = ELFNN_R_TYPE (irela->r_info);
4249 r_indx = ELFNN_R_SYM (irela->r_info);
a06ea964
NC
4250
4251 if (r_type >= (unsigned int) R_AARCH64_end)
4252 {
4253 bfd_set_error (bfd_error_bad_value);
4254 error_ret_free_internal:
4255 if (elf_section_data (section)->relocs == NULL)
4256 free (internal_relocs);
4257 goto error_ret_free_local;
4258 }
4259
4260 /* Only look for stubs on unconditional branch and
4261 branch and link instructions. */
a6bb11b2
YZ
4262 if (r_type != (unsigned int) AARCH64_R (CALL26)
4263 && r_type != (unsigned int) AARCH64_R (JUMP26))
a06ea964
NC
4264 continue;
4265
4266 /* Now determine the call target, its name, value,
4267 section. */
4268 sym_sec = NULL;
4269 sym_value = 0;
4270 destination = 0;
4271 hash = NULL;
4272 sym_name = NULL;
4273 if (r_indx < symtab_hdr->sh_info)
4274 {
4275 /* It's a local symbol. */
4276 Elf_Internal_Sym *sym;
4277 Elf_Internal_Shdr *hdr;
4278
4279 if (local_syms == NULL)
4280 {
4281 local_syms
4282 = (Elf_Internal_Sym *) symtab_hdr->contents;
4283 if (local_syms == NULL)
4284 local_syms
4285 = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
4286 symtab_hdr->sh_info, 0,
4287 NULL, NULL, NULL);
4288 if (local_syms == NULL)
4289 goto error_ret_free_internal;
4290 }
4291
4292 sym = local_syms + r_indx;
4293 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
4294 sym_sec = hdr->bfd_section;
4295 if (!sym_sec)
4296 /* This is an undefined symbol. It can never
4297 be resolved. */
4298 continue;
4299
4300 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
4301 sym_value = sym->st_value;
4302 destination = (sym_value + irela->r_addend
4303 + sym_sec->output_offset
4304 + sym_sec->output_section->vma);
4305 st_type = ELF_ST_TYPE (sym->st_info);
4306 sym_name
4307 = bfd_elf_string_from_elf_section (input_bfd,
4308 symtab_hdr->sh_link,
4309 sym->st_name);
4310 }
4311 else
4312 {
4313 int e_indx;
4314
4315 e_indx = r_indx - symtab_hdr->sh_info;
cec5225b 4316 hash = ((struct elf_aarch64_link_hash_entry *)
a06ea964
NC
4317 elf_sym_hashes (input_bfd)[e_indx]);
4318
4319 while (hash->root.root.type == bfd_link_hash_indirect
4320 || hash->root.root.type == bfd_link_hash_warning)
cec5225b 4321 hash = ((struct elf_aarch64_link_hash_entry *)
a06ea964
NC
4322 hash->root.root.u.i.link);
4323
4324 if (hash->root.root.type == bfd_link_hash_defined
4325 || hash->root.root.type == bfd_link_hash_defweak)
4326 {
cec5225b
YZ
4327 struct elf_aarch64_link_hash_table *globals =
4328 elf_aarch64_hash_table (info);
a06ea964
NC
4329 sym_sec = hash->root.root.u.def.section;
4330 sym_value = hash->root.root.u.def.value;
4331 /* For a destination in a shared library,
4332 use the PLT stub as target address to
4333 decide whether a branch stub is
4334 needed. */
4335 if (globals->root.splt != NULL && hash != NULL
4336 && hash->root.plt.offset != (bfd_vma) - 1)
4337 {
4338 sym_sec = globals->root.splt;
4339 sym_value = hash->root.plt.offset;
4340 if (sym_sec->output_section != NULL)
4341 destination = (sym_value
4342 + sym_sec->output_offset
4343 +
4344 sym_sec->output_section->vma);
4345 }
4346 else if (sym_sec->output_section != NULL)
4347 destination = (sym_value + irela->r_addend
4348 + sym_sec->output_offset
4349 + sym_sec->output_section->vma);
4350 }
4351 else if (hash->root.root.type == bfd_link_hash_undefined
4352 || (hash->root.root.type
4353 == bfd_link_hash_undefweak))
4354 {
4355 /* For a shared library, use the PLT stub as
4356 target address to decide whether a long
4357 branch stub is needed.
4358 For absolute code, they cannot be handled. */
cec5225b
YZ
4359 struct elf_aarch64_link_hash_table *globals =
4360 elf_aarch64_hash_table (info);
a06ea964
NC
4361
4362 if (globals->root.splt != NULL && hash != NULL
4363 && hash->root.plt.offset != (bfd_vma) - 1)
4364 {
4365 sym_sec = globals->root.splt;
4366 sym_value = hash->root.plt.offset;
4367 if (sym_sec->output_section != NULL)
4368 destination = (sym_value
4369 + sym_sec->output_offset
4370 +
4371 sym_sec->output_section->vma);
4372 }
4373 else
4374 continue;
4375 }
4376 else
4377 {
4378 bfd_set_error (bfd_error_bad_value);
4379 goto error_ret_free_internal;
4380 }
4381 st_type = ELF_ST_TYPE (hash->root.type);
4382 sym_name = hash->root.root.root.string;
4383 }
4384
4385 /* Determine what (if any) linker stub is needed. */
9a228467
JW
4386 stub_type = aarch64_type_of_stub (section, irela, sym_sec,
4387 st_type, destination);
a06ea964
NC
4388 if (stub_type == aarch64_stub_none)
4389 continue;
4390
4391 /* Support for grouping stub sections. */
4392 id_sec = htab->stub_group[section->id].link_sec;
4393
4394 /* Get the name of this stub. */
cec5225b 4395 stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash,
a06ea964
NC
4396 irela);
4397 if (!stub_name)
4398 goto error_ret_free_internal;
4399
4400 stub_entry =
4401 aarch64_stub_hash_lookup (&htab->stub_hash_table,
4402 stub_name, FALSE, FALSE);
4403 if (stub_entry != NULL)
4404 {
4405 /* The proper stub has already been created. */
4406 free (stub_name);
4407 continue;
4408 }
4409
ef857521
MS
4410 stub_entry = _bfd_aarch64_add_stub_entry_in_group
4411 (stub_name, section, htab);
a06ea964
NC
4412 if (stub_entry == NULL)
4413 {
4414 free (stub_name);
4415 goto error_ret_free_internal;
4416 }
4417
2f340668 4418 stub_entry->target_value = sym_value + irela->r_addend;
a06ea964
NC
4419 stub_entry->target_section = sym_sec;
4420 stub_entry->stub_type = stub_type;
4421 stub_entry->h = hash;
4422 stub_entry->st_type = st_type;
4423
4424 if (sym_name == NULL)
4425 sym_name = "unnamed";
4426 len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
4427 stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
4428 if (stub_entry->output_name == NULL)
4429 {
4430 free (stub_name);
4431 goto error_ret_free_internal;
4432 }
4433
4434 snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
4435 sym_name);
4436
4437 stub_changed = TRUE;
4438 }
4439
4440 /* We're done with the internal relocs, free them. */
4441 if (elf_section_data (section)->relocs == NULL)
4442 free (internal_relocs);
4443 }
4444 }
4445
4446 if (!stub_changed)
4447 break;
4448
13f622ec 4449 _bfd_aarch64_resize_stubs (htab);
a06ea964
NC
4450
4451 /* Ask the linker to do its stuff. */
4452 (*htab->layout_sections_again) ();
4453 stub_changed = FALSE;
4454 }
4455
4456 return TRUE;
4457
4458error_ret_free_local:
4459 return FALSE;
4460}
4461
4462/* Build all the stubs associated with the current output file. The
4463 stubs are kept in a hash table attached to the main linker hash
4464 table. We also set up the .plt entries for statically linked PIC
4465 functions here. This function is called via aarch64_elf_finish in the
4466 linker. */
4467
4468bfd_boolean
cec5225b 4469elfNN_aarch64_build_stubs (struct bfd_link_info *info)
a06ea964
NC
4470{
4471 asection *stub_sec;
4472 struct bfd_hash_table *table;
cec5225b 4473 struct elf_aarch64_link_hash_table *htab;
a06ea964 4474
cec5225b 4475 htab = elf_aarch64_hash_table (info);
a06ea964
NC
4476
4477 for (stub_sec = htab->stub_bfd->sections;
4478 stub_sec != NULL; stub_sec = stub_sec->next)
4479 {
4480 bfd_size_type size;
4481
4482 /* Ignore non-stub sections. */
4483 if (!strstr (stub_sec->name, STUB_SUFFIX))
4484 continue;
4485
4486 /* Allocate memory to hold the linker stubs. */
4487 size = stub_sec->size;
4488 stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
4489 if (stub_sec->contents == NULL && size != 0)
4490 return FALSE;
4491 stub_sec->size = 0;
61865519 4492
9a2ebffd
JW
4493 /* Add a branch around the stub section, and a nop, to keep it 8 byte
4494 aligned, as long branch stubs contain a 64-bit address. */
61865519 4495 bfd_putl32 (0x14000000 | (size >> 2), stub_sec->contents);
9a2ebffd
JW
4496 bfd_putl32 (INSN_NOP, stub_sec->contents + 4);
4497 stub_sec->size += 8;
a06ea964
NC
4498 }
4499
4500 /* Build the stubs as directed by the stub hash table. */
4501 table = &htab->stub_hash_table;
4502 bfd_hash_traverse (table, aarch64_build_one_stub, info);
4503
4504 return TRUE;
4505}
4506
4507
4508/* Add an entry to the code/data map for section SEC. */
4509
4510static void
cec5225b 4511elfNN_aarch64_section_map_add (asection *sec, char type, bfd_vma vma)
a06ea964
NC
4512{
4513 struct _aarch64_elf_section_data *sec_data =
cec5225b 4514 elf_aarch64_section_data (sec);
a06ea964
NC
4515 unsigned int newidx;
4516
4517 if (sec_data->map == NULL)
4518 {
cec5225b 4519 sec_data->map = bfd_malloc (sizeof (elf_aarch64_section_map));
a06ea964
NC
4520 sec_data->mapcount = 0;
4521 sec_data->mapsize = 1;
4522 }
4523
4524 newidx = sec_data->mapcount++;
4525
4526 if (sec_data->mapcount > sec_data->mapsize)
4527 {
4528 sec_data->mapsize *= 2;
4529 sec_data->map = bfd_realloc_or_free
cec5225b 4530 (sec_data->map, sec_data->mapsize * sizeof (elf_aarch64_section_map));
a06ea964
NC
4531 }
4532
4533 if (sec_data->map)
4534 {
4535 sec_data->map[newidx].vma = vma;
4536 sec_data->map[newidx].type = type;
4537 }
4538}
4539
4540
4541/* Initialise maps of insn/data for input BFDs. */
4542void
cec5225b 4543bfd_elfNN_aarch64_init_maps (bfd *abfd)
a06ea964
NC
4544{
4545 Elf_Internal_Sym *isymbuf;
4546 Elf_Internal_Shdr *hdr;
4547 unsigned int i, localsyms;
4548
4549 /* Make sure that we are dealing with an AArch64 elf binary. */
4550 if (!is_aarch64_elf (abfd))
4551 return;
4552
4553 if ((abfd->flags & DYNAMIC) != 0)
68fcca92 4554 return;
a06ea964
NC
4555
4556 hdr = &elf_symtab_hdr (abfd);
4557 localsyms = hdr->sh_info;
4558
4559 /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
4560 should contain the number of local symbols, which should come before any
4561 global symbols. Mapping symbols are always local. */
4562 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL);
4563
4564 /* No internal symbols read? Skip this BFD. */
4565 if (isymbuf == NULL)
4566 return;
4567
4568 for (i = 0; i < localsyms; i++)
4569 {
4570 Elf_Internal_Sym *isym = &isymbuf[i];
4571 asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
4572 const char *name;
4573
4574 if (sec != NULL && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
4575 {
4576 name = bfd_elf_string_from_elf_section (abfd,
4577 hdr->sh_link,
4578 isym->st_name);
4579
4580 if (bfd_is_aarch64_special_symbol_name
4581 (name, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP))
cec5225b 4582 elfNN_aarch64_section_map_add (sec, name[1], isym->st_value);
a06ea964
NC
4583 }
4584 }
4585}
4586
4587/* Set option values needed during linking. */
4588void
cec5225b 4589bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
a06ea964
NC
4590 struct bfd_link_info *link_info,
4591 int no_enum_warn,
68fcca92 4592 int no_wchar_warn, int pic_veneer,
4106101c 4593 int fix_erratum_835769,
1f56df9d
JW
4594 int fix_erratum_843419,
4595 int no_apply_dynamic_relocs)
a06ea964 4596{
cec5225b 4597 struct elf_aarch64_link_hash_table *globals;
a06ea964 4598
cec5225b 4599 globals = elf_aarch64_hash_table (link_info);
a06ea964 4600 globals->pic_veneer = pic_veneer;
68fcca92 4601 globals->fix_erratum_835769 = fix_erratum_835769;
4106101c
MS
4602 globals->fix_erratum_843419 = fix_erratum_843419;
4603 globals->fix_erratum_843419_adr = TRUE;
1f56df9d 4604 globals->no_apply_dynamic_relocs = no_apply_dynamic_relocs;
a06ea964
NC
4605
4606 BFD_ASSERT (is_aarch64_elf (output_bfd));
4607 elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
4608 elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
4609}
4610
a06ea964
NC
4611static bfd_vma
4612aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
cec5225b 4613 struct elf_aarch64_link_hash_table
a06ea964
NC
4614 *globals, struct bfd_link_info *info,
4615 bfd_vma value, bfd *output_bfd,
4616 bfd_boolean *unresolved_reloc_p)
4617{
4618 bfd_vma off = (bfd_vma) - 1;
4619 asection *basegot = globals->root.sgot;
4620 bfd_boolean dyn = globals->root.dynamic_sections_created;
4621
4622 if (h != NULL)
4623 {
a6bb11b2 4624 BFD_ASSERT (basegot != NULL);
a06ea964
NC
4625 off = h->got.offset;
4626 BFD_ASSERT (off != (bfd_vma) - 1);
0e1862bb
L
4627 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
4628 || (bfd_link_pic (info)
a06ea964
NC
4629 && SYMBOL_REFERENCES_LOCAL (info, h))
4630 || (ELF_ST_VISIBILITY (h->other)
4631 && h->root.type == bfd_link_hash_undefweak))
4632 {
4633 /* This is actually a static link, or it is a -Bsymbolic link
4634 and the symbol is defined locally. We must initialize this
4635 entry in the global offset table. Since the offset must
a6bb11b2
YZ
4636 always be a multiple of 8 (4 in the case of ILP32), we use
4637 the least significant bit to record whether we have
4638 initialized it already.
a06ea964
NC
4639 When doing a dynamic link, we create a .rel(a).got relocation
4640 entry to initialize the value. This is done in the
4641 finish_dynamic_symbol routine. */
4642 if ((off & 1) != 0)
4643 off &= ~1;
4644 else
4645 {
cec5225b 4646 bfd_put_NN (output_bfd, value, basegot->contents + off);
a06ea964
NC
4647 h->got.offset |= 1;
4648 }
4649 }
4650 else
4651 *unresolved_reloc_p = FALSE;
4652
4653 off = off + basegot->output_section->vma + basegot->output_offset;
4654 }
4655
4656 return off;
4657}
4658
4659/* Change R_TYPE to a more efficient access model where possible,
4660 return the new reloc type. */
4661
a6bb11b2
YZ
4662static bfd_reloc_code_real_type
4663aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
a06ea964
NC
4664 struct elf_link_hash_entry *h)
4665{
4666 bfd_boolean is_local = h == NULL;
a6bb11b2 4667
a06ea964
NC
4668 switch (r_type)
4669 {
a6bb11b2 4670 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
ce336788 4671 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
a6bb11b2
YZ
4672 return (is_local
4673 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4674 : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
4675
389b8029
MS
4676 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
4677 return (is_local
4678 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4679 : r_type);
4680
1ada945d
MS
4681 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
4682 return (is_local
4683 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
4684 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
4685
0484b454
RL
4686 case BFD_RELOC_AARCH64_TLSDESC_LDR:
4687 return (is_local
4688 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4689 : BFD_RELOC_AARCH64_NONE);
4690
4691 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
4692 return (is_local
4693 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
4694 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
4695
4696 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
4697 return (is_local
4698 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
4699 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
4700
a6bb11b2 4701 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
ce336788 4702 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
a6bb11b2
YZ
4703 return (is_local
4704 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
4705 : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
4706
4707 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
4708 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
4709
4710 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
4711 return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
4712
043bf05a
MS
4713 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
4714 return r_type;
4715
3c12b054
MS
4716 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
4717 return (is_local
4718 ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
4719 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
4720
0484b454 4721 case BFD_RELOC_AARCH64_TLSDESC_ADD:
f955cccf 4722 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
a6bb11b2 4723 case BFD_RELOC_AARCH64_TLSDESC_CALL:
a06ea964 4724 /* Instructions with these relocations will become NOPs. */
a6bb11b2
YZ
4725 return BFD_RELOC_AARCH64_NONE;
4726
259364ad
JW
4727 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
4728 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
4729 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
4730 return is_local ? BFD_RELOC_AARCH64_NONE : r_type;
4731
ac734732
RL
4732#if ARCH_SIZE == 64
4733 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
4734 return is_local
4735 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
4736 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
4737
4738 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
4739 return is_local
4740 ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
4741 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
4742#endif
4743
a6bb11b2
YZ
4744 default:
4745 break;
a06ea964
NC
4746 }
4747
4748 return r_type;
4749}
4750
4751static unsigned int
a6bb11b2 4752aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
a06ea964
NC
4753{
4754 switch (r_type)
4755 {
a6bb11b2
YZ
4756 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
4757 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
7018c030 4758 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
ce336788 4759 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
a2e1db00 4760 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
99ad26cb 4761 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
ce336788 4762 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
dc8008f5 4763 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
74a1bfe1 4764 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
a06ea964
NC
4765 return GOT_NORMAL;
4766
ce336788 4767 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
a6bb11b2 4768 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3c12b054 4769 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
7ba7cfe4 4770 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
94facae3 4771 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
73f925cc 4772 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
f69e4920 4773 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
77a69ff8 4774 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
a06ea964
NC
4775 return GOT_TLS_GD;
4776
0484b454 4777 case BFD_RELOC_AARCH64_TLSDESC_ADD:
f955cccf 4778 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
a6bb11b2 4779 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
389b8029 4780 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
a6bb11b2 4781 case BFD_RELOC_AARCH64_TLSDESC_CALL:
a6bb11b2 4782 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
f955cccf 4783 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
1ada945d 4784 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
0484b454
RL
4785 case BFD_RELOC_AARCH64_TLSDESC_LDR:
4786 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
4787 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
a06ea964
NC
4788 return GOT_TLSDESC_GD;
4789
a6bb11b2 4790 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
a6bb11b2 4791 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
ce336788 4792 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
043bf05a 4793 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
3b957e5b
RL
4794 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
4795 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
a06ea964
NC
4796 return GOT_TLS_IE;
4797
a6bb11b2
YZ
4798 default:
4799 break;
a06ea964
NC
4800 }
4801 return GOT_UNKNOWN;
4802}
4803
4804static bfd_boolean
4805aarch64_can_relax_tls (bfd *input_bfd,
4806 struct bfd_link_info *info,
a6bb11b2 4807 bfd_reloc_code_real_type r_type,
a06ea964
NC
4808 struct elf_link_hash_entry *h,
4809 unsigned long r_symndx)
4810{
4811 unsigned int symbol_got_type;
4812 unsigned int reloc_got_type;
4813
9331eea1 4814 if (! IS_AARCH64_TLS_RELAX_RELOC (r_type))
a06ea964
NC
4815 return FALSE;
4816
cec5225b 4817 symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
a06ea964
NC
4818 reloc_got_type = aarch64_reloc_got_type (r_type);
4819
4820 if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
4821 return TRUE;
4822
6dda7875 4823 if (!bfd_link_executable (info))
a06ea964
NC
4824 return FALSE;
4825
4826 if (h && h->root.type == bfd_link_hash_undefweak)
4827 return FALSE;
4828
4829 return TRUE;
4830}
4831
a6bb11b2
YZ
4832/* Given the relocation code R_TYPE, return the relaxed bfd reloc
4833 enumerator. */
4834
4835static bfd_reloc_code_real_type
a06ea964
NC
4836aarch64_tls_transition (bfd *input_bfd,
4837 struct bfd_link_info *info,
4838 unsigned int r_type,
4839 struct elf_link_hash_entry *h,
4840 unsigned long r_symndx)
4841{
a6bb11b2 4842 bfd_reloc_code_real_type bfd_r_type
0aa13fee 4843 = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
a06ea964 4844
a6bb11b2
YZ
4845 if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
4846 return bfd_r_type;
4847
4848 return aarch64_tls_transition_without_check (bfd_r_type, h);
a06ea964
NC
4849}
4850
4851/* Return the base VMA address which should be subtracted from real addresses
a6bb11b2 4852 when resolving R_AARCH64_TLS_DTPREL relocation. */
a06ea964
NC
4853
4854static bfd_vma
4855dtpoff_base (struct bfd_link_info *info)
4856{
4857 /* If tls_sec is NULL, we should have signalled an error already. */
4858 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4859 return elf_hash_table (info)->tls_sec->vma;
4860}
4861
a06ea964
NC
4862/* Return the base VMA address which should be subtracted from real addresses
4863 when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
4864
4865static bfd_vma
4866tpoff_base (struct bfd_link_info *info)
4867{
4868 struct elf_link_hash_table *htab = elf_hash_table (info);
4869
4870 /* If tls_sec is NULL, we should have signalled an error already. */
ac21917f 4871 BFD_ASSERT (htab->tls_sec != NULL);
a06ea964
NC
4872
4873 bfd_vma base = align_power ((bfd_vma) TCB_SIZE,
4874 htab->tls_sec->alignment_power);
4875 return htab->tls_sec->vma - base;
4876}
4877
4878static bfd_vma *
4879symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
4880 unsigned long r_symndx)
4881{
4882 /* Calculate the address of the GOT entry for symbol
4883 referred to in h. */
4884 if (h != NULL)
4885 return &h->got.offset;
4886 else
4887 {
4888 /* local symbol */
4889 struct elf_aarch64_local_symbol *l;
4890
cec5225b 4891 l = elf_aarch64_locals (input_bfd);
a06ea964
NC
4892 return &l[r_symndx].got_offset;
4893 }
4894}
4895
4896static void
4897symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
4898 unsigned long r_symndx)
4899{
4900 bfd_vma *p;
4901 p = symbol_got_offset_ref (input_bfd, h, r_symndx);
4902 *p |= 1;
4903}
4904
4905static int
4906symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
4907 unsigned long r_symndx)
4908{
4909 bfd_vma value;
4910 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
4911 return value & 1;
4912}
4913
4914static bfd_vma
4915symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
4916 unsigned long r_symndx)
4917{
4918 bfd_vma value;
4919 value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
4920 value &= ~1;
4921 return value;
4922}
4923
4924static bfd_vma *
4925symbol_tlsdesc_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
4926 unsigned long r_symndx)
4927{
4928 /* Calculate the address of the GOT entry for symbol
4929 referred to in h. */
4930 if (h != NULL)
4931 {
cec5225b
YZ
4932 struct elf_aarch64_link_hash_entry *eh;
4933 eh = (struct elf_aarch64_link_hash_entry *) h;
a06ea964
NC
4934 return &eh->tlsdesc_got_jump_table_offset;
4935 }
4936 else
4937 {
4938 /* local symbol */
4939 struct elf_aarch64_local_symbol *l;
4940
cec5225b 4941 l = elf_aarch64_locals (input_bfd);
a06ea964
NC
4942 return &l[r_symndx].tlsdesc_got_jump_table_offset;
4943 }
4944}
4945
4946static void
4947symbol_tlsdesc_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
4948 unsigned long r_symndx)
4949{
4950 bfd_vma *p;
4951 p = symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
4952 *p |= 1;
4953}
4954
4955static int
4956symbol_tlsdesc_got_offset_mark_p (bfd *input_bfd,
4957 struct elf_link_hash_entry *h,
4958 unsigned long r_symndx)
4959{
4960 bfd_vma value;
4961 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
4962 return value & 1;
4963}
4964
4965static bfd_vma
4966symbol_tlsdesc_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
4967 unsigned long r_symndx)
4968{
4969 bfd_vma value;
4970 value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
4971 value &= ~1;
4972 return value;
4973}
4974
68fcca92
JW
4975/* Data for make_branch_to_erratum_835769_stub(). */
4976
4977struct erratum_835769_branch_to_stub_data
4978{
4106101c 4979 struct bfd_link_info *info;
68fcca92
JW
4980 asection *output_section;
4981 bfd_byte *contents;
4982};
4983
4984/* Helper to insert branches to erratum 835769 stubs in the right
4985 places for a particular section. */
4986
4987static bfd_boolean
4988make_branch_to_erratum_835769_stub (struct bfd_hash_entry *gen_entry,
4989 void *in_arg)
4990{
4991 struct elf_aarch64_stub_hash_entry *stub_entry;
4992 struct erratum_835769_branch_to_stub_data *data;
4993 bfd_byte *contents;
4994 unsigned long branch_insn = 0;
4995 bfd_vma veneered_insn_loc, veneer_entry_loc;
4996 bfd_signed_vma branch_offset;
4997 unsigned int target;
4998 bfd *abfd;
4999
5000 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
5001 data = (struct erratum_835769_branch_to_stub_data *) in_arg;
5002
5003 if (stub_entry->target_section != data->output_section
5004 || stub_entry->stub_type != aarch64_stub_erratum_835769_veneer)
5005 return TRUE;
5006
5007 contents = data->contents;
5008 veneered_insn_loc = stub_entry->target_section->output_section->vma
5009 + stub_entry->target_section->output_offset
5010 + stub_entry->target_value;
5011 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
5012 + stub_entry->stub_sec->output_offset
5013 + stub_entry->stub_offset;
5014 branch_offset = veneer_entry_loc - veneered_insn_loc;
5015
5016 abfd = stub_entry->target_section->owner;
5017 if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
4eca0228 5018 _bfd_error_handler
90b6238f 5019 (_("%pB: error: erratum 835769 stub out "
4eca0228 5020 "of range (input file too large)"), abfd);
68fcca92
JW
5021
5022 target = stub_entry->target_value;
5023 branch_insn = 0x14000000;
5024 branch_offset >>= 2;
5025 branch_offset &= 0x3ffffff;
5026 branch_insn |= branch_offset;
5027 bfd_putl32 (branch_insn, &contents[target]);
5028
5029 return TRUE;
5030}
5031
4106101c
MS
5032
5033static bfd_boolean
5034_bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
5035 void *in_arg)
5036{
5037 struct elf_aarch64_stub_hash_entry *stub_entry
5038 = (struct elf_aarch64_stub_hash_entry *) gen_entry;
5039 struct erratum_835769_branch_to_stub_data *data
5040 = (struct erratum_835769_branch_to_stub_data *) in_arg;
5041 struct bfd_link_info *info;
5042 struct elf_aarch64_link_hash_table *htab;
5043 bfd_byte *contents;
5044 asection *section;
5045 bfd *abfd;
5046 bfd_vma place;
5047 uint32_t insn;
5048
5049 info = data->info;
5050 contents = data->contents;
5051 section = data->output_section;
5052
5053 htab = elf_aarch64_hash_table (info);
5054
5055 if (stub_entry->target_section != section
5056 || stub_entry->stub_type != aarch64_stub_erratum_843419_veneer)
5057 return TRUE;
5058
5059 insn = bfd_getl32 (contents + stub_entry->target_value);
5060 bfd_putl32 (insn,
5061 stub_entry->stub_sec->contents + stub_entry->stub_offset);
5062
5063 place = (section->output_section->vma + section->output_offset
5064 + stub_entry->adrp_offset);
5065 insn = bfd_getl32 (contents + stub_entry->adrp_offset);
5066
5067 if ((insn & AARCH64_ADRP_OP_MASK) != AARCH64_ADRP_OP)
5068 abort ();
5069
5070 bfd_signed_vma imm =
5071 (_bfd_aarch64_sign_extend
5072 ((bfd_vma) _bfd_aarch64_decode_adrp_imm (insn) << 12, 33)
5073 - (place & 0xfff));
5074
5075 if (htab->fix_erratum_843419_adr
5076 && (imm >= AARCH64_MIN_ADRP_IMM && imm <= AARCH64_MAX_ADRP_IMM))
5077 {
5078 insn = (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP, imm)
5079 | AARCH64_RT (insn));
5080 bfd_putl32 (insn, contents + stub_entry->adrp_offset);
5081 }
5082 else
5083 {
5084 bfd_vma veneered_insn_loc;
5085 bfd_vma veneer_entry_loc;
5086 bfd_signed_vma branch_offset;
5087 uint32_t branch_insn;
5088
5089 veneered_insn_loc = stub_entry->target_section->output_section->vma
5090 + stub_entry->target_section->output_offset
5091 + stub_entry->target_value;
5092 veneer_entry_loc = stub_entry->stub_sec->output_section->vma
5093 + stub_entry->stub_sec->output_offset
5094 + stub_entry->stub_offset;
5095 branch_offset = veneer_entry_loc - veneered_insn_loc;
5096
5097 abfd = stub_entry->target_section->owner;
5098 if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
4eca0228 5099 _bfd_error_handler
90b6238f 5100 (_("%pB: error: erratum 843419 stub out "
4106101c
MS
5101 "of range (input file too large)"), abfd);
5102
5103 branch_insn = 0x14000000;
5104 branch_offset >>= 2;
5105 branch_offset &= 0x3ffffff;
5106 branch_insn |= branch_offset;
5107 bfd_putl32 (branch_insn, contents + stub_entry->target_value);
5108 }
5109 return TRUE;
5110}
5111
5112
68fcca92
JW
5113static bfd_boolean
5114elfNN_aarch64_write_section (bfd *output_bfd ATTRIBUTE_UNUSED,
5115 struct bfd_link_info *link_info,
5116 asection *sec,
5117 bfd_byte *contents)
5118
5119{
5120 struct elf_aarch64_link_hash_table *globals =
f872121a 5121 elf_aarch64_hash_table (link_info);
68fcca92
JW
5122
5123 if (globals == NULL)
5124 return FALSE;
5125
5126 /* Fix code to point to erratum 835769 stubs. */
5127 if (globals->fix_erratum_835769)
5128 {
5129 struct erratum_835769_branch_to_stub_data data;
5130
4106101c 5131 data.info = link_info;
68fcca92
JW
5132 data.output_section = sec;
5133 data.contents = contents;
5134 bfd_hash_traverse (&globals->stub_hash_table,
5135 make_branch_to_erratum_835769_stub, &data);
5136 }
5137
4106101c
MS
5138 if (globals->fix_erratum_843419)
5139 {
5140 struct erratum_835769_branch_to_stub_data data;
5141
5142 data.info = link_info;
5143 data.output_section = sec;
5144 data.contents = contents;
5145 bfd_hash_traverse (&globals->stub_hash_table,
5146 _bfd_aarch64_erratum_843419_branch_to_stub, &data);
5147 }
5148
68fcca92
JW
5149 return FALSE;
5150}
5151
2aff25ba
JW
5152/* Return TRUE if RELOC is a relocation against the base of GOT table. */
5153
5154static bfd_boolean
5155aarch64_relocation_aginst_gp_p (bfd_reloc_code_real_type reloc)
5156{
5157 return (reloc == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
5158 || reloc == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
5159 || reloc == BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
5160 || reloc == BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
5161 || reloc == BFD_RELOC_AARCH64_MOVW_GOTOFF_G1);
5162}
5163
4e7fbb34
JW
5164/* Perform a relocation as part of a final link. The input relocation type
5165 should be TLS relaxed. */
5166
a06ea964 5167static bfd_reloc_status_type
cec5225b 5168elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
a06ea964
NC
5169 bfd *input_bfd,
5170 bfd *output_bfd,
5171 asection *input_section,
5172 bfd_byte *contents,
5173 Elf_Internal_Rela *rel,
5174 bfd_vma value,
5175 struct bfd_link_info *info,
5176 asection *sym_sec,
5177 struct elf_link_hash_entry *h,
5178 bfd_boolean *unresolved_reloc_p,
5179 bfd_boolean save_addend,
1419bbe5
WN
5180 bfd_vma *saved_addend,
5181 Elf_Internal_Sym *sym)
a06ea964 5182{
1419bbe5 5183 Elf_Internal_Shdr *symtab_hdr;
a06ea964 5184 unsigned int r_type = howto->type;
a6bb11b2
YZ
5185 bfd_reloc_code_real_type bfd_r_type
5186 = elfNN_aarch64_bfd_reloc_from_howto (howto);
a06ea964
NC
5187 unsigned long r_symndx;
5188 bfd_byte *hit_data = contents + rel->r_offset;
96d01d93 5189 bfd_vma place, off, got_entry_addr = 0;
a06ea964 5190 bfd_signed_vma signed_addend;
cec5225b 5191 struct elf_aarch64_link_hash_table *globals;
a06ea964 5192 bfd_boolean weak_undef_p;
ff07562f 5193 bfd_boolean relative_reloc;
b53b1bed 5194 asection *base_got;
ff07562f 5195 bfd_vma orig_value = value;
ddb7fd0f 5196 bfd_boolean resolved_to_zero;
0c1ded8d 5197 bfd_boolean abs_symbol_p;
a06ea964 5198
cec5225b 5199 globals = elf_aarch64_hash_table (info);
a06ea964 5200
1419bbe5
WN
5201 symtab_hdr = &elf_symtab_hdr (input_bfd);
5202
a06ea964
NC
5203 BFD_ASSERT (is_aarch64_elf (input_bfd));
5204
cec5225b 5205 r_symndx = ELFNN_R_SYM (rel->r_info);
a06ea964 5206
a06ea964
NC
5207 place = input_section->output_section->vma
5208 + input_section->output_offset + rel->r_offset;
5209
5210 /* Get addend, accumulating the addend for consecutive relocs
5211 which refer to the same offset. */
5212 signed_addend = saved_addend ? *saved_addend : 0;
5213 signed_addend += rel->r_addend;
5214
5215 weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
5216 : bfd_is_und_section (sym_sec));
0c1ded8d
RL
5217 abs_symbol_p = (h !=NULL && h->root.type == bfd_link_hash_defined
5218 && bfd_is_abs_section (h->root.u.def.section));
5219
a6bb11b2 5220
1419bbe5
WN
5221 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
5222 it here if it is defined in a non-shared object. */
5223 if (h != NULL
5224 && h->type == STT_GNU_IFUNC
5225 && h->def_regular)
5226 {
5227 asection *plt;
5228 const char *name;
99ad26cb 5229 bfd_vma addend = 0;
1419bbe5 5230
545bc2b3
SN
5231 if ((input_section->flags & SEC_ALLOC) == 0)
5232 {
f657f8c4
NC
5233 /* If this is a SHT_NOTE section without SHF_ALLOC, treat
5234 STT_GNU_IFUNC symbol as STT_FUNC. */
5235 if (elf_section_type (input_section) == SHT_NOTE)
5236 goto skip_ifunc;
5237
545bc2b3
SN
5238 /* Dynamic relocs are not propagated for SEC_DEBUGGING
5239 sections because such sections are not SEC_ALLOC and
5240 thus ld.so will not process them. */
5241 if ((input_section->flags & SEC_DEBUGGING) != 0)
5242 return bfd_reloc_ok;
5243
5244 if (h->root.root.string)
5245 name = h->root.root.string;
5246 else
5247 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, NULL);
5248 _bfd_error_handler
5249 /* xgettext:c-format */
2dcf00ce
AM
5250 (_("%pB(%pA+%#" PRIx64 "): "
5251 "unresolvable %s relocation against symbol `%s'"),
5252 input_bfd, input_section, (uint64_t) rel->r_offset,
5253 howto->name, name);
545bc2b3 5254 bfd_set_error (bfd_error_bad_value);
1d75a8e2 5255 return bfd_reloc_notsupported;
545bc2b3
SN
5256 }
5257 else if (h->plt.offset == (bfd_vma) -1)
5258 goto bad_ifunc_reloc;
1419bbe5
WN
5259
5260 /* STT_GNU_IFUNC symbol must go through PLT. */
5261 plt = globals->root.splt ? globals->root.splt : globals->root.iplt;
5262 value = (plt->output_section->vma + plt->output_offset + h->plt.offset);
5263
5264 switch (bfd_r_type)
5265 {
5266 default:
545bc2b3 5267bad_ifunc_reloc:
1419bbe5
WN
5268 if (h->root.root.string)
5269 name = h->root.root.string;
5270 else
5271 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5272 NULL);
4eca0228 5273 _bfd_error_handler
695344c0 5274 /* xgettext:c-format */
871b3ab2 5275 (_("%pB: relocation %s against STT_GNU_IFUNC "
1419bbe5
WN
5276 "symbol `%s' isn't handled by %s"), input_bfd,
5277 howto->name, name, __FUNCTION__);
5278 bfd_set_error (bfd_error_bad_value);
1d75a8e2 5279 return bfd_reloc_notsupported;
1419bbe5
WN
5280
5281 case BFD_RELOC_AARCH64_NN:
5282 if (rel->r_addend != 0)
5283 {
5284 if (h->root.root.string)
5285 name = h->root.root.string;
5286 else
5287 name = bfd_elf_sym_name (input_bfd, symtab_hdr,
5288 sym, NULL);
4eca0228 5289 _bfd_error_handler
695344c0 5290 /* xgettext:c-format */
871b3ab2 5291 (_("%pB: relocation %s against STT_GNU_IFUNC "
2dcf00ce
AM
5292 "symbol `%s' has non-zero addend: %" PRId64),
5293 input_bfd, howto->name, name, (int64_t) rel->r_addend);
1419bbe5 5294 bfd_set_error (bfd_error_bad_value);
1d75a8e2 5295 return bfd_reloc_notsupported;
1419bbe5
WN
5296 }
5297
5298 /* Generate dynamic relocation only when there is a
5299 non-GOT reference in a shared object. */
0e1862bb 5300 if (bfd_link_pic (info) && h->non_got_ref)
1419bbe5
WN
5301 {
5302 Elf_Internal_Rela outrel;
5303 asection *sreloc;
5304
5305 /* Need a dynamic relocation to get the real function
5306 address. */
5307 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
5308 info,
5309 input_section,
5310 rel->r_offset);
5311 if (outrel.r_offset == (bfd_vma) -1
5312 || outrel.r_offset == (bfd_vma) -2)
5313 abort ();
5314
5315 outrel.r_offset += (input_section->output_section->vma
5316 + input_section->output_offset);
5317
5318 if (h->dynindx == -1
5319 || h->forced_local
0e1862bb 5320 || bfd_link_executable (info))
1419bbe5
WN
5321 {
5322 /* This symbol is resolved locally. */
5323 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
5324 outrel.r_addend = (h->root.u.def.value
5325 + h->root.u.def.section->output_section->vma
5326 + h->root.u.def.section->output_offset);
5327 }
5328 else
5329 {
5330 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
5331 outrel.r_addend = 0;
5332 }
5333
5334 sreloc = globals->root.irelifunc;
5335 elf_append_rela (output_bfd, sreloc, &outrel);
5336
5337 /* If this reloc is against an external symbol, we
5338 do not want to fiddle with the addend. Otherwise,
5339 we need to include the symbol value so that it
5340 becomes an addend for the dynamic reloc. For an
5341 internal symbol, we have updated addend. */
5342 return bfd_reloc_ok;
5343 }
5344 /* FALLTHROUGH */
1419bbe5 5345 case BFD_RELOC_AARCH64_CALL26:
ce336788 5346 case BFD_RELOC_AARCH64_JUMP26:
1419bbe5
WN
5347 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5348 signed_addend,
5349 weak_undef_p);
5350 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
5351 howto, value);
1419bbe5
WN
5352 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
5353 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
7018c030 5354 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
ce336788 5355 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
99ad26cb 5356 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
dc8008f5 5357 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
74a1bfe1 5358 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
a2e1db00 5359 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
ce336788 5360 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
1419bbe5
WN
5361 base_got = globals->root.sgot;
5362 off = h->got.offset;
5363
5364 if (base_got == NULL)
5365 abort ();
5366
5367 if (off == (bfd_vma) -1)
5368 {
5369 bfd_vma plt_index;
5370
5371 /* We can't use h->got.offset here to save state, or
5372 even just remember the offset, as finish_dynamic_symbol
5373 would use that as offset into .got. */
5374
5375 if (globals->root.splt != NULL)
5376 {
b1ee0cc4
WN
5377 plt_index = ((h->plt.offset - globals->plt_header_size) /
5378 globals->plt_entry_size);
1419bbe5
WN
5379 off = (plt_index + 3) * GOT_ENTRY_SIZE;
5380 base_got = globals->root.sgotplt;
5381 }
5382 else
5383 {
5384 plt_index = h->plt.offset / globals->plt_entry_size;
5385 off = plt_index * GOT_ENTRY_SIZE;
5386 base_got = globals->root.igotplt;
5387 }
5388
5389 if (h->dynindx == -1
5390 || h->forced_local
5391 || info->symbolic)
5392 {
5393 /* This references the local definition. We must
5394 initialize this entry in the global offset table.
5395 Since the offset must always be a multiple of 8,
5396 we use the least significant bit to record
5397 whether we have initialized it already.
5398
5399 When doing a dynamic link, we create a .rela.got
5400 relocation entry to initialize the value. This
5401 is done in the finish_dynamic_symbol routine. */
5402 if ((off & 1) != 0)
5403 off &= ~1;
5404 else
5405 {
5406 bfd_put_NN (output_bfd, value,
5407 base_got->contents + off);
5408 /* Note that this is harmless as -1 | 1 still is -1. */
5409 h->got.offset |= 1;
5410 }
5411 }
5412 value = (base_got->output_section->vma
5413 + base_got->output_offset + off);
5414 }
5415 else
5416 value = aarch64_calculate_got_entry_vma (h, globals, info,
5417 value, output_bfd,
5418 unresolved_reloc_p);
a0becb89 5419
2aff25ba
JW
5420 if (aarch64_relocation_aginst_gp_p (bfd_r_type))
5421 addend = (globals->root.sgot->output_section->vma
5422 + globals->root.sgot->output_offset);
a0becb89 5423
1419bbe5 5424 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
99ad26cb 5425 addend, weak_undef_p);
1419bbe5 5426 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
1419bbe5 5427 case BFD_RELOC_AARCH64_ADD_LO12:
ce336788 5428 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
1419bbe5
WN
5429 break;
5430 }
5431 }
5432
f657f8c4 5433 skip_ifunc:
ddb7fd0f
L
5434 resolved_to_zero = (h != NULL
5435 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
5436
a6bb11b2 5437 switch (bfd_r_type)
a06ea964 5438 {
a6bb11b2 5439 case BFD_RELOC_AARCH64_NONE:
0484b454 5440 case BFD_RELOC_AARCH64_TLSDESC_ADD:
a6bb11b2 5441 case BFD_RELOC_AARCH64_TLSDESC_CALL:
0484b454 5442 case BFD_RELOC_AARCH64_TLSDESC_LDR:
a06ea964
NC
5443 *unresolved_reloc_p = FALSE;
5444 return bfd_reloc_ok;
5445
a6bb11b2 5446 case BFD_RELOC_AARCH64_NN:
a06ea964
NC
5447
5448 /* When generating a shared object or relocatable executable, these
07d6d2b8
AM
5449 relocations are copied into the output file to be resolved at
5450 run time. */
6353d82b
JW
5451 if (((bfd_link_pic (info)
5452 || globals->root.is_relocatable_executable)
5453 && (input_section->flags & SEC_ALLOC)
5454 && (h == NULL
ddb7fd0f
L
5455 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5456 && !resolved_to_zero)
6353d82b
JW
5457 || h->root.type != bfd_link_hash_undefweak))
5458 /* Or we are creating an executable, we may need to keep relocations
5459 for symbols satisfied by a dynamic library if we manage to avoid
5460 copy relocs for the symbol. */
5461 || (ELIMINATE_COPY_RELOCS
5462 && !bfd_link_pic (info)
5463 && h != NULL
5464 && (input_section->flags & SEC_ALLOC)
5465 && h->dynindx != -1
5466 && !h->non_got_ref
5467 && ((h->def_dynamic
5468 && !h->def_regular)
5469 || h->root.type == bfd_link_hash_undefweak
5470 || h->root.type == bfd_link_hash_undefined)))
a06ea964
NC
5471 {
5472 Elf_Internal_Rela outrel;
5473 bfd_byte *loc;
5474 bfd_boolean skip, relocate;
5475 asection *sreloc;
5476
5477 *unresolved_reloc_p = FALSE;
5478
a06ea964
NC
5479 skip = FALSE;
5480 relocate = FALSE;
5481
5482 outrel.r_addend = signed_addend;
5483 outrel.r_offset =
5484 _bfd_elf_section_offset (output_bfd, info, input_section,
5485 rel->r_offset);
5486 if (outrel.r_offset == (bfd_vma) - 1)
5487 skip = TRUE;
5488 else if (outrel.r_offset == (bfd_vma) - 2)
5489 {
5490 skip = TRUE;
5491 relocate = TRUE;
5492 }
0c1ded8d
RL
5493 else if (abs_symbol_p)
5494 {
5495 /* Local absolute symbol. */
5496 skip = (h->forced_local || (h->dynindx == -1));
5497 relocate = skip;
5498 }
a06ea964
NC
5499
5500 outrel.r_offset += (input_section->output_section->vma
5501 + input_section->output_offset);
5502
5503 if (skip)
5504 memset (&outrel, 0, sizeof outrel);
5505 else if (h != NULL
5506 && h->dynindx != -1
0e1862bb 5507 && (!bfd_link_pic (info)
0c1ded8d 5508 || !(bfd_link_pie (info) || SYMBOLIC_BIND (info, h))
0e1862bb 5509 || !h->def_regular))
cec5225b 5510 outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
a06ea964
NC
5511 else
5512 {
5513 int symbol;
5514
5515 /* On SVR4-ish systems, the dynamic loader cannot
5516 relocate the text and data segments independently,
5517 so the symbol does not matter. */
5518 symbol = 0;
1f56df9d 5519 relocate = globals->no_apply_dynamic_relocs ? FALSE : TRUE;
a6bb11b2 5520 outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
a06ea964
NC
5521 outrel.r_addend += value;
5522 }
5523
1419bbe5
WN
5524 sreloc = elf_section_data (input_section)->sreloc;
5525 if (sreloc == NULL || sreloc->contents == NULL)
5526 return bfd_reloc_notsupported;
5527
5528 loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
cec5225b 5529 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
a06ea964 5530
1419bbe5 5531 if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
a06ea964
NC
5532 {
5533 /* Sanity to check that we have previously allocated
5534 sufficient space in the relocation section for the
5535 number of relocations we actually want to emit. */
5536 abort ();
5537 }
5538
5539 /* If this reloc is against an external symbol, we do not want to
5540 fiddle with the addend. Otherwise, we need to include the symbol
5541 value so that it becomes an addend for the dynamic reloc. */
5542 if (!relocate)
5543 return bfd_reloc_ok;
5544
5545 return _bfd_final_link_relocate (howto, input_bfd, input_section,
5546 contents, rel->r_offset, value,
5547 signed_addend);
5548 }
5549 else
5550 value += signed_addend;
5551 break;
5552
a6bb11b2 5553 case BFD_RELOC_AARCH64_CALL26:
ce336788 5554 case BFD_RELOC_AARCH64_JUMP26:
a06ea964
NC
5555 {
5556 asection *splt = globals->root.splt;
5557 bfd_boolean via_plt_p =
5558 splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
5559
5560 /* A call to an undefined weak symbol is converted to a jump to
5561 the next instruction unless a PLT entry will be created.
5562 The jump to the next instruction is optimized as a NOP.
5563 Do the same for local undefined symbols. */
5564 if (weak_undef_p && ! via_plt_p)
5565 {
5566 bfd_putl32 (INSN_NOP, hit_data);
5567 return bfd_reloc_ok;
5568 }
5569
5570 /* If the call goes through a PLT entry, make sure to
5571 check distance to the right destination address. */
5572 if (via_plt_p)
07f9ddfe
JW
5573 value = (splt->output_section->vma
5574 + splt->output_offset + h->plt.offset);
5575
5576 /* Check if a stub has to be inserted because the destination
5577 is too far away. */
5578 struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
2f340668
JW
5579
5580 /* If the branch destination is directed to plt stub, "value" will be
5581 the final destination, otherwise we should plus signed_addend, it may
5582 contain non-zero value, for example call to local function symbol
5583 which are turned into "sec_sym + sec_off", and sec_off is kept in
5584 signed_addend. */
5585 if (! aarch64_valid_branch_p (via_plt_p ? value : value + signed_addend,
5586 place))
07f9ddfe
JW
5587 /* The target is out of reach, so redirect the branch to
5588 the local stub for this function. */
5589 stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
5590 rel, globals);
5591 if (stub_entry != NULL)
2f340668
JW
5592 {
5593 value = (stub_entry->stub_offset
5594 + stub_entry->stub_sec->output_offset
5595 + stub_entry->stub_sec->output_section->vma);
5596
5597 /* We have redirected the destination to stub entry address,
5598 so ignore any addend record in the original rela entry. */
5599 signed_addend = 0;
5600 }
a06ea964 5601 }
caed7120
YZ
5602 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5603 signed_addend, weak_undef_p);
07f9ddfe 5604 *unresolved_reloc_p = FALSE;
a06ea964
NC
5605 break;
5606
dcbd20eb
JW
5607 case BFD_RELOC_AARCH64_16_PCREL:
5608 case BFD_RELOC_AARCH64_32_PCREL:
5609 case BFD_RELOC_AARCH64_64_PCREL:
ce336788
JW
5610 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
5611 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
5612 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
5613 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
1daf502a
RL
5614 case BFD_RELOC_AARCH64_MOVW_PREL_G0:
5615 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC:
5616 case BFD_RELOC_AARCH64_MOVW_PREL_G1:
5617 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC:
5618 case BFD_RELOC_AARCH64_MOVW_PREL_G2:
5619 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC:
5620 case BFD_RELOC_AARCH64_MOVW_PREL_G3:
0e1862bb 5621 if (bfd_link_pic (info)
dcbd20eb
JW
5622 && (input_section->flags & SEC_ALLOC) != 0
5623 && (input_section->flags & SEC_READONLY) != 0
d68f1976 5624 && !SYMBOL_REFERENCES_LOCAL (info, h))
dcbd20eb
JW
5625 {
5626 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
5627
4eca0228 5628 _bfd_error_handler
695344c0 5629 /* xgettext:c-format */
871b3ab2 5630 (_("%pB: relocation %s against symbol `%s' which may bind "
d68f1976
JW
5631 "externally can not be used when making a shared object; "
5632 "recompile with -fPIC"),
dcbd20eb
JW
5633 input_bfd, elfNN_aarch64_howto_table[howto_index].name,
5634 h->root.root.string);
5635 bfd_set_error (bfd_error_bad_value);
1d75a8e2 5636 return bfd_reloc_notsupported;
dcbd20eb 5637 }
1a0670f3 5638 /* Fall through. */
dcbd20eb 5639
a6bb11b2 5640 case BFD_RELOC_AARCH64_16:
92d77487
RL
5641#if ARCH_SIZE == 64
5642 case BFD_RELOC_AARCH64_32:
5643#endif
a6bb11b2 5644 case BFD_RELOC_AARCH64_ADD_LO12:
a6bb11b2 5645 case BFD_RELOC_AARCH64_BRANCH19:
ce336788 5646 case BFD_RELOC_AARCH64_LDST128_LO12:
a6bb11b2
YZ
5647 case BFD_RELOC_AARCH64_LDST16_LO12:
5648 case BFD_RELOC_AARCH64_LDST32_LO12:
5649 case BFD_RELOC_AARCH64_LDST64_LO12:
ce336788 5650 case BFD_RELOC_AARCH64_LDST8_LO12:
a6bb11b2
YZ
5651 case BFD_RELOC_AARCH64_MOVW_G0:
5652 case BFD_RELOC_AARCH64_MOVW_G0_NC:
ce336788 5653 case BFD_RELOC_AARCH64_MOVW_G0_S:
a6bb11b2
YZ
5654 case BFD_RELOC_AARCH64_MOVW_G1:
5655 case BFD_RELOC_AARCH64_MOVW_G1_NC:
ce336788 5656 case BFD_RELOC_AARCH64_MOVW_G1_S:
a6bb11b2
YZ
5657 case BFD_RELOC_AARCH64_MOVW_G2:
5658 case BFD_RELOC_AARCH64_MOVW_G2_NC:
ce336788 5659 case BFD_RELOC_AARCH64_MOVW_G2_S:
a6bb11b2 5660 case BFD_RELOC_AARCH64_MOVW_G3:
a6bb11b2 5661 case BFD_RELOC_AARCH64_TSTBR14:
caed7120
YZ
5662 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5663 signed_addend, weak_undef_p);
a06ea964
NC
5664 break;
5665
a6bb11b2
YZ
5666 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
5667 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
7018c030 5668 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
ce336788 5669 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
99ad26cb 5670 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
ce336788 5671 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
2aff25ba
JW
5672 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
5673 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
5674 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
a06ea964
NC
5675 if (globals->root.sgot == NULL)
5676 BFD_ASSERT (h != NULL);
5677
ff07562f 5678 relative_reloc = FALSE;
a06ea964
NC
5679 if (h != NULL)
5680 {
99ad26cb 5681 bfd_vma addend = 0;
ff07562f
JW
5682
5683 /* If a symbol is not dynamic and is not undefined weak, bind it
5684 locally and generate a RELATIVE relocation under PIC mode.
5685
5686 NOTE: one symbol may be referenced by several relocations, we
5687 should only generate one RELATIVE relocation for that symbol.
5688 Therefore, check GOT offset mark first. */
5689 if (h->dynindx == -1
5690 && !h->forced_local
5691 && h->root.type != bfd_link_hash_undefweak
5692 && bfd_link_pic (info)
5693 && !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
5694 relative_reloc = TRUE;
5695
a06ea964
NC
5696 value = aarch64_calculate_got_entry_vma (h, globals, info, value,
5697 output_bfd,
5698 unresolved_reloc_p);
ff07562f
JW
5699 /* Record the GOT entry address which will be used when generating
5700 RELATIVE relocation. */
5701 if (relative_reloc)
5702 got_entry_addr = value;
5703
2aff25ba 5704 if (aarch64_relocation_aginst_gp_p (bfd_r_type))
99ad26cb
JW
5705 addend = (globals->root.sgot->output_section->vma
5706 + globals->root.sgot->output_offset);
caed7120 5707 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
99ad26cb 5708 addend, weak_undef_p);
a06ea964 5709 }
b53b1bed
JW
5710 else
5711 {
99ad26cb 5712 bfd_vma addend = 0;
b53b1bed
JW
5713 struct elf_aarch64_local_symbol *locals
5714 = elf_aarch64_locals (input_bfd);
5715
5716 if (locals == NULL)
5717 {
5718 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
4eca0228 5719 _bfd_error_handler
695344c0 5720 /* xgettext:c-format */
90b6238f 5721 (_("%pB: local symbol descriptor table be NULL when applying "
b53b1bed
JW
5722 "relocation %s against local symbol"),
5723 input_bfd, elfNN_aarch64_howto_table[howto_index].name);
5724 abort ();
5725 }
5726
5727 off = symbol_got_offset (input_bfd, h, r_symndx);
5728 base_got = globals->root.sgot;
ff07562f
JW
5729 got_entry_addr = (base_got->output_section->vma
5730 + base_got->output_offset + off);
b53b1bed
JW
5731
5732 if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
5733 {
5734 bfd_put_64 (output_bfd, value, base_got->contents + off);
5735
ff07562f
JW
5736 /* For local symbol, we have done absolute relocation in static
5737 linking stage. While for shared library, we need to update the
5738 content of GOT entry according to the shared object's runtime
5739 base address. So, we need to generate a R_AARCH64_RELATIVE reloc
5740 for dynamic linker. */
0e1862bb 5741 if (bfd_link_pic (info))
ff07562f 5742 relative_reloc = TRUE;
b53b1bed
JW
5743
5744 symbol_got_offset_mark (input_bfd, h, r_symndx);
5745 }
5746
5747 /* Update the relocation value to GOT entry addr as we have transformed
5748 the direct data access into indirect data access through GOT. */
5749 value = got_entry_addr;
99ad26cb 5750
2aff25ba 5751 if (aarch64_relocation_aginst_gp_p (bfd_r_type))
99ad26cb
JW
5752 addend = base_got->output_section->vma + base_got->output_offset;
5753
5754 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5755 addend, weak_undef_p);
b53b1bed 5756 }
ff07562f
JW
5757
5758 if (relative_reloc)
5759 {
5760 asection *s;
5761 Elf_Internal_Rela outrel;
5762
5763 s = globals->root.srelgot;
5764 if (s == NULL)
5765 abort ();
5766
5767 outrel.r_offset = got_entry_addr;
5768 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
5769 outrel.r_addend = orig_value;
5770 elf_append_rela (output_bfd, s, &outrel);
5771 }
a2e1db00
RL
5772 break;
5773
ce336788 5774 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
a6bb11b2 5775 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3c12b054 5776 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
a6bb11b2 5777 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
a6bb11b2 5778 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
ce336788 5779 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
043bf05a 5780 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
73f925cc 5781 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
f69e4920 5782 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
77a69ff8 5783 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
a06ea964
NC
5784 if (globals->root.sgot == NULL)
5785 return bfd_reloc_notsupported;
5786
5787 value = (symbol_got_offset (input_bfd, h, r_symndx)
5788 + globals->root.sgot->output_section->vma
f44a1f8e 5789 + globals->root.sgot->output_offset);
a06ea964 5790
caed7120
YZ
5791 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5792 0, weak_undef_p);
a06ea964
NC
5793 *unresolved_reloc_p = FALSE;
5794 break;
5795
7ba7cfe4 5796 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
94facae3 5797 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
3b957e5b
RL
5798 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
5799 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
94facae3
RL
5800 if (globals->root.sgot == NULL)
5801 return bfd_reloc_notsupported;
5802
5803 value = symbol_got_offset (input_bfd, h, r_symndx);
5804 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5805 0, weak_undef_p);
5806 *unresolved_reloc_p = FALSE;
5807 break;
5808
6ffe9a1b 5809 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12:
40fbed84 5810 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12:
753999c1 5811 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
07c9aa07
JW
5812 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12:
5813 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC:
5814 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12:
5815 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC:
5816 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12:
5817 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC:
5818 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12:
5819 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC:
6ffe9a1b
JW
5820 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0:
5821 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
5822 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1:
5823 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC:
5824 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2:
40fbed84
JW
5825 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5826 signed_addend - dtpoff_base (info),
5827 weak_undef_p);
5828 break;
5829
a6bb11b2
YZ
5830 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
5831 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
5832 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
5833 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
5834 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
5835 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
5836 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
5837 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
caed7120
YZ
5838 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5839 signed_addend - tpoff_base (info),
5840 weak_undef_p);
a06ea964
NC
5841 *unresolved_reloc_p = FALSE;
5842 break;
5843
f955cccf 5844 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
a6bb11b2 5845 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
389b8029 5846 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
a6bb11b2 5847 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
f955cccf 5848 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
1ada945d 5849 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
a06ea964
NC
5850 if (globals->root.sgot == NULL)
5851 return bfd_reloc_notsupported;
a06ea964
NC
5852 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
5853 + globals->root.sgotplt->output_section->vma
f44a1f8e 5854 + globals->root.sgotplt->output_offset
a06ea964
NC
5855 + globals->sgotplt_jump_table_size);
5856
caed7120
YZ
5857 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5858 0, weak_undef_p);
a06ea964
NC
5859 *unresolved_reloc_p = FALSE;
5860 break;
5861
0484b454
RL
5862 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
5863 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
5864 if (globals->root.sgot == NULL)
5865 return bfd_reloc_notsupported;
5866
5867 value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
5868 + globals->root.sgotplt->output_section->vma
5869 + globals->root.sgotplt->output_offset
5870 + globals->sgotplt_jump_table_size);
5871
5872 value -= (globals->root.sgot->output_section->vma
5873 + globals->root.sgot->output_offset);
5874
5875 value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
5876 0, weak_undef_p);
5877 *unresolved_reloc_p = FALSE;
5878 break;
5879
a06ea964
NC
5880 default:
5881 return bfd_reloc_notsupported;
5882 }
5883
5884 if (saved_addend)
5885 *saved_addend = value;
5886
5887 /* Only apply the final relocation in a sequence. */
5888 if (save_addend)
5889 return bfd_reloc_continue;
5890
caed7120
YZ
5891 return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
5892 howto, value);
a06ea964
NC
5893}
5894
2d0ca824
YN
5895/* LP64 and ILP32 operates on x- and w-registers respectively.
5896 Next definitions take into account the difference between
5897 corresponding machine codes. R means x-register if the target
5898 arch is LP64, and w-register if the target is ILP32. */
5899
5900#if ARCH_SIZE == 64
5901# define add_R0_R0 (0x91000000)
5902# define add_R0_R0_R1 (0x8b000020)
5903# define add_R0_R1 (0x91400020)
5904# define ldr_R0 (0x58000000)
5905# define ldr_R0_mask(i) (i & 0xffffffe0)
5906# define ldr_R0_x0 (0xf9400000)
5907# define ldr_hw_R0 (0xf2a00000)
5908# define movk_R0 (0xf2800000)
5909# define movz_R0 (0xd2a00000)
5910# define movz_hw_R0 (0xd2c00000)
5911#else /*ARCH_SIZE == 32 */
5912# define add_R0_R0 (0x11000000)
5913# define add_R0_R0_R1 (0x0b000020)
5914# define add_R0_R1 (0x11400020)
5915# define ldr_R0 (0x18000000)
5916# define ldr_R0_mask(i) (i & 0xbfffffe0)
5917# define ldr_R0_x0 (0xb9400000)
5918# define ldr_hw_R0 (0x72a00000)
5919# define movk_R0 (0x72800000)
5920# define movz_R0 (0x52a00000)
5921# define movz_hw_R0 (0x52c00000)
5922#endif
5923
a06ea964
NC
5924/* Handle TLS relaxations. Relaxing is possible for symbols that use
5925 R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
5926 link.
5927
5928 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
5929 is to then call final_link_relocate. Return other values in the
5930 case of error. */
5931
5932static bfd_reloc_status_type
cec5225b 5933elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
a06ea964 5934 bfd *input_bfd, bfd_byte *contents,
06d2788c 5935 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h)
a06ea964
NC
5936{
5937 bfd_boolean is_local = h == NULL;
cec5225b 5938 unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
a06ea964
NC
5939 unsigned long insn;
5940
5941 BFD_ASSERT (globals && input_bfd && contents && rel);
5942
0aa13fee 5943 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type))
a06ea964 5944 {
a6bb11b2 5945 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
ce336788 5946 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
a06ea964
NC
5947 if (is_local)
5948 {
5949 /* GD->LE relaxation:
2d0ca824 5950 adrp x0, :tlsgd:var => movz R0, :tprel_g1:var
a06ea964 5951 or
2d0ca824
YN
5952 adrp x0, :tlsdesc:var => movz R0, :tprel_g1:var
5953
5954 Where R is x for LP64, and w for ILP32. */
5955 bfd_putl32 (movz_R0, contents + rel->r_offset);
a06ea964
NC
5956 return bfd_reloc_continue;
5957 }
5958 else
5959 {
5960 /* GD->IE relaxation:
5961 adrp x0, :tlsgd:var => adrp x0, :gottprel:var
5962 or
5963 adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
5964 */
a06ea964
NC
5965 return bfd_reloc_continue;
5966 }
5967
389b8029
MS
5968 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
5969 BFD_ASSERT (0);
5970 break;
5971
1ada945d
MS
5972 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
5973 if (is_local)
5974 {
5975 /* Tiny TLSDESC->LE relaxation:
07d6d2b8
AM
5976 ldr x1, :tlsdesc:var => movz R0, #:tprel_g1:var
5977 adr x0, :tlsdesc:var => movk R0, #:tprel_g0_nc:var
1ada945d 5978 .tlsdesccall var
07d6d2b8 5979 blr x1 => nop
2d0ca824
YN
5980
5981 Where R is x for LP64, and w for ILP32. */
1ada945d
MS
5982 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
5983 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
5984
5985 rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
5986 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
5987 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
5988
2d0ca824
YN
5989 bfd_putl32 (movz_R0, contents + rel->r_offset);
5990 bfd_putl32 (movk_R0, contents + rel->r_offset + 4);
1ada945d
MS
5991 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
5992 return bfd_reloc_continue;
5993 }
5994 else
5995 {
5996 /* Tiny TLSDESC->IE relaxation:
07d6d2b8
AM
5997 ldr x1, :tlsdesc:var => ldr x0, :gottprel:var
5998 adr x0, :tlsdesc:var => nop
1ada945d 5999 .tlsdesccall var
07d6d2b8 6000 blr x1 => nop
1ada945d
MS
6001 */
6002 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
6003 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
6004
6005 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6006 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6007
2d0ca824 6008 bfd_putl32 (ldr_R0, contents + rel->r_offset);
1ada945d
MS
6009 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
6010 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
6011 return bfd_reloc_continue;
6012 }
6013
3c12b054
MS
6014 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
6015 if (is_local)
6016 {
6017 /* Tiny GD->LE relaxation:
07d6d2b8
AM
6018 adr x0, :tlsgd:var => mrs x1, tpidr_el0
6019 bl __tls_get_addr => add R0, R1, #:tprel_hi12:x, lsl #12
6020 nop => add R0, R0, #:tprel_lo12_nc:x
2d0ca824
YN
6021
6022 Where R is x for LP64, and x for Ilp32. */
3c12b054
MS
6023
6024 /* First kill the tls_get_addr reloc on the bl instruction. */
6025 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6026
6027 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 0);
2d0ca824
YN
6028 bfd_putl32 (add_R0_R1, contents + rel->r_offset + 4);
6029 bfd_putl32 (add_R0_R0, contents + rel->r_offset + 8);
3c12b054
MS
6030
6031 rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6032 AARCH64_R (TLSLE_ADD_TPREL_LO12_NC));
6033 rel[1].r_offset = rel->r_offset + 8;
6034
6035 /* Move the current relocation to the second instruction in
6036 the sequence. */
6037 rel->r_offset += 4;
6038 rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6039 AARCH64_R (TLSLE_ADD_TPREL_HI12));
6040 return bfd_reloc_continue;
6041 }
6042 else
6043 {
6044 /* Tiny GD->IE relaxation:
07d6d2b8
AM
6045 adr x0, :tlsgd:var => ldr R0, :gottprel:var
6046 bl __tls_get_addr => mrs x1, tpidr_el0
6047 nop => add R0, R0, R1
2d0ca824
YN
6048
6049 Where R is x for LP64, and w for Ilp32. */
3c12b054
MS
6050
6051 /* First kill the tls_get_addr reloc on the bl instruction. */
6052 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6053 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6054
2d0ca824 6055 bfd_putl32 (ldr_R0, contents + rel->r_offset);
3c12b054 6056 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
2d0ca824 6057 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 8);
3c12b054
MS
6058 return bfd_reloc_continue;
6059 }
6060
ac734732
RL
6061#if ARCH_SIZE == 64
6062 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
6063 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSGD_MOVW_G0_NC));
6064 BFD_ASSERT (rel->r_offset + 12 == rel[2].r_offset);
6065 BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (CALL26));
6066
6067 if (is_local)
6068 {
6069 /* Large GD->LE relaxation:
07d6d2b8 6070 movz x0, #:tlsgd_g1:var => movz x0, #:tprel_g2:var, lsl #32
ac734732 6071 movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
07d6d2b8
AM
6072 add x0, gp, x0 => movk x0, #:tprel_g0_nc:var
6073 bl __tls_get_addr => mrs x1, tpidr_el0
6074 nop => add x0, x0, x1
ac734732
RL
6075 */
6076 rel[2].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
6077 AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
6078 rel[2].r_offset = rel->r_offset + 8;
6079
2d0ca824
YN
6080 bfd_putl32 (movz_hw_R0, contents + rel->r_offset + 0);
6081 bfd_putl32 (ldr_hw_R0, contents + rel->r_offset + 4);
6082 bfd_putl32 (movk_R0, contents + rel->r_offset + 8);
ac734732 6083 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
2d0ca824 6084 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 16);
ac734732
RL
6085 }
6086 else
6087 {
6088 /* Large GD->IE relaxation:
07d6d2b8 6089 movz x0, #:tlsgd_g1:var => movz x0, #:gottprel_g1:var, lsl #16
ac734732 6090 movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
07d6d2b8
AM
6091 add x0, gp, x0 => ldr x0, [gp, x0]
6092 bl __tls_get_addr => mrs x1, tpidr_el0
6093 nop => add x0, x0, x1
ac734732
RL
6094 */
6095 rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6096 bfd_putl32 (0xd2a80000, contents + rel->r_offset + 0);
2d0ca824 6097 bfd_putl32 (ldr_R0, contents + rel->r_offset + 8);
ac734732 6098 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
2d0ca824 6099 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 16);
ac734732
RL
6100 }
6101 return bfd_reloc_continue;
6102
6103 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
6104 return bfd_reloc_continue;
6105#endif
6106
043bf05a
MS
6107 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
6108 return bfd_reloc_continue;
6109
a6bb11b2 6110 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
a06ea964
NC
6111 if (is_local)
6112 {
6113 /* GD->LE relaxation:
6114 ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
2d0ca824
YN
6115
6116 Where R is x for lp64 mode, and w for ILP32 mode. */
6117 bfd_putl32 (movk_R0, contents + rel->r_offset);
a06ea964
NC
6118 return bfd_reloc_continue;
6119 }
6120 else
6121 {
6122 /* GD->IE relaxation:
2d0ca824
YN
6123 ldr xd, [x0, #:tlsdesc_lo12:var] => ldr R0, [x0, #:gottprel_lo12:var]
6124
6125 Where R is x for lp64 mode, and w for ILP32 mode. */
a06ea964 6126 insn = bfd_getl32 (contents + rel->r_offset);
2d0ca824 6127 bfd_putl32 (ldr_R0_mask (insn), contents + rel->r_offset);
a06ea964
NC
6128 return bfd_reloc_continue;
6129 }
6130
a6bb11b2 6131 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
a06ea964
NC
6132 if (is_local)
6133 {
6134 /* GD->LE relaxation
07d6d2b8
AM
6135 add x0, #:tlsgd_lo12:var => movk R0, :tprel_g0_nc:var
6136 bl __tls_get_addr => mrs x1, tpidr_el0
6137 nop => add R0, R1, R0
2d0ca824
YN
6138
6139 Where R is x for lp64 mode, and w for ILP32 mode. */
a06ea964
NC
6140
6141 /* First kill the tls_get_addr reloc on the bl instruction. */
6142 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
cec5225b 6143 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
a06ea964 6144
2d0ca824 6145 bfd_putl32 (movk_R0, contents + rel->r_offset);
a06ea964 6146 bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
2d0ca824 6147 bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 8);
a06ea964
NC
6148 return bfd_reloc_continue;
6149 }
6150 else
6151 {
6152 /* GD->IE relaxation
07d6d2b8
AM
6153 ADD x0, #:tlsgd_lo12:var => ldr R0, [x0, #:gottprel_lo12:var]
6154 BL __tls_get_addr => mrs x1, tpidr_el0
a06ea964 6155 R_AARCH64_CALL26
07d6d2b8 6156 NOP => add R0, R1, R0
5cd1d8bc
YN
6157
6158 Where R is x for lp64 mode, and w for ilp32 mode. */
a06ea964 6159
a6bb11b2 6160 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
a06ea964
NC
6161
6162 /* Remove the relocation on the BL instruction. */
cec5225b 6163 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
a06ea964 6164
a06ea964
NC
6165 /* We choose to fixup the BL and NOP instructions using the
6166 offset from the second relocation to allow flexibility in
6167 scheduling instructions between the ADD and BL. */
2d0ca824 6168 bfd_putl32 (ldr_R0_x0, contents + rel->r_offset);
5cd1d8bc 6169 bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
2d0ca824 6170 bfd_putl32 (add_R0_R0_R1, contents + rel[1].r_offset + 4);
a06ea964
NC
6171 return bfd_reloc_continue;
6172 }
6173
0484b454 6174 case BFD_RELOC_AARCH64_TLSDESC_ADD:
f955cccf 6175 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
a6bb11b2 6176 case BFD_RELOC_AARCH64_TLSDESC_CALL:
a06ea964 6177 /* GD->IE/LE relaxation:
07d6d2b8
AM
6178 add x0, x0, #:tlsdesc_lo12:var => nop
6179 blr xd => nop
a06ea964
NC
6180 */
6181 bfd_putl32 (INSN_NOP, contents + rel->r_offset);
6182 return bfd_reloc_ok;
6183
0484b454
RL
6184 case BFD_RELOC_AARCH64_TLSDESC_LDR:
6185 if (is_local)
6186 {
6187 /* GD->LE relaxation:
2d0ca824
YN
6188 ldr xd, [gp, xn] => movk R0, #:tprel_g0_nc:var
6189
6190 Where R is x for lp64 mode, and w for ILP32 mode. */
6191 bfd_putl32 (movk_R0, contents + rel->r_offset);
0484b454
RL
6192 return bfd_reloc_continue;
6193 }
6194 else
6195 {
6196 /* GD->IE relaxation:
2d0ca824
YN
6197 ldr xd, [gp, xn] => ldr R0, [gp, xn]
6198
6199 Where R is x for lp64 mode, and w for ILP32 mode. */
0484b454 6200 insn = bfd_getl32 (contents + rel->r_offset);
2d0ca824 6201 bfd_putl32 (ldr_R0_mask (insn), contents + rel->r_offset);
0484b454
RL
6202 return bfd_reloc_ok;
6203 }
6204
6205 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
6206 /* GD->LE relaxation:
2d0ca824 6207 movk xd, #:tlsdesc_off_g0_nc:var => movk R0, #:tprel_g1_nc:var, lsl #16
0484b454 6208 GD->IE relaxation:
2d0ca824
YN
6209 movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
6210
6211 Where R is x for lp64 mode, and w for ILP32 mode. */
0484b454 6212 if (is_local)
2d0ca824 6213 bfd_putl32 (ldr_hw_R0, contents + rel->r_offset);
0484b454
RL
6214 return bfd_reloc_continue;
6215
6216 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
6217 if (is_local)
6218 {
6219 /* GD->LE relaxation:
2d0ca824
YN
6220 movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
6221
6222 Where R is x for lp64 mode, and w for ILP32 mode. */
6223 bfd_putl32 (movz_hw_R0, contents + rel->r_offset);
0484b454
RL
6224 return bfd_reloc_continue;
6225 }
6226 else
6227 {
6228 /* GD->IE relaxation:
2d0ca824
YN
6229 movz xd, #:tlsdesc_off_g1:var => movz Rd, #:gottprel_g1:var, lsl #16
6230
6231 Where R is x for lp64 mode, and w for ILP32 mode. */
0484b454 6232 insn = bfd_getl32 (contents + rel->r_offset);
2d0ca824 6233 bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
0484b454
RL
6234 return bfd_reloc_continue;
6235 }
6236
a6bb11b2 6237 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
a06ea964 6238 /* IE->LE relaxation:
07d6d2b8 6239 adrp xd, :gottprel:var => movz Rd, :tprel_g1:var
2d0ca824
YN
6240
6241 Where R is x for lp64 mode, and w for ILP32 mode. */
a06ea964
NC
6242 if (is_local)
6243 {
6244 insn = bfd_getl32 (contents + rel->r_offset);
2d0ca824 6245 bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
a06ea964
NC
6246 }
6247 return bfd_reloc_continue;
6248
a6bb11b2 6249 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
a06ea964 6250 /* IE->LE relaxation:
07d6d2b8 6251 ldr xd, [xm, #:gottprel_lo12:var] => movk Rd, :tprel_g0_nc:var
2d0ca824
YN
6252
6253 Where R is x for lp64 mode, and w for ILP32 mode. */
a06ea964
NC
6254 if (is_local)
6255 {
6256 insn = bfd_getl32 (contents + rel->r_offset);
2d0ca824 6257 bfd_putl32 (movk_R0 | (insn & 0x1f), contents + rel->r_offset);
a06ea964
NC
6258 }
6259 return bfd_reloc_continue;
6260
259364ad
JW
6261 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
6262 /* LD->LE relaxation (tiny):
6263 adr x0, :tlsldm:x => mrs x0, tpidr_el0
c1fc2d7e
YN
6264 bl __tls_get_addr => add R0, R0, TCB_SIZE
6265
6266 Where R is x for lp64 mode, and w for ilp32 mode. */
259364ad
JW
6267 if (is_local)
6268 {
6269 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6270 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
6271 /* No need of CALL26 relocation for tls_get_addr. */
6272 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
6273 bfd_putl32 (0xd53bd040, contents + rel->r_offset + 0);
2d0ca824
YN
6274 bfd_putl32 (add_R0_R0 | (TCB_SIZE << 10),
6275 contents + rel->r_offset + 4);
259364ad
JW
6276 return bfd_reloc_ok;
6277 }
6278 return bfd_reloc_continue;
6279
6280 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
6281 /* LD->LE relaxation (small):
6282 adrp x0, :tlsldm:x => mrs x0, tpidr_el0
6283 */
6284 if (is_local)
6285 {
6286 bfd_putl32 (0xd53bd040, contents + rel->r_offset);
6287 return bfd_reloc_ok;
6288 }
6289 return bfd_reloc_continue;
6290
6291 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
6292 /* LD->LE relaxation (small):
c1fc2d7e 6293 add x0, #:tlsldm_lo12:x => add R0, R0, TCB_SIZE
259364ad 6294 bl __tls_get_addr => nop
c1fc2d7e
YN
6295
6296 Where R is x for lp64 mode, and w for ilp32 mode. */
259364ad
JW
6297 if (is_local)
6298 {
6299 BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
6300 BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
6301 /* No need of CALL26 relocation for tls_get_addr. */
6302 rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
2d0ca824
YN
6303 bfd_putl32 (add_R0_R0 | (TCB_SIZE << 10),
6304 contents + rel->r_offset + 0);
c1fc2d7e 6305 bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
259364ad
JW
6306 return bfd_reloc_ok;
6307 }
6308 return bfd_reloc_continue;
6309
a06ea964
NC
6310 default:
6311 return bfd_reloc_continue;
6312 }
6313
6314 return bfd_reloc_ok;
6315}
6316
6317/* Relocate an AArch64 ELF section. */
6318
6319static bfd_boolean
cec5225b 6320elfNN_aarch64_relocate_section (bfd *output_bfd,
a06ea964
NC
6321 struct bfd_link_info *info,
6322 bfd *input_bfd,
6323 asection *input_section,
6324 bfd_byte *contents,
6325 Elf_Internal_Rela *relocs,
6326 Elf_Internal_Sym *local_syms,
6327 asection **local_sections)
6328{
6329 Elf_Internal_Shdr *symtab_hdr;
6330 struct elf_link_hash_entry **sym_hashes;
6331 Elf_Internal_Rela *rel;
6332 Elf_Internal_Rela *relend;
6333 const char *name;
cec5225b 6334 struct elf_aarch64_link_hash_table *globals;
a06ea964
NC
6335 bfd_boolean save_addend = FALSE;
6336 bfd_vma addend = 0;
6337
cec5225b 6338 globals = elf_aarch64_hash_table (info);
a06ea964
NC
6339
6340 symtab_hdr = &elf_symtab_hdr (input_bfd);
6341 sym_hashes = elf_sym_hashes (input_bfd);
6342
6343 rel = relocs;
6344 relend = relocs + input_section->reloc_count;
6345 for (; rel < relend; rel++)
6346 {
6347 unsigned int r_type;
a6bb11b2
YZ
6348 bfd_reloc_code_real_type bfd_r_type;
6349 bfd_reloc_code_real_type relaxed_bfd_r_type;
a06ea964
NC
6350 reloc_howto_type *howto;
6351 unsigned long r_symndx;
6352 Elf_Internal_Sym *sym;
6353 asection *sec;
6354 struct elf_link_hash_entry *h;
6355 bfd_vma relocation;
6356 bfd_reloc_status_type r;
6357 arelent bfd_reloc;
6358 char sym_type;
6359 bfd_boolean unresolved_reloc = FALSE;
6360 char *error_message = NULL;
6361
cec5225b
YZ
6362 r_symndx = ELFNN_R_SYM (rel->r_info);
6363 r_type = ELFNN_R_TYPE (rel->r_info);
a06ea964 6364
0aa13fee
AM
6365 bfd_reloc.howto = elfNN_aarch64_howto_from_type (input_bfd, r_type);
6366 howto = bfd_reloc.howto;
a06ea964 6367
7fcfd62d 6368 if (howto == NULL)
47aeb64c
NC
6369 return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
6370
a6bb11b2 6371 bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
7fcfd62d 6372
a06ea964
NC
6373 h = NULL;
6374 sym = NULL;
6375 sec = NULL;
6376
6377 if (r_symndx < symtab_hdr->sh_info)
6378 {
6379 sym = local_syms + r_symndx;
cec5225b 6380 sym_type = ELFNN_ST_TYPE (sym->st_info);
a06ea964
NC
6381 sec = local_sections[r_symndx];
6382
6383 /* An object file might have a reference to a local
6384 undefined symbol. This is a daft object file, but we
6385 should at least do something about it. */
6386 if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
6387 && bfd_is_und_section (sec)
6388 && ELF_ST_BIND (sym->st_info) != STB_WEAK)
1a72702b
AM
6389 (*info->callbacks->undefined_symbol)
6390 (info, bfd_elf_string_from_elf_section
6391 (input_bfd, symtab_hdr->sh_link, sym->st_name),
6392 input_bfd, input_section, rel->r_offset, TRUE);
a06ea964 6393
a06ea964 6394 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1419bbe5
WN
6395
6396 /* Relocate against local STT_GNU_IFUNC symbol. */
0e1862bb 6397 if (!bfd_link_relocatable (info)
1419bbe5
WN
6398 && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
6399 {
6400 h = elfNN_aarch64_get_local_sym_hash (globals, input_bfd,
6401 rel, FALSE);
6402 if (h == NULL)
6403 abort ();
6404
6405 /* Set STT_GNU_IFUNC symbol value. */
6406 h->root.u.def.value = sym->st_value;
6407 h->root.u.def.section = sec;
6408 }
a06ea964
NC
6409 }
6410 else
6411 {
62d887d4 6412 bfd_boolean warned, ignored;
a06ea964
NC
6413
6414 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
6415 r_symndx, symtab_hdr, sym_hashes,
6416 h, sec, relocation,
62d887d4 6417 unresolved_reloc, warned, ignored);
a06ea964
NC
6418
6419 sym_type = h->type;
6420 }
6421
6422 if (sec != NULL && discarded_section (sec))
6423 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
6424 rel, 1, relend, howto, 0, contents);
6425
0e1862bb 6426 if (bfd_link_relocatable (info))
2e0488d3 6427 continue;
a06ea964
NC
6428
6429 if (h != NULL)
6430 name = h->root.root.string;
6431 else
6432 {
6433 name = (bfd_elf_string_from_elf_section
6434 (input_bfd, symtab_hdr->sh_link, sym->st_name));
6435 if (name == NULL || *name == '\0')
6436 name = bfd_section_name (input_bfd, sec);
6437 }
6438
6439 if (r_symndx != 0
6440 && r_type != R_AARCH64_NONE
6441 && r_type != R_AARCH64_NULL
6442 && (h == NULL
6443 || h->root.type == bfd_link_hash_defined
6444 || h->root.type == bfd_link_hash_defweak)
a6bb11b2 6445 && IS_AARCH64_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
a06ea964 6446 {
4eca0228 6447 _bfd_error_handler
a06ea964 6448 ((sym_type == STT_TLS
695344c0 6449 /* xgettext:c-format */
2dcf00ce 6450 ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
695344c0 6451 /* xgettext:c-format */
2dcf00ce 6452 : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
a06ea964 6453 input_bfd,
2dcf00ce 6454 input_section, (uint64_t) rel->r_offset, howto->name, name);
a06ea964
NC
6455 }
6456
a06ea964 6457 /* We relax only if we can see that there can be a valid transition
07d6d2b8
AM
6458 from a reloc type to another.
6459 We call elfNN_aarch64_final_link_relocate unless we're completely
6460 done, i.e., the relaxation produced the final output we want. */
a06ea964 6461
a6bb11b2
YZ
6462 relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
6463 h, r_symndx);
6464 if (relaxed_bfd_r_type != bfd_r_type)
a06ea964 6465 {
a6bb11b2
YZ
6466 bfd_r_type = relaxed_bfd_r_type;
6467 howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
6468 BFD_ASSERT (howto != NULL);
6469 r_type = howto->type;
06d2788c 6470 r = elfNN_aarch64_tls_relax (globals, input_bfd, contents, rel, h);
a06ea964
NC
6471 unresolved_reloc = 0;
6472 }
6473 else
6474 r = bfd_reloc_continue;
6475
6476 /* There may be multiple consecutive relocations for the
07d6d2b8
AM
6477 same offset. In that case we are supposed to treat the
6478 output of each relocation as the addend for the next. */
a06ea964
NC
6479 if (rel + 1 < relend
6480 && rel->r_offset == rel[1].r_offset
cec5225b
YZ
6481 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NONE
6482 && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NULL)
a06ea964
NC
6483 save_addend = TRUE;
6484 else
6485 save_addend = FALSE;
6486
6487 if (r == bfd_reloc_continue)
cec5225b 6488 r = elfNN_aarch64_final_link_relocate (howto, input_bfd, output_bfd,
a06ea964
NC
6489 input_section, contents, rel,
6490 relocation, info, sec,
6491 h, &unresolved_reloc,
1419bbe5 6492 save_addend, &addend, sym);
a06ea964 6493
0aa13fee 6494 switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type))
a06ea964 6495 {
ce336788 6496 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
a6bb11b2 6497 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3c12b054 6498 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
7ba7cfe4 6499 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
94facae3 6500 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
73f925cc 6501 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
f69e4920 6502 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
77a69ff8 6503 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
a06ea964
NC
6504 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
6505 {
6506 bfd_boolean need_relocs = FALSE;
6507 bfd_byte *loc;
6508 int indx;
6509 bfd_vma off;
6510
6511 off = symbol_got_offset (input_bfd, h, r_symndx);
6512 indx = h && h->dynindx != -1 ? h->dynindx : 0;
6513
6514 need_relocs =
6dda7875 6515 (!bfd_link_executable (info) || indx != 0) &&
a06ea964
NC
6516 (h == NULL
6517 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
6518 || h->root.type != bfd_link_hash_undefweak);
6519
6520 BFD_ASSERT (globals->root.srelgot != NULL);
6521
6522 if (need_relocs)
6523 {
6524 Elf_Internal_Rela rela;
a6bb11b2 6525 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPMOD));
a06ea964
NC
6526 rela.r_addend = 0;
6527 rela.r_offset = globals->root.sgot->output_section->vma +
6528 globals->root.sgot->output_offset + off;
6529
6530
6531 loc = globals->root.srelgot->contents;
6532 loc += globals->root.srelgot->reloc_count++
6533 * RELOC_SIZE (htab);
cec5225b 6534 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
a06ea964 6535
f69e4920 6536 bfd_reloc_code_real_type real_type =
0aa13fee 6537 elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
f69e4920
JW
6538
6539 if (real_type == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
73f925cc
JW
6540 || real_type == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
6541 || real_type == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC)
77a69ff8
JW
6542 {
6543 /* For local dynamic, don't generate DTPREL in any case.
6544 Initialize the DTPREL slot into zero, so we get module
6545 base address when invoke runtime TLS resolver. */
6546 bfd_put_NN (output_bfd, 0,
6547 globals->root.sgot->contents + off
6548 + GOT_ENTRY_SIZE);
6549 }
6550 else if (indx == 0)
a06ea964 6551 {
cec5225b 6552 bfd_put_NN (output_bfd,
a06ea964
NC
6553 relocation - dtpoff_base (info),
6554 globals->root.sgot->contents + off
6555 + GOT_ENTRY_SIZE);
6556 }
6557 else
6558 {
6559 /* This TLS symbol is global. We emit a
6560 relocation to fixup the tls offset at load
6561 time. */
6562 rela.r_info =
a6bb11b2 6563 ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPREL));
a06ea964
NC
6564 rela.r_addend = 0;
6565 rela.r_offset =
6566 (globals->root.sgot->output_section->vma
6567 + globals->root.sgot->output_offset + off
6568 + GOT_ENTRY_SIZE);
6569
6570 loc = globals->root.srelgot->contents;
6571 loc += globals->root.srelgot->reloc_count++
6572 * RELOC_SIZE (globals);
cec5225b
YZ
6573 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
6574 bfd_put_NN (output_bfd, (bfd_vma) 0,
a06ea964
NC
6575 globals->root.sgot->contents + off
6576 + GOT_ENTRY_SIZE);
6577 }
6578 }
6579 else
6580 {
cec5225b 6581 bfd_put_NN (output_bfd, (bfd_vma) 1,
a06ea964 6582 globals->root.sgot->contents + off);
cec5225b 6583 bfd_put_NN (output_bfd,
a06ea964
NC
6584 relocation - dtpoff_base (info),
6585 globals->root.sgot->contents + off
6586 + GOT_ENTRY_SIZE);
6587 }
6588
6589 symbol_got_offset_mark (input_bfd, h, r_symndx);
6590 }
6591 break;
6592
a6bb11b2
YZ
6593 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
6594 case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
043bf05a 6595 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
3b957e5b
RL
6596 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
6597 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
a06ea964
NC
6598 if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
6599 {
6600 bfd_boolean need_relocs = FALSE;
6601 bfd_byte *loc;
6602 int indx;
6603 bfd_vma off;
6604
6605 off = symbol_got_offset (input_bfd, h, r_symndx);
6606
6607 indx = h && h->dynindx != -1 ? h->dynindx : 0;
6608
6609 need_relocs =
6dda7875 6610 (!bfd_link_executable (info) || indx != 0) &&
a06ea964
NC
6611 (h == NULL
6612 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
6613 || h->root.type != bfd_link_hash_undefweak);
6614
6615 BFD_ASSERT (globals->root.srelgot != NULL);
6616
6617 if (need_relocs)
6618 {
6619 Elf_Internal_Rela rela;
6620
6621 if (indx == 0)
6622 rela.r_addend = relocation - dtpoff_base (info);
6623 else
6624 rela.r_addend = 0;
6625
a6bb11b2 6626 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_TPREL));
a06ea964
NC
6627 rela.r_offset = globals->root.sgot->output_section->vma +
6628 globals->root.sgot->output_offset + off;
6629
6630 loc = globals->root.srelgot->contents;
6631 loc += globals->root.srelgot->reloc_count++
6632 * RELOC_SIZE (htab);
6633
cec5225b 6634 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
a06ea964 6635
cec5225b 6636 bfd_put_NN (output_bfd, rela.r_addend,
a06ea964
NC
6637 globals->root.sgot->contents + off);
6638 }
6639 else
cec5225b 6640 bfd_put_NN (output_bfd, relocation - tpoff_base (info),
a06ea964
NC
6641 globals->root.sgot->contents + off);
6642
6643 symbol_got_offset_mark (input_bfd, h, r_symndx);
6644 }
6645 break;
6646
f955cccf 6647 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
a6bb11b2 6648 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
389b8029 6649 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
a6bb11b2 6650 case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
1ada945d 6651 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
0484b454
RL
6652 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
6653 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
a06ea964
NC
6654 if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
6655 {
6656 bfd_boolean need_relocs = FALSE;
6657 int indx = h && h->dynindx != -1 ? h->dynindx : 0;
6658 bfd_vma off = symbol_tlsdesc_got_offset (input_bfd, h, r_symndx);
6659
6660 need_relocs = (h == NULL
6661 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
6662 || h->root.type != bfd_link_hash_undefweak);
6663
6664 BFD_ASSERT (globals->root.srelgot != NULL);
6665 BFD_ASSERT (globals->root.sgot != NULL);
6666
6667 if (need_relocs)
6668 {
6669 bfd_byte *loc;
6670 Elf_Internal_Rela rela;
a6bb11b2
YZ
6671 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
6672
a06ea964
NC
6673 rela.r_addend = 0;
6674 rela.r_offset = (globals->root.sgotplt->output_section->vma
6675 + globals->root.sgotplt->output_offset
6676 + off + globals->sgotplt_jump_table_size);
6677
6678 if (indx == 0)
6679 rela.r_addend = relocation - dtpoff_base (info);
6680
6681 /* Allocate the next available slot in the PLT reloc
6682 section to hold our R_AARCH64_TLSDESC, the next
6683 available slot is determined from reloc_count,
6684 which we step. But note, reloc_count was
6685 artifically moved down while allocating slots for
6686 real PLT relocs such that all of the PLT relocs
6687 will fit above the initial reloc_count and the
6688 extra stuff will fit below. */
6689 loc = globals->root.srelplt->contents;
6690 loc += globals->root.srelplt->reloc_count++
6691 * RELOC_SIZE (globals);
6692
cec5225b 6693 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
a06ea964 6694
cec5225b 6695 bfd_put_NN (output_bfd, (bfd_vma) 0,
a06ea964
NC
6696 globals->root.sgotplt->contents + off +
6697 globals->sgotplt_jump_table_size);
cec5225b 6698 bfd_put_NN (output_bfd, (bfd_vma) 0,
a06ea964
NC
6699 globals->root.sgotplt->contents + off +
6700 globals->sgotplt_jump_table_size +
6701 GOT_ENTRY_SIZE);
6702 }
6703
6704 symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
6705 }
6706 break;
a6bb11b2
YZ
6707 default:
6708 break;
a06ea964
NC
6709 }
6710
a06ea964 6711 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
07d6d2b8
AM
6712 because such sections are not SEC_ALLOC and thus ld.so will
6713 not process them. */
a06ea964
NC
6714 if (unresolved_reloc
6715 && !((input_section->flags & SEC_DEBUGGING) != 0
6716 && h->def_dynamic)
6717 && _bfd_elf_section_offset (output_bfd, info, input_section,
6718 +rel->r_offset) != (bfd_vma) - 1)
6719 {
4eca0228 6720 _bfd_error_handler
695344c0 6721 /* xgettext:c-format */
2dcf00ce
AM
6722 (_("%pB(%pA+%#" PRIx64 "): "
6723 "unresolvable %s relocation against symbol `%s'"),
6724 input_bfd, input_section, (uint64_t) rel->r_offset, howto->name,
a06ea964
NC
6725 h->root.root.string);
6726 return FALSE;
6727 }
6728
6729 if (r != bfd_reloc_ok && r != bfd_reloc_continue)
6730 {
c674f5cd 6731 bfd_reloc_code_real_type real_r_type
0aa13fee 6732 = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
c674f5cd 6733
a06ea964
NC
6734 switch (r)
6735 {
6736 case bfd_reloc_overflow:
1a72702b
AM
6737 (*info->callbacks->reloc_overflow)
6738 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
6739 input_bfd, input_section, rel->r_offset);
c674f5cd
JW
6740 if (real_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
6741 || real_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
6742 {
6743 (*info->callbacks->warning)
6744 (info,
90b6238f 6745 _("too many GOT entries for -fpic, "
c674f5cd
JW
6746 "please recompile with -fPIC"),
6747 name, input_bfd, input_section, rel->r_offset);
6748 return FALSE;
6749 }
027e9c75
NC
6750 /* Overflow can occur when a variable is referenced with a type
6751 that has a larger alignment than the type with which it was
6752 declared. eg:
6753 file1.c: extern int foo; int a (void) { return foo; }
6754 file2.c: char bar, foo, baz;
6755 If the variable is placed into a data section at an offset
6756 that is incompatible with the larger alignment requirement
6757 overflow will occur. (Strictly speaking this is not overflow
6758 but rather an alignment problem, but the bfd_reloc_ error
6759 enum does not have a value to cover that situation).
6760
6761 Try to catch this situation here and provide a more helpful
6762 error message to the user. */
6763 if (addend & ((1 << howto->rightshift) - 1)
6764 /* FIXME: Are we testing all of the appropriate reloc
6765 types here ? */
6766 && (real_r_type == BFD_RELOC_AARCH64_LD_LO19_PCREL
6767 || real_r_type == BFD_RELOC_AARCH64_LDST16_LO12
6768 || real_r_type == BFD_RELOC_AARCH64_LDST32_LO12
6769 || real_r_type == BFD_RELOC_AARCH64_LDST64_LO12
6770 || real_r_type == BFD_RELOC_AARCH64_LDST128_LO12))
6771 {
6772 info->callbacks->warning
90b6238f 6773 (info, _("one possible cause of this error is that the \
027e9c75 6774symbol is being referenced in the indicated code as if it had a larger \
90b6238f 6775alignment than was declared where it was defined"),
027e9c75
NC
6776 name, input_bfd, input_section, rel->r_offset);
6777 }
a06ea964
NC
6778 break;
6779
6780 case bfd_reloc_undefined:
1a72702b
AM
6781 (*info->callbacks->undefined_symbol)
6782 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
a06ea964
NC
6783 break;
6784
6785 case bfd_reloc_outofrange:
6786 error_message = _("out of range");
6787 goto common_error;
6788
6789 case bfd_reloc_notsupported:
6790 error_message = _("unsupported relocation");
6791 goto common_error;
6792
6793 case bfd_reloc_dangerous:
6794 /* error_message should already be set. */
6795 goto common_error;
6796
6797 default:
6798 error_message = _("unknown error");
6799 /* Fall through. */
6800
6801 common_error:
6802 BFD_ASSERT (error_message != NULL);
1a72702b
AM
6803 (*info->callbacks->reloc_dangerous)
6804 (info, error_message, input_bfd, input_section, rel->r_offset);
a06ea964
NC
6805 break;
6806 }
6807 }
027e9c75
NC
6808
6809 if (!save_addend)
6810 addend = 0;
a06ea964
NC
6811 }
6812
6813 return TRUE;
6814}
6815
6816/* Set the right machine number. */
6817
6818static bfd_boolean
cec5225b 6819elfNN_aarch64_object_p (bfd *abfd)
a06ea964 6820{
cec5225b
YZ
6821#if ARCH_SIZE == 32
6822 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64_ilp32);
6823#else
a06ea964 6824 bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64);
cec5225b 6825#endif
a06ea964
NC
6826 return TRUE;
6827}
6828
6829/* Function to keep AArch64 specific flags in the ELF header. */
6830
6831static bfd_boolean
cec5225b 6832elfNN_aarch64_set_private_flags (bfd *abfd, flagword flags)
a06ea964
NC
6833{
6834 if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
6835 {
6836 }
6837 else
6838 {
6839 elf_elfheader (abfd)->e_flags = flags;
6840 elf_flags_init (abfd) = TRUE;
6841 }
6842
6843 return TRUE;
6844}
6845
a06ea964
NC
6846/* Merge backend specific data from an object file to the output
6847 object file when linking. */
6848
6849static bfd_boolean
50e03d47 6850elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
a06ea964 6851{
50e03d47 6852 bfd *obfd = info->output_bfd;
a06ea964
NC
6853 flagword out_flags;
6854 flagword in_flags;
6855 bfd_boolean flags_compatible = TRUE;
6856 asection *sec;
6857
6858 /* Check if we have the same endianess. */
50e03d47 6859 if (!_bfd_generic_verify_endian_match (ibfd, info))
a06ea964
NC
6860 return FALSE;
6861
6862 if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
6863 return TRUE;
6864
6865 /* The input BFD must have had its flags initialised. */
6866 /* The following seems bogus to me -- The flags are initialized in
6867 the assembler but I don't think an elf_flags_init field is
6868 written into the object. */
6869 /* BFD_ASSERT (elf_flags_init (ibfd)); */
6870
6871 in_flags = elf_elfheader (ibfd)->e_flags;
6872 out_flags = elf_elfheader (obfd)->e_flags;
6873
6874 if (!elf_flags_init (obfd))
6875 {
6876 /* If the input is the default architecture and had the default
07d6d2b8
AM
6877 flags then do not bother setting the flags for the output
6878 architecture, instead allow future merges to do this. If no
6879 future merges ever set these flags then they will retain their
6880 uninitialised values, which surprise surprise, correspond
6881 to the default values. */
a06ea964
NC
6882 if (bfd_get_arch_info (ibfd)->the_default
6883 && elf_elfheader (ibfd)->e_flags == 0)
6884 return TRUE;
6885
6886 elf_flags_init (obfd) = TRUE;
6887 elf_elfheader (obfd)->e_flags = in_flags;
6888
6889 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
6890 && bfd_get_arch_info (obfd)->the_default)
6891 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
6892 bfd_get_mach (ibfd));
6893
6894 return TRUE;
6895 }
6896
6897 /* Identical flags must be compatible. */
6898 if (in_flags == out_flags)
6899 return TRUE;
6900
6901 /* Check to see if the input BFD actually contains any sections. If
6902 not, its flags may not have been initialised either, but it
6903 cannot actually cause any incompatiblity. Do not short-circuit
6904 dynamic objects; their section list may be emptied by
6905 elf_link_add_object_symbols.
6906
6907 Also check to see if there are no code sections in the input.
6908 In this case there is no need to check for code specific flags.
6909 XXX - do we need to worry about floating-point format compatability
6910 in data sections ? */
6911 if (!(ibfd->flags & DYNAMIC))
6912 {
6913 bfd_boolean null_input_bfd = TRUE;
6914 bfd_boolean only_data_sections = TRUE;
6915
6916 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
6917 {
6918 if ((bfd_get_section_flags (ibfd, sec)
6919 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
6920 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
6921 only_data_sections = FALSE;
6922
6923 null_input_bfd = FALSE;
6924 break;
6925 }
6926
6927 if (null_input_bfd || only_data_sections)
6928 return TRUE;
6929 }
6930
6931 return flags_compatible;
6932}
6933
6934/* Display the flags field. */
6935
6936static bfd_boolean
cec5225b 6937elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
a06ea964
NC
6938{
6939 FILE *file = (FILE *) ptr;
6940 unsigned long flags;
6941
6942 BFD_ASSERT (abfd != NULL && ptr != NULL);
6943
6944 /* Print normal ELF private data. */
6945 _bfd_elf_print_private_bfd_data (abfd, ptr);
6946
6947 flags = elf_elfheader (abfd)->e_flags;
6948 /* Ignore init flag - it may not be set, despite the flags field
6949 containing valid data. */
6950
6951 /* xgettext:c-format */
6952 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
6953
6954 if (flags)
6955 fprintf (file, _("<Unrecognised flag bits set>"));
6956
6957 fputc ('\n', file);
6958
6959 return TRUE;
6960}
6961
63c1f59d
AM
6962/* Find dynamic relocs for H that apply to read-only sections. */
6963
6964static asection *
6965readonly_dynrelocs (struct elf_link_hash_entry *h)
6966{
6967 struct elf_dyn_relocs *p;
6968
6969 for (p = elf_aarch64_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
6970 {
6971 asection *s = p->sec->output_section;
6972
6973 if (s != NULL && (s->flags & SEC_READONLY) != 0)
6974 return p->sec;
6975 }
6976 return NULL;
6977}
6978
6353d82b
JW
6979/* Return true if we need copy relocation against EH. */
6980
6981static bfd_boolean
6982need_copy_relocation_p (struct elf_aarch64_link_hash_entry *eh)
6983{
6984 struct elf_dyn_relocs *p;
6985 asection *s;
6986
6987 for (p = eh->dyn_relocs; p != NULL; p = p->next)
6988 {
6989 /* If there is any pc-relative reference, we need to keep copy relocation
6990 to avoid propagating the relocation into runtime that current glibc
6991 does not support. */
6992 if (p->pc_count)
6993 return TRUE;
6994
6995 s = p->sec->output_section;
6996 /* Need copy relocation if it's against read-only section. */
6997 if (s != NULL && (s->flags & SEC_READONLY) != 0)
6998 return TRUE;
6999 }
7000
7001 return FALSE;
7002}
7003
a06ea964
NC
7004/* Adjust a symbol defined by a dynamic object and referenced by a
7005 regular object. The current definition is in some section of the
7006 dynamic object, but we're not including those sections. We have to
7007 change the definition to something the rest of the link can
7008 understand. */
7009
7010static bfd_boolean
cec5225b 7011elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
a06ea964
NC
7012 struct elf_link_hash_entry *h)
7013{
cec5225b 7014 struct elf_aarch64_link_hash_table *htab;
5474d94f 7015 asection *s, *srel;
a06ea964
NC
7016
7017 /* If this is a function, put it in the procedure linkage table. We
7018 will fill in the contents of the procedure linkage table later,
7019 when we know the address of the .got section. */
1419bbe5 7020 if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
a06ea964
NC
7021 {
7022 if (h->plt.refcount <= 0
1419bbe5
WN
7023 || (h->type != STT_GNU_IFUNC
7024 && (SYMBOL_CALLS_LOCAL (info, h)
7025 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
7026 && h->root.type == bfd_link_hash_undefweak))))
a06ea964
NC
7027 {
7028 /* This case can occur if we saw a CALL26 reloc in
7029 an input file, but the symbol wasn't referred to
7030 by a dynamic object or all references were
7031 garbage collected. In which case we can end up
7032 resolving. */
7033 h->plt.offset = (bfd_vma) - 1;
7034 h->needs_plt = 0;
7035 }
7036
7037 return TRUE;
7038 }
7039 else
80de0c6d 7040 /* Otherwise, reset to -1. */
a06ea964
NC
7041 h->plt.offset = (bfd_vma) - 1;
7042
7043
7044 /* If this is a weak symbol, and there is a real definition, the
7045 processor independent code will have arranged for us to see the
7046 real definition first, and we can just use the same value. */
60d67dc8 7047 if (h->is_weakalias)
a06ea964 7048 {
60d67dc8
AM
7049 struct elf_link_hash_entry *def = weakdef (h);
7050 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
7051 h->root.u.def.section = def->root.u.def.section;
7052 h->root.u.def.value = def->root.u.def.value;
a06ea964 7053 if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
60d67dc8 7054 h->non_got_ref = def->non_got_ref;
a06ea964
NC
7055 return TRUE;
7056 }
7057
7058 /* If we are creating a shared library, we must presume that the
7059 only references to the symbol are via the global offset table.
7060 For such cases we need not do anything here; the relocations will
7061 be handled correctly by relocate_section. */
0e1862bb 7062 if (bfd_link_pic (info))
a06ea964
NC
7063 return TRUE;
7064
7065 /* If there are no references to this symbol that do not use the
7066 GOT, we don't need to generate a copy reloc. */
7067 if (!h->non_got_ref)
7068 return TRUE;
7069
7070 /* If -z nocopyreloc was given, we won't generate them either. */
7071 if (info->nocopyreloc)
7072 {
7073 h->non_got_ref = 0;
7074 return TRUE;
7075 }
7076
6353d82b
JW
7077 if (ELIMINATE_COPY_RELOCS)
7078 {
7079 struct elf_aarch64_link_hash_entry *eh;
dce2246a 7080 /* If we don't find any dynamic relocs in read-only sections, then
6353d82b
JW
7081 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
7082 eh = (struct elf_aarch64_link_hash_entry *) h;
7083 if (!need_copy_relocation_p (eh))
7084 {
7085 h->non_got_ref = 0;
7086 return TRUE;
7087 }
7088 }
7089
a06ea964
NC
7090 /* We must allocate the symbol in our .dynbss section, which will
7091 become part of the .bss section of the executable. There will be
7092 an entry for this symbol in the .dynsym section. The dynamic
7093 object will contain position independent code, so all references
7094 from the dynamic object to this symbol will go through the global
7095 offset table. The dynamic linker will use the .dynsym entry to
7096 determine the address it must put in the global offset table, so
7097 both the dynamic object and the regular object will refer to the
7098 same memory location for the variable. */
7099
cec5225b 7100 htab = elf_aarch64_hash_table (info);
a06ea964
NC
7101
7102 /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
7103 to copy the initial value out of the dynamic object and into the
7104 runtime process image. */
5474d94f
AM
7105 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
7106 {
7107 s = htab->root.sdynrelro;
7108 srel = htab->root.sreldynrelro;
7109 }
7110 else
7111 {
7112 s = htab->root.sdynbss;
7113 srel = htab->root.srelbss;
7114 }
a06ea964
NC
7115 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
7116 {
5474d94f 7117 srel->size += RELOC_SIZE (htab);
a06ea964
NC
7118 h->needs_copy = 1;
7119 }
7120
6cabe1ea 7121 return _bfd_elf_adjust_dynamic_copy (info, h, s);
a06ea964
NC
7122
7123}
7124
7125static bfd_boolean
cec5225b 7126elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
a06ea964
NC
7127{
7128 struct elf_aarch64_local_symbol *locals;
cec5225b 7129 locals = elf_aarch64_locals (abfd);
a06ea964
NC
7130 if (locals == NULL)
7131 {
7132 locals = (struct elf_aarch64_local_symbol *)
7133 bfd_zalloc (abfd, number * sizeof (struct elf_aarch64_local_symbol));
7134 if (locals == NULL)
7135 return FALSE;
cec5225b 7136 elf_aarch64_locals (abfd) = locals;
a06ea964
NC
7137 }
7138 return TRUE;
7139}
7140
cc0efaa8
MS
7141/* Create the .got section to hold the global offset table. */
7142
7143static bfd_boolean
7144aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
7145{
7146 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7147 flagword flags;
7148 asection *s;
7149 struct elf_link_hash_entry *h;
7150 struct elf_link_hash_table *htab = elf_hash_table (info);
7151
7152 /* This function may be called more than once. */
ce558b89 7153 if (htab->sgot != NULL)
cc0efaa8
MS
7154 return TRUE;
7155
7156 flags = bed->dynamic_sec_flags;
7157
7158 s = bfd_make_section_anyway_with_flags (abfd,
7159 (bed->rela_plts_and_copies_p
7160 ? ".rela.got" : ".rel.got"),
7161 (bed->dynamic_sec_flags
7162 | SEC_READONLY));
7163 if (s == NULL
7164 || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
7165 return FALSE;
7166 htab->srelgot = s;
7167
7168 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
7169 if (s == NULL
7170 || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
7171 return FALSE;
7172 htab->sgot = s;
7173 htab->sgot->size += GOT_ENTRY_SIZE;
7174
7175 if (bed->want_got_sym)
7176 {
7177 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
7178 (or .got.plt) section. We don't do this in the linker script
7179 because we don't want to define the symbol if we are not creating
7180 a global offset table. */
7181 h = _bfd_elf_define_linkage_sym (abfd, info, s,
7182 "_GLOBAL_OFFSET_TABLE_");
7183 elf_hash_table (info)->hgot = h;
7184 if (h == NULL)
7185 return FALSE;
7186 }
7187
7188 if (bed->want_got_plt)
7189 {
7190 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
7191 if (s == NULL
7192 || !bfd_set_section_alignment (abfd, s,
7193 bed->s->log_file_align))
7194 return FALSE;
7195 htab->sgotplt = s;
7196 }
7197
7198 /* The first bit of the global offset table is the header. */
7199 s->size += bed->got_header_size;
7200
7201 return TRUE;
7202}
7203
a06ea964
NC
7204/* Look through the relocs for a section during the first phase. */
7205
7206static bfd_boolean
cec5225b 7207elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
a06ea964
NC
7208 asection *sec, const Elf_Internal_Rela *relocs)
7209{
7210 Elf_Internal_Shdr *symtab_hdr;
7211 struct elf_link_hash_entry **sym_hashes;
7212 const Elf_Internal_Rela *rel;
7213 const Elf_Internal_Rela *rel_end;
7214 asection *sreloc;
7215
cec5225b 7216 struct elf_aarch64_link_hash_table *htab;
a06ea964 7217
0e1862bb 7218 if (bfd_link_relocatable (info))
a06ea964
NC
7219 return TRUE;
7220
7221 BFD_ASSERT (is_aarch64_elf (abfd));
7222
cec5225b 7223 htab = elf_aarch64_hash_table (info);
a06ea964
NC
7224 sreloc = NULL;
7225
7226 symtab_hdr = &elf_symtab_hdr (abfd);
7227 sym_hashes = elf_sym_hashes (abfd);
a06ea964
NC
7228
7229 rel_end = relocs + sec->reloc_count;
7230 for (rel = relocs; rel < rel_end; rel++)
7231 {
7232 struct elf_link_hash_entry *h;
d42c267e 7233 unsigned int r_symndx;
a06ea964 7234 unsigned int r_type;
a6bb11b2 7235 bfd_reloc_code_real_type bfd_r_type;
1419bbe5 7236 Elf_Internal_Sym *isym;
a06ea964 7237
cec5225b
YZ
7238 r_symndx = ELFNN_R_SYM (rel->r_info);
7239 r_type = ELFNN_R_TYPE (rel->r_info);
a06ea964
NC
7240
7241 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
7242 {
695344c0 7243 /* xgettext:c-format */
871b3ab2 7244 _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
a06ea964
NC
7245 return FALSE;
7246 }
7247
ed5acf27 7248 if (r_symndx < symtab_hdr->sh_info)
1419bbe5
WN
7249 {
7250 /* A local symbol. */
7251 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
7252 abfd, r_symndx);
7253 if (isym == NULL)
7254 return FALSE;
7255
7256 /* Check relocation against local STT_GNU_IFUNC symbol. */
7257 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
7258 {
7259 h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel,
7260 TRUE);
7261 if (h == NULL)
7262 return FALSE;
7263
7264 /* Fake a STT_GNU_IFUNC symbol. */
7265 h->type = STT_GNU_IFUNC;
7266 h->def_regular = 1;
7267 h->ref_regular = 1;
7268 h->forced_local = 1;
7269 h->root.type = bfd_link_hash_defined;
7270 }
7271 else
7272 h = NULL;
7273 }
a06ea964
NC
7274 else
7275 {
7276 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
7277 while (h->root.type == bfd_link_hash_indirect
7278 || h->root.type == bfd_link_hash_warning)
7279 h = (struct elf_link_hash_entry *) h->root.u.i.link;
7280 }
7281
7282 /* Could be done earlier, if h were already available. */
a6bb11b2 7283 bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
a06ea964 7284
1419bbe5
WN
7285 if (h != NULL)
7286 {
18f822a0
JW
7287 /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
7288 This shows up in particular in an R_AARCH64_PREL64 in large model
7289 when calculating the pc-relative address to .got section which is
7290 used to initialize the gp register. */
7291 if (h->root.root.string
7292 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
7293 {
7294 if (htab->root.dynobj == NULL)
7295 htab->root.dynobj = abfd;
7296
7297 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
7298 return FALSE;
7299
7300 BFD_ASSERT (h == htab->root.hgot);
7301 }
7302
1419bbe5
WN
7303 /* Create the ifunc sections for static executables. If we
7304 never see an indirect function symbol nor we are building
7305 a static executable, those sections will be empty and
7306 won't appear in output. */
7307 switch (bfd_r_type)
7308 {
7309 default:
7310 break;
7311
ce336788
JW
7312 case BFD_RELOC_AARCH64_ADD_LO12:
7313 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
7314 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
1419bbe5 7315 case BFD_RELOC_AARCH64_CALL26:
ce336788 7316 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
1419bbe5 7317 case BFD_RELOC_AARCH64_JUMP26:
7018c030 7318 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
1419bbe5 7319 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
a2e1db00 7320 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
99ad26cb 7321 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
1419bbe5 7322 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
dc8008f5 7323 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
74a1bfe1 7324 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
ce336788 7325 case BFD_RELOC_AARCH64_NN:
1419bbe5
WN
7326 if (htab->root.dynobj == NULL)
7327 htab->root.dynobj = abfd;
7328 if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
7329 return FALSE;
7330 break;
7331 }
7332
2d0ca824 7333 /* It is referenced by a non-shared object. */
1419bbe5 7334 h->ref_regular = 1;
1419bbe5
WN
7335 }
7336
a6bb11b2 7337 switch (bfd_r_type)
a06ea964 7338 {
79e74192
RL
7339 case BFD_RELOC_AARCH64_16:
7340#if ARCH_SIZE == 64
7341 case BFD_RELOC_AARCH64_32:
7342#endif
279b2f94 7343 if (bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0)
79e74192 7344 {
279b2f94
RL
7345 if (h != NULL
7346 /* This is an absolute symbol. It represents a value instead
7347 of an address. */
7348 && ((h->root.type == bfd_link_hash_defined
7349 && bfd_is_abs_section (h->root.u.def.section))
7350 /* This is an undefined symbol. */
7351 || h->root.type == bfd_link_hash_undefined))
7352 break;
7353
7354 /* For local symbols, defined global symbols in a non-ABS section,
7355 it is assumed that the value is an address. */
79e74192
RL
7356 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
7357 _bfd_error_handler
7358 /* xgettext:c-format */
871b3ab2 7359 (_("%pB: relocation %s against `%s' can not be used when making "
79e74192
RL
7360 "a shared object"),
7361 abfd, elfNN_aarch64_howto_table[howto_index].name,
7362 (h) ? h->root.root.string : "a local symbol");
7363 bfd_set_error (bfd_error_bad_value);
7364 return FALSE;
7365 }
7366 else
7367 break;
7368
6353d82b
JW
7369 case BFD_RELOC_AARCH64_MOVW_G0_NC:
7370 case BFD_RELOC_AARCH64_MOVW_G1_NC:
7371 case BFD_RELOC_AARCH64_MOVW_G2_NC:
7372 case BFD_RELOC_AARCH64_MOVW_G3:
7373 if (bfd_link_pic (info))
7374 {
7375 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
7376 _bfd_error_handler
7377 /* xgettext:c-format */
871b3ab2 7378 (_("%pB: relocation %s against `%s' can not be used when making "
6353d82b
JW
7379 "a shared object; recompile with -fPIC"),
7380 abfd, elfNN_aarch64_howto_table[howto_index].name,
7381 (h) ? h->root.root.string : "a local symbol");
7382 bfd_set_error (bfd_error_bad_value);
7383 return FALSE;
7384 }
7385 /* Fall through. */
7386
7387 case BFD_RELOC_AARCH64_16_PCREL:
7388 case BFD_RELOC_AARCH64_32_PCREL:
7389 case BFD_RELOC_AARCH64_64_PCREL:
7390 case BFD_RELOC_AARCH64_ADD_LO12:
7391 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
7392 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
7393 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
7394 case BFD_RELOC_AARCH64_LDST128_LO12:
7395 case BFD_RELOC_AARCH64_LDST16_LO12:
7396 case BFD_RELOC_AARCH64_LDST32_LO12:
7397 case BFD_RELOC_AARCH64_LDST64_LO12:
7398 case BFD_RELOC_AARCH64_LDST8_LO12:
7399 case BFD_RELOC_AARCH64_LD_LO19_PCREL:
7400 if (h == NULL || bfd_link_pic (info))
7401 break;
7402 /* Fall through. */
7403
a6bb11b2 7404 case BFD_RELOC_AARCH64_NN:
a06ea964
NC
7405
7406 /* We don't need to handle relocs into sections not going into
7407 the "real" output. */
7408 if ((sec->flags & SEC_ALLOC) == 0)
7409 break;
7410
7411 if (h != NULL)
7412 {
0e1862bb 7413 if (!bfd_link_pic (info))
a06ea964
NC
7414 h->non_got_ref = 1;
7415
7416 h->plt.refcount += 1;
7417 h->pointer_equality_needed = 1;
7418 }
7419
7420 /* No need to do anything if we're not creating a shared
7421 object. */
6353d82b
JW
7422 if (!(bfd_link_pic (info)
7423 /* If on the other hand, we are creating an executable, we
7424 may need to keep relocations for symbols satisfied by a
7425 dynamic library if we manage to avoid copy relocs for the
7426 symbol.
7427
7428 NOTE: Currently, there is no support of copy relocs
7429 elimination on pc-relative relocation types, because there is
7430 no dynamic relocation support for them in glibc. We still
7431 record the dynamic symbol reference for them. This is
7432 because one symbol may be referenced by both absolute
7433 relocation (for example, BFD_RELOC_AARCH64_NN) and
7434 pc-relative relocation. We need full symbol reference
7435 information to make correct decision later in
7436 elfNN_aarch64_adjust_dynamic_symbol. */
7437 || (ELIMINATE_COPY_RELOCS
7438 && !bfd_link_pic (info)
7439 && h != NULL
7440 && (h->root.type == bfd_link_hash_defweak
7441 || !h->def_regular))))
a06ea964
NC
7442 break;
7443
7444 {
7445 struct elf_dyn_relocs *p;
7446 struct elf_dyn_relocs **head;
6353d82b 7447 int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
a06ea964
NC
7448
7449 /* We must copy these reloc types into the output file.
7450 Create a reloc section in dynobj and make room for
7451 this reloc. */
7452 if (sreloc == NULL)
7453 {
7454 if (htab->root.dynobj == NULL)
7455 htab->root.dynobj = abfd;
7456
7457 sreloc = _bfd_elf_make_dynamic_reloc_section
0608afa7 7458 (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ TRUE);
a06ea964
NC
7459
7460 if (sreloc == NULL)
7461 return FALSE;
7462 }
7463
7464 /* If this is a global symbol, we count the number of
7465 relocations we need for this symbol. */
7466 if (h != NULL)
7467 {
cec5225b
YZ
7468 struct elf_aarch64_link_hash_entry *eh;
7469 eh = (struct elf_aarch64_link_hash_entry *) h;
a06ea964
NC
7470 head = &eh->dyn_relocs;
7471 }
7472 else
7473 {
7474 /* Track dynamic relocs needed for local syms too.
7475 We really need local syms available to do this
7476 easily. Oh well. */
7477
7478 asection *s;
7479 void **vpp;
a06ea964
NC
7480
7481 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
7482 abfd, r_symndx);
7483 if (isym == NULL)
7484 return FALSE;
7485
7486 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
7487 if (s == NULL)
7488 s = sec;
7489
7490 /* Beware of type punned pointers vs strict aliasing
7491 rules. */
7492 vpp = &(elf_section_data (s)->local_dynrel);
7493 head = (struct elf_dyn_relocs **) vpp;
7494 }
7495
7496 p = *head;
7497 if (p == NULL || p->sec != sec)
7498 {
7499 bfd_size_type amt = sizeof *p;
7500 p = ((struct elf_dyn_relocs *)
7501 bfd_zalloc (htab->root.dynobj, amt));
7502 if (p == NULL)
7503 return FALSE;
7504 p->next = *head;
7505 *head = p;
7506 p->sec = sec;
7507 }
7508
7509 p->count += 1;
7510
6353d82b
JW
7511 if (elfNN_aarch64_howto_table[howto_index].pc_relative)
7512 p->pc_count += 1;
a06ea964
NC
7513 }
7514 break;
7515
7516 /* RR: We probably want to keep a consistency check that
7517 there are no dangling GOT_PAGE relocs. */
a6bb11b2 7518 case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
7bcccb57 7519 case BFD_RELOC_AARCH64_GOT_LD_PREL19:
7018c030 7520 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
7bcccb57 7521 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
a2e1db00 7522 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
99ad26cb 7523 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
7bcccb57 7524 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
dc8008f5 7525 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
74a1bfe1 7526 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
f955cccf 7527 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
7bcccb57 7528 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
389b8029 7529 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
7bcccb57 7530 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
f955cccf 7531 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
1ada945d 7532 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
0484b454
RL
7533 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
7534 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
a6bb11b2 7535 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
7bcccb57 7536 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
3c12b054 7537 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
7ba7cfe4 7538 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
94facae3 7539 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
a6bb11b2 7540 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
a6bb11b2 7541 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
7bcccb57 7542 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
043bf05a 7543 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
3b957e5b
RL
7544 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
7545 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
73f925cc 7546 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
f69e4920 7547 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
77a69ff8 7548 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
b7a944fe
RL
7549 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
7550 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
7551 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
a06ea964
NC
7552 {
7553 unsigned got_type;
7554 unsigned old_got_type;
7555
a6bb11b2 7556 got_type = aarch64_reloc_got_type (bfd_r_type);
a06ea964
NC
7557
7558 if (h)
7559 {
7560 h->got.refcount += 1;
cec5225b 7561 old_got_type = elf_aarch64_hash_entry (h)->got_type;
a06ea964
NC
7562 }
7563 else
7564 {
7565 struct elf_aarch64_local_symbol *locals;
7566
cec5225b 7567 if (!elfNN_aarch64_allocate_local_symbols
a06ea964
NC
7568 (abfd, symtab_hdr->sh_info))
7569 return FALSE;
7570
cec5225b 7571 locals = elf_aarch64_locals (abfd);
a06ea964
NC
7572 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
7573 locals[r_symndx].got_refcount += 1;
7574 old_got_type = locals[r_symndx].got_type;
7575 }
7576
7577 /* If a variable is accessed with both general dynamic TLS
7578 methods, two slots may be created. */
7579 if (GOT_TLS_GD_ANY_P (old_got_type) && GOT_TLS_GD_ANY_P (got_type))
7580 got_type |= old_got_type;
7581
7582 /* We will already have issued an error message if there
7583 is a TLS/non-TLS mismatch, based on the symbol type.
7584 So just combine any TLS types needed. */
7585 if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
7586 && got_type != GOT_NORMAL)
7587 got_type |= old_got_type;
7588
7589 /* If the symbol is accessed by both IE and GD methods, we
7590 are able to relax. Turn off the GD flag, without
7591 messing up with any other kind of TLS types that may be
7592 involved. */
7593 if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
7594 got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
7595
7596 if (old_got_type != got_type)
7597 {
7598 if (h != NULL)
cec5225b 7599 elf_aarch64_hash_entry (h)->got_type = got_type;
a06ea964
NC
7600 else
7601 {
7602 struct elf_aarch64_local_symbol *locals;
cec5225b 7603 locals = elf_aarch64_locals (abfd);
a06ea964
NC
7604 BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
7605 locals[r_symndx].got_type = got_type;
7606 }
7607 }
7608
cc0efaa8
MS
7609 if (htab->root.dynobj == NULL)
7610 htab->root.dynobj = abfd;
7611 if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
7612 return FALSE;
a06ea964
NC
7613 break;
7614 }
7615
a6bb11b2
YZ
7616 case BFD_RELOC_AARCH64_CALL26:
7617 case BFD_RELOC_AARCH64_JUMP26:
a06ea964
NC
7618 /* If this is a local symbol then we resolve it
7619 directly without creating a PLT entry. */
7620 if (h == NULL)
7621 continue;
7622
7623 h->needs_plt = 1;
1419bbe5
WN
7624 if (h->plt.refcount <= 0)
7625 h->plt.refcount = 1;
7626 else
7627 h->plt.refcount += 1;
a06ea964 7628 break;
a6bb11b2
YZ
7629
7630 default:
7631 break;
a06ea964
NC
7632 }
7633 }
a6bb11b2 7634
a06ea964
NC
7635 return TRUE;
7636}
7637
7638/* Treat mapping symbols as special target symbols. */
7639
7640static bfd_boolean
cec5225b 7641elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED,
a06ea964
NC
7642 asymbol *sym)
7643{
7644 return bfd_is_aarch64_special_symbol_name (sym->name,
7645 BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
7646}
7647
7648/* This is a copy of elf_find_function () from elf.c except that
7649 AArch64 mapping symbols are ignored when looking for function names. */
7650
7651static bfd_boolean
7652aarch64_elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
a06ea964 7653 asymbol **symbols,
fb167eb2 7654 asection *section,
a06ea964
NC
7655 bfd_vma offset,
7656 const char **filename_ptr,
7657 const char **functionname_ptr)
7658{
7659 const char *filename = NULL;
7660 asymbol *func = NULL;
7661 bfd_vma low_func = 0;
7662 asymbol **p;
7663
7664 for (p = symbols; *p != NULL; p++)
7665 {
7666 elf_symbol_type *q;
7667
7668 q = (elf_symbol_type *) * p;
7669
7670 switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
7671 {
7672 default:
7673 break;
7674 case STT_FILE:
7675 filename = bfd_asymbol_name (&q->symbol);
7676 break;
7677 case STT_FUNC:
7678 case STT_NOTYPE:
7679 /* Skip mapping symbols. */
7680 if ((q->symbol.flags & BSF_LOCAL)
7681 && (bfd_is_aarch64_special_symbol_name
7682 (q->symbol.name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)))
7683 continue;
7684 /* Fall through. */
7685 if (bfd_get_section (&q->symbol) == section
7686 && q->symbol.value >= low_func && q->symbol.value <= offset)
7687 {
7688 func = (asymbol *) q;
7689 low_func = q->symbol.value;
7690 }
7691 break;
7692 }
7693 }
7694
7695 if (func == NULL)
7696 return FALSE;
7697
7698 if (filename_ptr)
7699 *filename_ptr = filename;
7700 if (functionname_ptr)
7701 *functionname_ptr = bfd_asymbol_name (func);
7702
7703 return TRUE;
7704}
7705
7706
7707/* Find the nearest line to a particular section and offset, for error
7708 reporting. This code is a duplicate of the code in elf.c, except
7709 that it uses aarch64_elf_find_function. */
7710
7711static bfd_boolean
cec5225b 7712elfNN_aarch64_find_nearest_line (bfd *abfd,
a06ea964 7713 asymbol **symbols,
fb167eb2 7714 asection *section,
a06ea964
NC
7715 bfd_vma offset,
7716 const char **filename_ptr,
7717 const char **functionname_ptr,
fb167eb2
AM
7718 unsigned int *line_ptr,
7719 unsigned int *discriminator_ptr)
a06ea964
NC
7720{
7721 bfd_boolean found = FALSE;
7722
fb167eb2 7723 if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
a06ea964 7724 filename_ptr, functionname_ptr,
fb167eb2
AM
7725 line_ptr, discriminator_ptr,
7726 dwarf_debug_sections, 0,
a06ea964
NC
7727 &elf_tdata (abfd)->dwarf2_find_line_info))
7728 {
7729 if (!*functionname_ptr)
fb167eb2 7730 aarch64_elf_find_function (abfd, symbols, section, offset,
a06ea964
NC
7731 *filename_ptr ? NULL : filename_ptr,
7732 functionname_ptr);
7733
7734 return TRUE;
7735 }
7736
fb167eb2
AM
7737 /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
7738 toolchain uses DWARF1. */
7739
a06ea964
NC
7740 if (!_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
7741 &found, filename_ptr,
7742 functionname_ptr, line_ptr,
7743 &elf_tdata (abfd)->line_info))
7744 return FALSE;
7745
7746 if (found && (*functionname_ptr || *line_ptr))
7747 return TRUE;
7748
7749 if (symbols == NULL)
7750 return FALSE;
7751
fb167eb2 7752 if (!aarch64_elf_find_function (abfd, symbols, section, offset,
a06ea964
NC
7753 filename_ptr, functionname_ptr))
7754 return FALSE;
7755
7756 *line_ptr = 0;
7757 return TRUE;
7758}
7759
7760static bfd_boolean
cec5225b 7761elfNN_aarch64_find_inliner_info (bfd *abfd,
a06ea964
NC
7762 const char **filename_ptr,
7763 const char **functionname_ptr,
7764 unsigned int *line_ptr)
7765{
7766 bfd_boolean found;
7767 found = _bfd_dwarf2_find_inliner_info
7768 (abfd, filename_ptr,
7769 functionname_ptr, line_ptr, &elf_tdata (abfd)->dwarf2_find_line_info);
7770 return found;
7771}
7772
7773
7774static void
cec5225b 7775elfNN_aarch64_post_process_headers (bfd *abfd,
1419bbe5 7776 struct bfd_link_info *link_info)
a06ea964
NC
7777{
7778 Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
7779
7780 i_ehdrp = elf_elfheader (abfd);
a06ea964 7781 i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
1419bbe5 7782
78245035 7783 _bfd_elf_post_process_headers (abfd, link_info);
a06ea964
NC
7784}
7785
7786static enum elf_reloc_type_class
cec5225b 7787elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
7e612e98
AM
7788 const asection *rel_sec ATTRIBUTE_UNUSED,
7789 const Elf_Internal_Rela *rela)
a06ea964 7790{
f2e6a843
SN
7791 struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
7792
7793 if (htab->root.dynsym != NULL
7794 && htab->root.dynsym->contents != NULL)
7795 {
7796 /* Check relocation against STT_GNU_IFUNC symbol if there are
7797 dynamic symbols. */
7798 bfd *abfd = info->output_bfd;
7799 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7800 unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
7801 if (r_symndx != STN_UNDEF)
7802 {
7803 Elf_Internal_Sym sym;
7804 if (!bed->s->swap_symbol_in (abfd,
7805 (htab->root.dynsym->contents
7806 + r_symndx * bed->s->sizeof_sym),
7807 0, &sym))
7808 {
7809 /* xgettext:c-format */
871b3ab2 7810 _bfd_error_handler (_("%pB symbol number %lu references"
f2e6a843
SN
7811 " nonexistent SHT_SYMTAB_SHNDX section"),
7812 abfd, r_symndx);
7813 /* Ideally an error class should be returned here. */
7814 }
7815 else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
7816 return reloc_class_ifunc;
7817 }
7818 }
7819
cec5225b 7820 switch ((int) ELFNN_R_TYPE (rela->r_info))
a06ea964 7821 {
f2e6a843
SN
7822 case AARCH64_R (IRELATIVE):
7823 return reloc_class_ifunc;
a6bb11b2 7824 case AARCH64_R (RELATIVE):
a06ea964 7825 return reloc_class_relative;
a6bb11b2 7826 case AARCH64_R (JUMP_SLOT):
a06ea964 7827 return reloc_class_plt;
a6bb11b2 7828 case AARCH64_R (COPY):
a06ea964
NC
7829 return reloc_class_copy;
7830 default:
7831 return reloc_class_normal;
7832 }
7833}
7834
a06ea964
NC
7835/* Handle an AArch64 specific section when reading an object file. This is
7836 called when bfd_section_from_shdr finds a section with an unknown
7837 type. */
7838
7839static bfd_boolean
cec5225b 7840elfNN_aarch64_section_from_shdr (bfd *abfd,
a06ea964
NC
7841 Elf_Internal_Shdr *hdr,
7842 const char *name, int shindex)
7843{
7844 /* There ought to be a place to keep ELF backend specific flags, but
7845 at the moment there isn't one. We just keep track of the
7846 sections by their name, instead. Fortunately, the ABI gives
7847 names for all the AArch64 specific sections, so we will probably get
7848 away with this. */
7849 switch (hdr->sh_type)
7850 {
7851 case SHT_AARCH64_ATTRIBUTES:
7852 break;
7853
7854 default:
7855 return FALSE;
7856 }
7857
7858 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
7859 return FALSE;
7860
7861 return TRUE;
7862}
7863
7864/* A structure used to record a list of sections, independently
7865 of the next and prev fields in the asection structure. */
7866typedef struct section_list
7867{
7868 asection *sec;
7869 struct section_list *next;
7870 struct section_list *prev;
7871}
7872section_list;
7873
7874/* Unfortunately we need to keep a list of sections for which
7875 an _aarch64_elf_section_data structure has been allocated. This
cec5225b 7876 is because it is possible for functions like elfNN_aarch64_write_section
a06ea964
NC
7877 to be called on a section which has had an elf_data_structure
7878 allocated for it (and so the used_by_bfd field is valid) but
7879 for which the AArch64 extended version of this structure - the
7880 _aarch64_elf_section_data structure - has not been allocated. */
7881static section_list *sections_with_aarch64_elf_section_data = NULL;
7882
7883static void
7884record_section_with_aarch64_elf_section_data (asection *sec)
7885{
7886 struct section_list *entry;
7887
7888 entry = bfd_malloc (sizeof (*entry));
7889 if (entry == NULL)
7890 return;
7891 entry->sec = sec;
7892 entry->next = sections_with_aarch64_elf_section_data;
7893 entry->prev = NULL;
7894 if (entry->next != NULL)
7895 entry->next->prev = entry;
7896 sections_with_aarch64_elf_section_data = entry;
7897}
7898
7899static struct section_list *
7900find_aarch64_elf_section_entry (asection *sec)
7901{
7902 struct section_list *entry;
7903 static struct section_list *last_entry = NULL;
7904
7905 /* This is a short cut for the typical case where the sections are added
7906 to the sections_with_aarch64_elf_section_data list in forward order and
7907 then looked up here in backwards order. This makes a real difference
7908 to the ld-srec/sec64k.exp linker test. */
7909 entry = sections_with_aarch64_elf_section_data;
7910 if (last_entry != NULL)
7911 {
7912 if (last_entry->sec == sec)
7913 entry = last_entry;
7914 else if (last_entry->next != NULL && last_entry->next->sec == sec)
7915 entry = last_entry->next;
7916 }
7917
7918 for (; entry; entry = entry->next)
7919 if (entry->sec == sec)
7920 break;
7921
7922 if (entry)
7923 /* Record the entry prior to this one - it is the entry we are
7924 most likely to want to locate next time. Also this way if we
7925 have been called from
7926 unrecord_section_with_aarch64_elf_section_data () we will not
7927 be caching a pointer that is about to be freed. */
7928 last_entry = entry->prev;
7929
7930 return entry;
7931}
7932
7933static void
7934unrecord_section_with_aarch64_elf_section_data (asection *sec)
7935{
7936 struct section_list *entry;
7937
7938 entry = find_aarch64_elf_section_entry (sec);
7939
7940 if (entry)
7941 {
7942 if (entry->prev != NULL)
7943 entry->prev->next = entry->next;
7944 if (entry->next != NULL)
7945 entry->next->prev = entry->prev;
7946 if (entry == sections_with_aarch64_elf_section_data)
7947 sections_with_aarch64_elf_section_data = entry->next;
7948 free (entry);
7949 }
7950}
7951
7952
7953typedef struct
7954{
7955 void *finfo;
7956 struct bfd_link_info *info;
7957 asection *sec;
7958 int sec_shndx;
7959 int (*func) (void *, const char *, Elf_Internal_Sym *,
7960 asection *, struct elf_link_hash_entry *);
7961} output_arch_syminfo;
7962
7963enum map_symbol_type
7964{
7965 AARCH64_MAP_INSN,
7966 AARCH64_MAP_DATA
7967};
7968
7969
7970/* Output a single mapping symbol. */
7971
7972static bfd_boolean
cec5225b 7973elfNN_aarch64_output_map_sym (output_arch_syminfo *osi,
a06ea964
NC
7974 enum map_symbol_type type, bfd_vma offset)
7975{
7976 static const char *names[2] = { "$x", "$d" };
7977 Elf_Internal_Sym sym;
7978
7979 sym.st_value = (osi->sec->output_section->vma
7980 + osi->sec->output_offset + offset);
7981 sym.st_size = 0;
7982 sym.st_other = 0;
7983 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
7984 sym.st_shndx = osi->sec_shndx;
7985 return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
7986}
7987
a06ea964
NC
7988/* Output a single local symbol for a generated stub. */
7989
7990static bfd_boolean
cec5225b 7991elfNN_aarch64_output_stub_sym (output_arch_syminfo *osi, const char *name,
a06ea964
NC
7992 bfd_vma offset, bfd_vma size)
7993{
7994 Elf_Internal_Sym sym;
7995
7996 sym.st_value = (osi->sec->output_section->vma
7997 + osi->sec->output_offset + offset);
7998 sym.st_size = size;
7999 sym.st_other = 0;
8000 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
8001 sym.st_shndx = osi->sec_shndx;
8002 return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
8003}
8004
8005static bfd_boolean
8006aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
8007{
cec5225b 8008 struct elf_aarch64_stub_hash_entry *stub_entry;
a06ea964
NC
8009 asection *stub_sec;
8010 bfd_vma addr;
8011 char *stub_name;
8012 output_arch_syminfo *osi;
8013
8014 /* Massage our args to the form they really have. */
cec5225b 8015 stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
a06ea964
NC
8016 osi = (output_arch_syminfo *) in_arg;
8017
8018 stub_sec = stub_entry->stub_sec;
8019
8020 /* Ensure this stub is attached to the current section being
8021 processed. */
8022 if (stub_sec != osi->sec)
8023 return TRUE;
8024
8025 addr = (bfd_vma) stub_entry->stub_offset;
8026
8027 stub_name = stub_entry->output_name;
8028
8029 switch (stub_entry->stub_type)
8030 {
8031 case aarch64_stub_adrp_branch:
cec5225b 8032 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
a06ea964
NC
8033 sizeof (aarch64_adrp_branch_stub)))
8034 return FALSE;
cec5225b 8035 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
a06ea964
NC
8036 return FALSE;
8037 break;
8038 case aarch64_stub_long_branch:
cec5225b 8039 if (!elfNN_aarch64_output_stub_sym
a06ea964
NC
8040 (osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
8041 return FALSE;
cec5225b 8042 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
a06ea964 8043 return FALSE;
cec5225b 8044 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_DATA, addr + 16))
a06ea964
NC
8045 return FALSE;
8046 break;
68fcca92
JW
8047 case aarch64_stub_erratum_835769_veneer:
8048 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
8049 sizeof (aarch64_erratum_835769_stub)))
8050 return FALSE;
8051 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8052 return FALSE;
8053 break;
4106101c
MS
8054 case aarch64_stub_erratum_843419_veneer:
8055 if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
8056 sizeof (aarch64_erratum_843419_stub)))
8057 return FALSE;
8058 if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
8059 return FALSE;
8060 break;
8061
a06ea964 8062 default:
8e2fe09f 8063 abort ();
a06ea964
NC
8064 }
8065
8066 return TRUE;
8067}
8068
8069/* Output mapping symbols for linker generated sections. */
8070
8071static bfd_boolean
cec5225b 8072elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
a06ea964
NC
8073 struct bfd_link_info *info,
8074 void *finfo,
8075 int (*func) (void *, const char *,
8076 Elf_Internal_Sym *,
8077 asection *,
8078 struct elf_link_hash_entry
8079 *))
8080{
8081 output_arch_syminfo osi;
cec5225b 8082 struct elf_aarch64_link_hash_table *htab;
a06ea964 8083
cec5225b 8084 htab = elf_aarch64_hash_table (info);
a06ea964
NC
8085
8086 osi.finfo = finfo;
8087 osi.info = info;
8088 osi.func = func;
8089
8090 /* Long calls stubs. */
8091 if (htab->stub_bfd && htab->stub_bfd->sections)
8092 {
8093 asection *stub_sec;
8094
8095 for (stub_sec = htab->stub_bfd->sections;
8096 stub_sec != NULL; stub_sec = stub_sec->next)
8097 {
8098 /* Ignore non-stub sections. */
8099 if (!strstr (stub_sec->name, STUB_SUFFIX))
8100 continue;
8101
8102 osi.sec = stub_sec;
8103
8104 osi.sec_shndx = _bfd_elf_section_from_bfd_section
8105 (output_bfd, osi.sec->output_section);
8106
61865519
MS
8107 /* The first instruction in a stub is always a branch. */
8108 if (!elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0))
8109 return FALSE;
8110
a06ea964
NC
8111 bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
8112 &osi);
8113 }
8114 }
8115
8116 /* Finally, output mapping symbols for the PLT. */
8117 if (!htab->root.splt || htab->root.splt->size == 0)
8118 return TRUE;
8119
a06ea964
NC
8120 osi.sec_shndx = _bfd_elf_section_from_bfd_section
8121 (output_bfd, htab->root.splt->output_section);
8122 osi.sec = htab->root.splt;
8123
73524045 8124 elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0);
a06ea964
NC
8125
8126 return TRUE;
8127
8128}
8129
8130/* Allocate target specific section data. */
8131
8132static bfd_boolean
cec5225b 8133elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec)
a06ea964
NC
8134{
8135 if (!sec->used_by_bfd)
8136 {
8137 _aarch64_elf_section_data *sdata;
8138 bfd_size_type amt = sizeof (*sdata);
8139
8140 sdata = bfd_zalloc (abfd, amt);
8141 if (sdata == NULL)
8142 return FALSE;
8143 sec->used_by_bfd = sdata;
8144 }
8145
8146 record_section_with_aarch64_elf_section_data (sec);
8147
8148 return _bfd_elf_new_section_hook (abfd, sec);
8149}
8150
8151
8152static void
8153unrecord_section_via_map_over_sections (bfd *abfd ATTRIBUTE_UNUSED,
8154 asection *sec,
8155 void *ignore ATTRIBUTE_UNUSED)
8156{
8157 unrecord_section_with_aarch64_elf_section_data (sec);
8158}
8159
8160static bfd_boolean
cec5225b 8161elfNN_aarch64_close_and_cleanup (bfd *abfd)
a06ea964
NC
8162{
8163 if (abfd->sections)
8164 bfd_map_over_sections (abfd,
8165 unrecord_section_via_map_over_sections, NULL);
8166
8167 return _bfd_elf_close_and_cleanup (abfd);
8168}
8169
8170static bfd_boolean
cec5225b 8171elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
a06ea964
NC
8172{
8173 if (abfd->sections)
8174 bfd_map_over_sections (abfd,
8175 unrecord_section_via_map_over_sections, NULL);
8176
8177 return _bfd_free_cached_info (abfd);
8178}
8179
a06ea964
NC
8180/* Create dynamic sections. This is different from the ARM backend in that
8181 the got, plt, gotplt and their relocation sections are all created in the
8182 standard part of the bfd elf backend. */
8183
8184static bfd_boolean
cec5225b 8185elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
a06ea964
NC
8186 struct bfd_link_info *info)
8187{
cc0efaa8
MS
8188 /* We need to create .got section. */
8189 if (!aarch64_elf_create_got_section (dynobj, info))
8190 return FALSE;
a06ea964 8191
9d19e4fd 8192 return _bfd_elf_create_dynamic_sections (dynobj, info);
a06ea964
NC
8193}
8194
8195
8196/* Allocate space in .plt, .got and associated reloc sections for
8197 dynamic relocs. */
8198
8199static bfd_boolean
cec5225b 8200elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
a06ea964
NC
8201{
8202 struct bfd_link_info *info;
cec5225b
YZ
8203 struct elf_aarch64_link_hash_table *htab;
8204 struct elf_aarch64_link_hash_entry *eh;
a06ea964
NC
8205 struct elf_dyn_relocs *p;
8206
8207 /* An example of a bfd_link_hash_indirect symbol is versioned
8208 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
8209 -> __gxx_personality_v0(bfd_link_hash_defined)
8210
8211 There is no need to process bfd_link_hash_indirect symbols here
8212 because we will also be presented with the concrete instance of
cec5225b 8213 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
a06ea964 8214 called to copy all relevant data from the generic to the concrete
2d0ca824 8215 symbol instance. */
a06ea964
NC
8216 if (h->root.type == bfd_link_hash_indirect)
8217 return TRUE;
8218
8219 if (h->root.type == bfd_link_hash_warning)
8220 h = (struct elf_link_hash_entry *) h->root.u.i.link;
8221
8222 info = (struct bfd_link_info *) inf;
cec5225b 8223 htab = elf_aarch64_hash_table (info);
a06ea964 8224
1419bbe5
WN
8225 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
8226 here if it is defined and referenced in a non-shared object. */
8227 if (h->type == STT_GNU_IFUNC
8228 && h->def_regular)
8229 return TRUE;
8230 else if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
a06ea964
NC
8231 {
8232 /* Make sure this symbol is output as a dynamic symbol.
07d6d2b8 8233 Undefined weak syms won't yet be marked as dynamic. */
ff07562f
JW
8234 if (h->dynindx == -1 && !h->forced_local
8235 && h->root.type == bfd_link_hash_undefweak)
a06ea964
NC
8236 {
8237 if (!bfd_elf_link_record_dynamic_symbol (info, h))
8238 return FALSE;
8239 }
8240
0e1862bb 8241 if (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
a06ea964
NC
8242 {
8243 asection *s = htab->root.splt;
8244
8245 /* If this is the first .plt entry, make room for the special
8246 first entry. */
8247 if (s->size == 0)
8248 s->size += htab->plt_header_size;
8249
8250 h->plt.offset = s->size;
8251
8252 /* If this symbol is not defined in a regular file, and we are
8253 not generating a shared library, then set the symbol to this
8254 location in the .plt. This is required to make function
8255 pointers compare as equal between the normal executable and
8256 the shared library. */
0e1862bb 8257 if (!bfd_link_pic (info) && !h->def_regular)
a06ea964
NC
8258 {
8259 h->root.u.def.section = s;
8260 h->root.u.def.value = h->plt.offset;
8261 }
8262
8263 /* Make room for this entry. For now we only create the
8264 small model PLT entries. We later need to find a way
8265 of relaxing into these from the large model PLT entries. */
8266 s->size += PLT_SMALL_ENTRY_SIZE;
8267
8268 /* We also need to make an entry in the .got.plt section, which
8269 will be placed in the .got section by the linker script. */
8270 htab->root.sgotplt->size += GOT_ENTRY_SIZE;
8271
8272 /* We also need to make an entry in the .rela.plt section. */
8273 htab->root.srelplt->size += RELOC_SIZE (htab);
8274
8275 /* We need to ensure that all GOT entries that serve the PLT
8276 are consecutive with the special GOT slots [0] [1] and
8277 [2]. Any addtional relocations, such as
8278 R_AARCH64_TLSDESC, must be placed after the PLT related
8279 entries. We abuse the reloc_count such that during
8280 sizing we adjust reloc_count to indicate the number of
8281 PLT related reserved entries. In subsequent phases when
8282 filling in the contents of the reloc entries, PLT related
8283 entries are placed by computing their PLT index (0
8284 .. reloc_count). While other none PLT relocs are placed
8285 at the slot indicated by reloc_count and reloc_count is
8286 updated. */
8287
8288 htab->root.srelplt->reloc_count++;
8289 }
8290 else
8291 {
8292 h->plt.offset = (bfd_vma) - 1;
8293 h->needs_plt = 0;
8294 }
8295 }
8296 else
8297 {
8298 h->plt.offset = (bfd_vma) - 1;
8299 h->needs_plt = 0;
8300 }
8301
cec5225b 8302 eh = (struct elf_aarch64_link_hash_entry *) h;
a06ea964
NC
8303 eh->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
8304
8305 if (h->got.refcount > 0)
8306 {
8307 bfd_boolean dyn;
cec5225b 8308 unsigned got_type = elf_aarch64_hash_entry (h)->got_type;
a06ea964
NC
8309
8310 h->got.offset = (bfd_vma) - 1;
8311
8312 dyn = htab->root.dynamic_sections_created;
8313
8314 /* Make sure this symbol is output as a dynamic symbol.
07d6d2b8 8315 Undefined weak syms won't yet be marked as dynamic. */
ff07562f
JW
8316 if (dyn && h->dynindx == -1 && !h->forced_local
8317 && h->root.type == bfd_link_hash_undefweak)
a06ea964
NC
8318 {
8319 if (!bfd_elf_link_record_dynamic_symbol (info, h))
8320 return FALSE;
8321 }
8322
8323 if (got_type == GOT_UNKNOWN)
8324 {
8325 }
8326 else if (got_type == GOT_NORMAL)
8327 {
8328 h->got.offset = htab->root.sgot->size;
8329 htab->root.sgot->size += GOT_ENTRY_SIZE;
8330 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8331 || h->root.type != bfd_link_hash_undefweak)
0e1862bb 8332 && (bfd_link_pic (info)
a377ae2a
SN
8333 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
8334 /* Undefined weak symbol in static PIE resolves to 0 without
8335 any dynamic relocations. */
8336 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
a06ea964
NC
8337 {
8338 htab->root.srelgot->size += RELOC_SIZE (htab);
8339 }
8340 }
8341 else
8342 {
8343 int indx;
8344 if (got_type & GOT_TLSDESC_GD)
8345 {
8346 eh->tlsdesc_got_jump_table_offset =
8347 (htab->root.sgotplt->size
8348 - aarch64_compute_jump_table_size (htab));
8349 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
8350 h->got.offset = (bfd_vma) - 2;
8351 }
8352
8353 if (got_type & GOT_TLS_GD)
8354 {
8355 h->got.offset = htab->root.sgot->size;
8356 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
8357 }
8358
8359 if (got_type & GOT_TLS_IE)
8360 {
8361 h->got.offset = htab->root.sgot->size;
8362 htab->root.sgot->size += GOT_ENTRY_SIZE;
8363 }
8364
8365 indx = h && h->dynindx != -1 ? h->dynindx : 0;
8366 if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8367 || h->root.type != bfd_link_hash_undefweak)
6dda7875 8368 && (!bfd_link_executable (info)
a06ea964
NC
8369 || indx != 0
8370 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
8371 {
8372 if (got_type & GOT_TLSDESC_GD)
8373 {
8374 htab->root.srelplt->size += RELOC_SIZE (htab);
8375 /* Note reloc_count not incremented here! We have
8376 already adjusted reloc_count for this relocation
8377 type. */
8378
8379 /* TLSDESC PLT is now needed, but not yet determined. */
8380 htab->tlsdesc_plt = (bfd_vma) - 1;
8381 }
8382
8383 if (got_type & GOT_TLS_GD)
8384 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
8385
8386 if (got_type & GOT_TLS_IE)
8387 htab->root.srelgot->size += RELOC_SIZE (htab);
8388 }
8389 }
8390 }
8391 else
8392 {
8393 h->got.offset = (bfd_vma) - 1;
8394 }
8395
8396 if (eh->dyn_relocs == NULL)
8397 return TRUE;
8398
8399 /* In the shared -Bsymbolic case, discard space allocated for
8400 dynamic pc-relative relocs against symbols which turn out to be
8401 defined in regular objects. For the normal shared case, discard
8402 space for pc-relative relocs that have become local due to symbol
8403 visibility changes. */
8404
0e1862bb 8405 if (bfd_link_pic (info))
a06ea964
NC
8406 {
8407 /* Relocs that use pc_count are those that appear on a call
07d6d2b8
AM
8408 insn, or certain REL relocs that can generated via assembly.
8409 We want calls to protected symbols to resolve directly to the
8410 function rather than going via the plt. If people want
8411 function pointer comparisons to work as expected then they
8412 should avoid writing weird assembly. */
a06ea964
NC
8413 if (SYMBOL_CALLS_LOCAL (info, h))
8414 {
8415 struct elf_dyn_relocs **pp;
8416
8417 for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
8418 {
8419 p->count -= p->pc_count;
8420 p->pc_count = 0;
8421 if (p->count == 0)
8422 *pp = p->next;
8423 else
8424 pp = &p->next;
8425 }
8426 }
8427
8428 /* Also discard relocs on undefined weak syms with non-default
07d6d2b8 8429 visibility. */
a06ea964
NC
8430 if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
8431 {
ddb7fd0f
L
8432 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
8433 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
a06ea964
NC
8434 eh->dyn_relocs = NULL;
8435
8436 /* Make sure undefined weak symbols are output as a dynamic
8437 symbol in PIEs. */
8438 else if (h->dynindx == -1
8439 && !h->forced_local
ff07562f 8440 && h->root.type == bfd_link_hash_undefweak
a06ea964
NC
8441 && !bfd_elf_link_record_dynamic_symbol (info, h))
8442 return FALSE;
8443 }
8444
8445 }
8446 else if (ELIMINATE_COPY_RELOCS)
8447 {
8448 /* For the non-shared case, discard space for relocs against
07d6d2b8
AM
8449 symbols which turn out to need copy relocs or are not
8450 dynamic. */
a06ea964
NC
8451
8452 if (!h->non_got_ref
8453 && ((h->def_dynamic
8454 && !h->def_regular)
8455 || (htab->root.dynamic_sections_created
8456 && (h->root.type == bfd_link_hash_undefweak
8457 || h->root.type == bfd_link_hash_undefined))))
8458 {
8459 /* Make sure this symbol is output as a dynamic symbol.
8460 Undefined weak syms won't yet be marked as dynamic. */
8461 if (h->dynindx == -1
8462 && !h->forced_local
ff07562f 8463 && h->root.type == bfd_link_hash_undefweak
a06ea964
NC
8464 && !bfd_elf_link_record_dynamic_symbol (info, h))
8465 return FALSE;
8466
8467 /* If that succeeded, we know we'll be keeping all the
8468 relocs. */
8469 if (h->dynindx != -1)
8470 goto keep;
8471 }
8472
8473 eh->dyn_relocs = NULL;
8474
8475 keep:;
8476 }
8477
8478 /* Finally, allocate space. */
8479 for (p = eh->dyn_relocs; p != NULL; p = p->next)
8480 {
8481 asection *sreloc;
8482
8483 sreloc = elf_section_data (p->sec)->sreloc;
8484
8485 BFD_ASSERT (sreloc != NULL);
8486
8487 sreloc->size += p->count * RELOC_SIZE (htab);
8488 }
8489
8490 return TRUE;
8491}
8492
1419bbe5
WN
8493/* Allocate space in .plt, .got and associated reloc sections for
8494 ifunc dynamic relocs. */
8495
8496static bfd_boolean
8497elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
8498 void *inf)
8499{
8500 struct bfd_link_info *info;
8501 struct elf_aarch64_link_hash_table *htab;
8502 struct elf_aarch64_link_hash_entry *eh;
8503
8504 /* An example of a bfd_link_hash_indirect symbol is versioned
8505 symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
8506 -> __gxx_personality_v0(bfd_link_hash_defined)
8507
8508 There is no need to process bfd_link_hash_indirect symbols here
8509 because we will also be presented with the concrete instance of
8510 the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
8511 called to copy all relevant data from the generic to the concrete
2d0ca824 8512 symbol instance. */
1419bbe5
WN
8513 if (h->root.type == bfd_link_hash_indirect)
8514 return TRUE;
8515
8516 if (h->root.type == bfd_link_hash_warning)
8517 h = (struct elf_link_hash_entry *) h->root.u.i.link;
8518
8519 info = (struct bfd_link_info *) inf;
8520 htab = elf_aarch64_hash_table (info);
8521
8522 eh = (struct elf_aarch64_link_hash_entry *) h;
8523
8524 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
8525 here if it is defined and referenced in a non-shared object. */
8526 if (h->type == STT_GNU_IFUNC
8527 && h->def_regular)
8528 return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
8529 &eh->dyn_relocs,
2df3368d 8530 NULL,
1419bbe5
WN
8531 htab->plt_entry_size,
8532 htab->plt_header_size,
233cc9c1
L
8533 GOT_ENTRY_SIZE,
8534 FALSE);
1419bbe5
WN
8535 return TRUE;
8536}
8537
8538/* Allocate space in .plt, .got and associated reloc sections for
8539 local dynamic relocs. */
8540
8541static bfd_boolean
8542elfNN_aarch64_allocate_local_dynrelocs (void **slot, void *inf)
8543{
8544 struct elf_link_hash_entry *h
8545 = (struct elf_link_hash_entry *) *slot;
8546
8547 if (h->type != STT_GNU_IFUNC
8548 || !h->def_regular
8549 || !h->ref_regular
8550 || !h->forced_local
8551 || h->root.type != bfd_link_hash_defined)
8552 abort ();
8553
8554 return elfNN_aarch64_allocate_dynrelocs (h, inf);
8555}
8556
8557/* Allocate space in .plt, .got and associated reloc sections for
8558 local ifunc dynamic relocs. */
8559
8560static bfd_boolean
8561elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
8562{
8563 struct elf_link_hash_entry *h
8564 = (struct elf_link_hash_entry *) *slot;
8565
8566 if (h->type != STT_GNU_IFUNC
8567 || !h->def_regular
8568 || !h->ref_regular
8569 || !h->forced_local
8570 || h->root.type != bfd_link_hash_defined)
8571 abort ();
8572
8573 return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
8574}
a06ea964 8575
63c1f59d
AM
8576/* Set DF_TEXTREL if we find any dynamic relocs that apply to
8577 read-only sections. */
c2170589
JW
8578
8579static bfd_boolean
63c1f59d 8580maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
c2170589 8581{
63c1f59d 8582 asection *sec;
c2170589 8583
63c1f59d
AM
8584 if (h->root.type == bfd_link_hash_indirect)
8585 return TRUE;
c2170589 8586
63c1f59d
AM
8587 sec = readonly_dynrelocs (h);
8588 if (sec != NULL)
8589 {
8590 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
c2170589 8591
63c1f59d
AM
8592 info->flags |= DF_TEXTREL;
8593 info->callbacks->minfo
c1c8c1ef 8594 (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
63c1f59d 8595 sec->owner, h->root.root.string, sec);
c2170589 8596
63c1f59d
AM
8597 /* Not an error, just cut short the traversal. */
8598 return FALSE;
c2170589
JW
8599 }
8600 return TRUE;
8601}
8602
a06ea964
NC
8603/* This is the most important function of all . Innocuosly named
8604 though ! */
2d0ca824 8605
a06ea964 8606static bfd_boolean
cec5225b 8607elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
a06ea964
NC
8608 struct bfd_link_info *info)
8609{
cec5225b 8610 struct elf_aarch64_link_hash_table *htab;
a06ea964
NC
8611 bfd *dynobj;
8612 asection *s;
8613 bfd_boolean relocs;
8614 bfd *ibfd;
8615
cec5225b 8616 htab = elf_aarch64_hash_table ((info));
a06ea964
NC
8617 dynobj = htab->root.dynobj;
8618
8619 BFD_ASSERT (dynobj != NULL);
8620
8621 if (htab->root.dynamic_sections_created)
8622 {
9b8b325a 8623 if (bfd_link_executable (info) && !info->nointerp)
a06ea964
NC
8624 {
8625 s = bfd_get_linker_section (dynobj, ".interp");
8626 if (s == NULL)
8627 abort ();
8628 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
8629 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
8630 }
8631 }
8632
8633 /* Set up .got offsets for local syms, and space for local dynamic
8634 relocs. */
c72f2fb2 8635 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
a06ea964
NC
8636 {
8637 struct elf_aarch64_local_symbol *locals = NULL;
8638 Elf_Internal_Shdr *symtab_hdr;
8639 asection *srel;
8640 unsigned int i;
8641
8642 if (!is_aarch64_elf (ibfd))
8643 continue;
8644
8645 for (s = ibfd->sections; s != NULL; s = s->next)
8646 {
8647 struct elf_dyn_relocs *p;
8648
8649 for (p = (struct elf_dyn_relocs *)
8650 (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
8651 {
8652 if (!bfd_is_abs_section (p->sec)
8653 && bfd_is_abs_section (p->sec->output_section))
8654 {
8655 /* Input section has been discarded, either because
8656 it is a copy of a linkonce section or due to
8657 linker script /DISCARD/, so we'll be discarding
8658 the relocs too. */
8659 }
8660 else if (p->count != 0)
8661 {
8662 srel = elf_section_data (p->sec)->sreloc;
8663 srel->size += p->count * RELOC_SIZE (htab);
8664 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
8665 info->flags |= DF_TEXTREL;
8666 }
8667 }
8668 }
8669
cec5225b 8670 locals = elf_aarch64_locals (ibfd);
a06ea964
NC
8671 if (!locals)
8672 continue;
8673
8674 symtab_hdr = &elf_symtab_hdr (ibfd);
8675 srel = htab->root.srelgot;
8676 for (i = 0; i < symtab_hdr->sh_info; i++)
8677 {
8678 locals[i].got_offset = (bfd_vma) - 1;
8679 locals[i].tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
8680 if (locals[i].got_refcount > 0)
8681 {
8682 unsigned got_type = locals[i].got_type;
8683 if (got_type & GOT_TLSDESC_GD)
8684 {
8685 locals[i].tlsdesc_got_jump_table_offset =
8686 (htab->root.sgotplt->size
8687 - aarch64_compute_jump_table_size (htab));
8688 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
8689 locals[i].got_offset = (bfd_vma) - 2;
8690 }
8691
8692 if (got_type & GOT_TLS_GD)
8693 {
8694 locals[i].got_offset = htab->root.sgot->size;
8695 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
8696 }
8697
b53b1bed
JW
8698 if (got_type & GOT_TLS_IE
8699 || got_type & GOT_NORMAL)
a06ea964
NC
8700 {
8701 locals[i].got_offset = htab->root.sgot->size;
8702 htab->root.sgot->size += GOT_ENTRY_SIZE;
8703 }
8704
8705 if (got_type == GOT_UNKNOWN)
8706 {
8707 }
8708
0e1862bb 8709 if (bfd_link_pic (info))
a06ea964
NC
8710 {
8711 if (got_type & GOT_TLSDESC_GD)
8712 {
8713 htab->root.srelplt->size += RELOC_SIZE (htab);
8714 /* Note RELOC_COUNT not incremented here! */
8715 htab->tlsdesc_plt = (bfd_vma) - 1;
8716 }
8717
8718 if (got_type & GOT_TLS_GD)
8719 htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
8720
b53b1bed
JW
8721 if (got_type & GOT_TLS_IE
8722 || got_type & GOT_NORMAL)
a06ea964
NC
8723 htab->root.srelgot->size += RELOC_SIZE (htab);
8724 }
8725 }
8726 else
8727 {
8728 locals[i].got_refcount = (bfd_vma) - 1;
8729 }
8730 }
8731 }
8732
8733
8734 /* Allocate global sym .plt and .got entries, and space for global
8735 sym dynamic relocs. */
cec5225b 8736 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
a06ea964
NC
8737 info);
8738
1419bbe5
WN
8739 /* Allocate global ifunc sym .plt and .got entries, and space for global
8740 ifunc sym dynamic relocs. */
8741 elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_ifunc_dynrelocs,
8742 info);
8743
8744 /* Allocate .plt and .got entries, and space for local symbols. */
8745 htab_traverse (htab->loc_hash_table,
8746 elfNN_aarch64_allocate_local_dynrelocs,
8747 info);
8748
8749 /* Allocate .plt and .got entries, and space for local ifunc symbols. */
8750 htab_traverse (htab->loc_hash_table,
8751 elfNN_aarch64_allocate_local_ifunc_dynrelocs,
8752 info);
a06ea964
NC
8753
8754 /* For every jump slot reserved in the sgotplt, reloc_count is
8755 incremented. However, when we reserve space for TLS descriptors,
8756 it's not incremented, so in order to compute the space reserved
8757 for them, it suffices to multiply the reloc count by the jump
8758 slot size. */
8759
8760 if (htab->root.srelplt)
8847944f 8761 htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab);
a06ea964
NC
8762
8763 if (htab->tlsdesc_plt)
8764 {
8765 if (htab->root.splt->size == 0)
8766 htab->root.splt->size += PLT_ENTRY_SIZE;
8767
8768 htab->tlsdesc_plt = htab->root.splt->size;
8769 htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
8770
8771 /* If we're not using lazy TLS relocations, don't generate the
07d6d2b8 8772 GOT entry required. */
a06ea964
NC
8773 if (!(info->flags & DF_BIND_NOW))
8774 {
8775 htab->dt_tlsdesc_got = htab->root.sgot->size;
8776 htab->root.sgot->size += GOT_ENTRY_SIZE;
8777 }
8778 }
8779
68fcca92 8780 /* Init mapping symbols information to use later to distingush between
4106101c
MS
8781 code and data while scanning for errata. */
8782 if (htab->fix_erratum_835769 || htab->fix_erratum_843419)
68fcca92
JW
8783 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
8784 {
8785 if (!is_aarch64_elf (ibfd))
8786 continue;
8787 bfd_elfNN_aarch64_init_maps (ibfd);
8788 }
8789
a06ea964
NC
8790 /* We now have determined the sizes of the various dynamic sections.
8791 Allocate memory for them. */
8792 relocs = FALSE;
8793 for (s = dynobj->sections; s != NULL; s = s->next)
8794 {
8795 if ((s->flags & SEC_LINKER_CREATED) == 0)
8796 continue;
8797
8798 if (s == htab->root.splt
8799 || s == htab->root.sgot
8800 || s == htab->root.sgotplt
8801 || s == htab->root.iplt
9d19e4fd 8802 || s == htab->root.igotplt
5474d94f
AM
8803 || s == htab->root.sdynbss
8804 || s == htab->root.sdynrelro)
a06ea964
NC
8805 {
8806 /* Strip this section if we don't need it; see the
8807 comment below. */
8808 }
8809 else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
8810 {
8811 if (s->size != 0 && s != htab->root.srelplt)
8812 relocs = TRUE;
8813
8814 /* We use the reloc_count field as a counter if we need
8815 to copy relocs into the output file. */
8816 if (s != htab->root.srelplt)
8817 s->reloc_count = 0;
8818 }
8819 else
8820 {
8821 /* It's not one of our sections, so don't allocate space. */
8822 continue;
8823 }
8824
8825 if (s->size == 0)
8826 {
8827 /* If we don't need this section, strip it from the
8828 output file. This is mostly to handle .rela.bss and
8829 .rela.plt. We must create both sections in
8830 create_dynamic_sections, because they must be created
8831 before the linker maps input sections to output
8832 sections. The linker does that before
8833 adjust_dynamic_symbol is called, and it is that
8834 function which decides whether anything needs to go
8835 into these sections. */
a06ea964
NC
8836 s->flags |= SEC_EXCLUDE;
8837 continue;
8838 }
8839
8840 if ((s->flags & SEC_HAS_CONTENTS) == 0)
8841 continue;
8842
8843 /* Allocate memory for the section contents. We use bfd_zalloc
07d6d2b8
AM
8844 here in case unused entries are not reclaimed before the
8845 section's contents are written out. This should not happen,
8846 but this way if it does, we get a R_AARCH64_NONE reloc instead
8847 of garbage. */
a06ea964
NC
8848 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
8849 if (s->contents == NULL)
8850 return FALSE;
8851 }
8852
8853 if (htab->root.dynamic_sections_created)
8854 {
8855 /* Add some entries to the .dynamic section. We fill in the
07d6d2b8
AM
8856 values later, in elfNN_aarch64_finish_dynamic_sections, but we
8857 must add the entries now so that we get the correct size for
8858 the .dynamic section. The DT_DEBUG entry is filled in by the
8859 dynamic linker and used by the debugger. */
a06ea964
NC
8860#define add_dynamic_entry(TAG, VAL) \
8861 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
8862
0e1862bb 8863 if (bfd_link_executable (info))
a06ea964
NC
8864 {
8865 if (!add_dynamic_entry (DT_DEBUG, 0))
8866 return FALSE;
8867 }
8868
8869 if (htab->root.splt->size != 0)
8870 {
8871 if (!add_dynamic_entry (DT_PLTGOT, 0)
8872 || !add_dynamic_entry (DT_PLTRELSZ, 0)
8873 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
8874 || !add_dynamic_entry (DT_JMPREL, 0))
8875 return FALSE;
8876
8877 if (htab->tlsdesc_plt
8878 && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
8879 || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
8880 return FALSE;
8881 }
8882
8883 if (relocs)
8884 {
8885 if (!add_dynamic_entry (DT_RELA, 0)
8886 || !add_dynamic_entry (DT_RELASZ, 0)
8887 || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
8888 return FALSE;
8889
8890 /* If any dynamic relocs apply to a read-only section,
8891 then we need a DT_TEXTREL entry. */
c2170589 8892 if ((info->flags & DF_TEXTREL) == 0)
63c1f59d 8893 elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
c2170589 8894
a06ea964
NC
8895 if ((info->flags & DF_TEXTREL) != 0)
8896 {
8897 if (!add_dynamic_entry (DT_TEXTREL, 0))
8898 return FALSE;
8899 }
8900 }
8901 }
8902#undef add_dynamic_entry
8903
8904 return TRUE;
a06ea964
NC
8905}
8906
8907static inline void
caed7120
YZ
8908elf_aarch64_update_plt_entry (bfd *output_bfd,
8909 bfd_reloc_code_real_type r_type,
8910 bfd_byte *plt_entry, bfd_vma value)
a06ea964 8911{
caed7120
YZ
8912 reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
8913
1d75a8e2
NC
8914 /* FIXME: We should check the return value from this function call. */
8915 (void) _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
a06ea964
NC
8916}
8917
8918static void
cec5225b
YZ
8919elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
8920 struct elf_aarch64_link_hash_table
1419bbe5
WN
8921 *htab, bfd *output_bfd,
8922 struct bfd_link_info *info)
a06ea964
NC
8923{
8924 bfd_byte *plt_entry;
8925 bfd_vma plt_index;
8926 bfd_vma got_offset;
8927 bfd_vma gotplt_entry_address;
8928 bfd_vma plt_entry_address;
8929 Elf_Internal_Rela rela;
8930 bfd_byte *loc;
1419bbe5
WN
8931 asection *plt, *gotplt, *relplt;
8932
8933 /* When building a static executable, use .iplt, .igot.plt and
8934 .rela.iplt sections for STT_GNU_IFUNC symbols. */
8935 if (htab->root.splt != NULL)
8936 {
8937 plt = htab->root.splt;
8938 gotplt = htab->root.sgotplt;
8939 relplt = htab->root.srelplt;
8940 }
8941 else
8942 {
8943 plt = htab->root.iplt;
8944 gotplt = htab->root.igotplt;
8945 relplt = htab->root.irelplt;
8946 }
8947
8948 /* Get the index in the procedure linkage table which
8949 corresponds to this symbol. This is the index of this symbol
8950 in all the symbols for which we are making plt entries. The
8951 first entry in the procedure linkage table is reserved.
a06ea964 8952
1419bbe5
WN
8953 Get the offset into the .got table of the entry that
8954 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
8955 bytes. The first three are reserved for the dynamic linker.
692e2b8b 8956
1419bbe5
WN
8957 For static executables, we don't reserve anything. */
8958
8959 if (plt == htab->root.splt)
8960 {
8961 plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
8962 got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
8963 }
8964 else
8965 {
8966 plt_index = h->plt.offset / htab->plt_entry_size;
8967 got_offset = plt_index * GOT_ENTRY_SIZE;
8968 }
8969
8970 plt_entry = plt->contents + h->plt.offset;
8971 plt_entry_address = plt->output_section->vma
f44a1f8e 8972 + plt->output_offset + h->plt.offset;
1419bbe5
WN
8973 gotplt_entry_address = gotplt->output_section->vma +
8974 gotplt->output_offset + got_offset;
a06ea964
NC
8975
8976 /* Copy in the boiler-plate for the PLTn entry. */
cec5225b 8977 memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
a06ea964
NC
8978
8979 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
8980 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
caed7120
YZ
8981 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
8982 plt_entry,
8983 PG (gotplt_entry_address) -
8984 PG (plt_entry_address));
a06ea964
NC
8985
8986 /* Fill in the lo12 bits for the load from the pltgot. */
caed7120
YZ
8987 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
8988 plt_entry + 4,
8989 PG_OFFSET (gotplt_entry_address));
a06ea964 8990
9aff4b7a 8991 /* Fill in the lo12 bits for the add from the pltgot entry. */
caed7120
YZ
8992 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
8993 plt_entry + 8,
8994 PG_OFFSET (gotplt_entry_address));
a06ea964
NC
8995
8996 /* All the GOTPLT Entries are essentially initialized to PLT0. */
cec5225b 8997 bfd_put_NN (output_bfd,
1419bbe5
WN
8998 plt->output_section->vma + plt->output_offset,
8999 gotplt->contents + got_offset);
a06ea964 9000
a06ea964 9001 rela.r_offset = gotplt_entry_address;
1419bbe5
WN
9002
9003 if (h->dynindx == -1
0e1862bb 9004 || ((bfd_link_executable (info)
1419bbe5
WN
9005 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
9006 && h->def_regular
9007 && h->type == STT_GNU_IFUNC))
9008 {
9009 /* If an STT_GNU_IFUNC symbol is locally defined, generate
9010 R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
9011 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
9012 rela.r_addend = (h->root.u.def.value
9013 + h->root.u.def.section->output_section->vma
9014 + h->root.u.def.section->output_offset);
9015 }
9016 else
9017 {
9018 /* Fill in the entry in the .rela.plt section. */
9019 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
9020 rela.r_addend = 0;
9021 }
a06ea964
NC
9022
9023 /* Compute the relocation entry to used based on PLT index and do
9024 not adjust reloc_count. The reloc_count has already been adjusted
9025 to account for this entry. */
1419bbe5 9026 loc = relplt->contents + plt_index * RELOC_SIZE (htab);
cec5225b 9027 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
a06ea964
NC
9028}
9029
9030/* Size sections even though they're not dynamic. We use it to setup
9031 _TLS_MODULE_BASE_, if needed. */
9032
9033static bfd_boolean
cec5225b 9034elfNN_aarch64_always_size_sections (bfd *output_bfd,
a06ea964
NC
9035 struct bfd_link_info *info)
9036{
9037 asection *tls_sec;
9038
0e1862bb 9039 if (bfd_link_relocatable (info))
a06ea964
NC
9040 return TRUE;
9041
9042 tls_sec = elf_hash_table (info)->tls_sec;
9043
9044 if (tls_sec)
9045 {
9046 struct elf_link_hash_entry *tlsbase;
9047
9048 tlsbase = elf_link_hash_lookup (elf_hash_table (info),
9049 "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
9050
9051 if (tlsbase)
9052 {
9053 struct bfd_link_hash_entry *h = NULL;
9054 const struct elf_backend_data *bed =
9055 get_elf_backend_data (output_bfd);
9056
9057 if (!(_bfd_generic_link_add_one_symbol
9058 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
9059 tls_sec, 0, NULL, FALSE, bed->collect, &h)))
9060 return FALSE;
9061
9062 tlsbase->type = STT_TLS;
9063 tlsbase = (struct elf_link_hash_entry *) h;
9064 tlsbase->def_regular = 1;
9065 tlsbase->other = STV_HIDDEN;
9066 (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
9067 }
9068 }
9069
9070 return TRUE;
9071}
9072
9073/* Finish up dynamic symbol handling. We set the contents of various
9074 dynamic sections here. */
2d0ca824 9075
a06ea964 9076static bfd_boolean
cec5225b 9077elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
a06ea964
NC
9078 struct bfd_link_info *info,
9079 struct elf_link_hash_entry *h,
9080 Elf_Internal_Sym *sym)
9081{
cec5225b
YZ
9082 struct elf_aarch64_link_hash_table *htab;
9083 htab = elf_aarch64_hash_table (info);
a06ea964
NC
9084
9085 if (h->plt.offset != (bfd_vma) - 1)
9086 {
1419bbe5
WN
9087 asection *plt, *gotplt, *relplt;
9088
a06ea964 9089 /* This symbol has an entry in the procedure linkage table. Set
07d6d2b8 9090 it up. */
a06ea964 9091
1419bbe5
WN
9092 /* When building a static executable, use .iplt, .igot.plt and
9093 .rela.iplt sections for STT_GNU_IFUNC symbols. */
9094 if (htab->root.splt != NULL)
9095 {
9096 plt = htab->root.splt;
9097 gotplt = htab->root.sgotplt;
9098 relplt = htab->root.srelplt;
9099 }
9100 else
9101 {
9102 plt = htab->root.iplt;
9103 gotplt = htab->root.igotplt;
9104 relplt = htab->root.irelplt;
9105 }
9106
9107 /* This symbol has an entry in the procedure linkage table. Set
9108 it up. */
9109 if ((h->dynindx == -1
0e1862bb 9110 && !((h->forced_local || bfd_link_executable (info))
1419bbe5
WN
9111 && h->def_regular
9112 && h->type == STT_GNU_IFUNC))
9113 || plt == NULL
9114 || gotplt == NULL
9115 || relplt == NULL)
f955cccf 9116 return FALSE;
a06ea964 9117
1419bbe5 9118 elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd, info);
a06ea964
NC
9119 if (!h->def_regular)
9120 {
9121 /* Mark the symbol as undefined, rather than as defined in
46b87d49 9122 the .plt section. */
a06ea964 9123 sym->st_shndx = SHN_UNDEF;
46b87d49
WN
9124 /* If the symbol is weak we need to clear the value.
9125 Otherwise, the PLT entry would provide a definition for
9126 the symbol even if the symbol wasn't defined anywhere,
9127 and so the symbol would never be NULL. Leave the value if
9128 there were any relocations where pointer equality matters
9129 (this is a clue for the dynamic linker, to make function
9130 pointer comparisons work between an application and shared
9131 library). */
9132 if (!h->ref_regular_nonweak || !h->pointer_equality_needed)
9133 sym->st_value = 0;
a06ea964
NC
9134 }
9135 }
9136
9137 if (h->got.offset != (bfd_vma) - 1
a377ae2a
SN
9138 && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
9139 /* Undefined weak symbol in static PIE resolves to 0 without
9140 any dynamic relocations. */
9141 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
a06ea964
NC
9142 {
9143 Elf_Internal_Rela rela;
9144 bfd_byte *loc;
9145
9146 /* This symbol has an entry in the global offset table. Set it
07d6d2b8 9147 up. */
a06ea964
NC
9148 if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
9149 abort ();
9150
9151 rela.r_offset = (htab->root.sgot->output_section->vma
9152 + htab->root.sgot->output_offset
9153 + (h->got.offset & ~(bfd_vma) 1));
9154
49206388
WN
9155 if (h->def_regular
9156 && h->type == STT_GNU_IFUNC)
9157 {
0e1862bb 9158 if (bfd_link_pic (info))
49206388
WN
9159 {
9160 /* Generate R_AARCH64_GLOB_DAT. */
9161 goto do_glob_dat;
9162 }
9163 else
9164 {
9165 asection *plt;
9166
9167 if (!h->pointer_equality_needed)
9168 abort ();
9169
9170 /* For non-shared object, we can't use .got.plt, which
9171 contains the real function address if we need pointer
9172 equality. We load the GOT entry with the PLT entry. */
9173 plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
9174 bfd_put_NN (output_bfd, (plt->output_section->vma
9175 + plt->output_offset
9176 + h->plt.offset),
9177 htab->root.sgot->contents
9178 + (h->got.offset & ~(bfd_vma) 1));
9179 return TRUE;
9180 }
9181 }
0e1862bb 9182 else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
a06ea964 9183 {
0ee3a6db 9184 if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
a06ea964
NC
9185 return FALSE;
9186
9187 BFD_ASSERT ((h->got.offset & 1) != 0);
a6bb11b2 9188 rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
a06ea964
NC
9189 rela.r_addend = (h->root.u.def.value
9190 + h->root.u.def.section->output_section->vma
9191 + h->root.u.def.section->output_offset);
9192 }
9193 else
9194 {
49206388 9195do_glob_dat:
a06ea964 9196 BFD_ASSERT ((h->got.offset & 1) == 0);
cec5225b 9197 bfd_put_NN (output_bfd, (bfd_vma) 0,
a06ea964 9198 htab->root.sgot->contents + h->got.offset);
a6bb11b2 9199 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
a06ea964
NC
9200 rela.r_addend = 0;
9201 }
9202
9203 loc = htab->root.srelgot->contents;
9204 loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
cec5225b 9205 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
a06ea964
NC
9206 }
9207
9208 if (h->needs_copy)
9209 {
9210 Elf_Internal_Rela rela;
5474d94f 9211 asection *s;
a06ea964
NC
9212 bfd_byte *loc;
9213
9214 /* This symbol needs a copy reloc. Set it up. */
a06ea964
NC
9215 if (h->dynindx == -1
9216 || (h->root.type != bfd_link_hash_defined
9217 && h->root.type != bfd_link_hash_defweak)
9d19e4fd 9218 || htab->root.srelbss == NULL)
a06ea964
NC
9219 abort ();
9220
9221 rela.r_offset = (h->root.u.def.value
9222 + h->root.u.def.section->output_section->vma
9223 + h->root.u.def.section->output_offset);
a6bb11b2 9224 rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
a06ea964 9225 rela.r_addend = 0;
afbf7e8e 9226 if (h->root.u.def.section == htab->root.sdynrelro)
5474d94f
AM
9227 s = htab->root.sreldynrelro;
9228 else
9229 s = htab->root.srelbss;
9230 loc = s->contents + s->reloc_count++ * RELOC_SIZE (htab);
cec5225b 9231 bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
a06ea964
NC
9232 }
9233
9234 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
9235 be NULL for local symbols. */
9236 if (sym != NULL
9637f6ef 9237 && (h == elf_hash_table (info)->hdynamic
a06ea964
NC
9238 || h == elf_hash_table (info)->hgot))
9239 sym->st_shndx = SHN_ABS;
9240
9241 return TRUE;
9242}
9243
1419bbe5
WN
9244/* Finish up local dynamic symbol handling. We set the contents of
9245 various dynamic sections here. */
9246
9247static bfd_boolean
9248elfNN_aarch64_finish_local_dynamic_symbol (void **slot, void *inf)
9249{
9250 struct elf_link_hash_entry *h
9251 = (struct elf_link_hash_entry *) *slot;
9252 struct bfd_link_info *info
9253 = (struct bfd_link_info *) inf;
9254
9255 return elfNN_aarch64_finish_dynamic_symbol (info->output_bfd,
9256 info, h, NULL);
9257}
9258
a06ea964 9259static void
cec5225b
YZ
9260elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
9261 struct elf_aarch64_link_hash_table
a06ea964
NC
9262 *htab)
9263{
9264 /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
9265 small and large plts and at the minute just generates
9266 the small PLT. */
9267
cec5225b 9268 /* PLT0 of the small PLT looks like this in ELF64 -
a06ea964
NC
9269 stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
9270 adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
9271 ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
9272 // symbol resolver
9273 add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
9274 // GOTPLT entry for this.
9275 br x17
cec5225b 9276 PLT0 will be slightly different in ELF32 due to different got entry
2d0ca824 9277 size. */
caed7120 9278 bfd_vma plt_got_2nd_ent; /* Address of GOT[2]. */
a06ea964
NC
9279 bfd_vma plt_base;
9280
9281
cec5225b 9282 memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry,
a06ea964
NC
9283 PLT_ENTRY_SIZE);
9284 elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
9285 PLT_ENTRY_SIZE;
9286
caed7120
YZ
9287 plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
9288 + htab->root.sgotplt->output_offset
9289 + GOT_ENTRY_SIZE * 2);
a06ea964
NC
9290
9291 plt_base = htab->root.splt->output_section->vma +
f44a1f8e 9292 htab->root.splt->output_offset;
a06ea964
NC
9293
9294 /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
9295 ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
caed7120
YZ
9296 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
9297 htab->root.splt->contents + 4,
9298 PG (plt_got_2nd_ent) - PG (plt_base + 4));
a06ea964 9299
caed7120
YZ
9300 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
9301 htab->root.splt->contents + 8,
9302 PG_OFFSET (plt_got_2nd_ent));
a06ea964 9303
caed7120
YZ
9304 elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
9305 htab->root.splt->contents + 12,
9306 PG_OFFSET (plt_got_2nd_ent));
a06ea964
NC
9307}
9308
9309static bfd_boolean
cec5225b 9310elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
a06ea964
NC
9311 struct bfd_link_info *info)
9312{
cec5225b 9313 struct elf_aarch64_link_hash_table *htab;
a06ea964
NC
9314 bfd *dynobj;
9315 asection *sdyn;
9316
cec5225b 9317 htab = elf_aarch64_hash_table (info);
a06ea964
NC
9318 dynobj = htab->root.dynobj;
9319 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
9320
9321 if (htab->root.dynamic_sections_created)
9322 {
cec5225b 9323 ElfNN_External_Dyn *dyncon, *dynconend;
a06ea964
NC
9324
9325 if (sdyn == NULL || htab->root.sgot == NULL)
9326 abort ();
9327
cec5225b
YZ
9328 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
9329 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
a06ea964
NC
9330 for (; dyncon < dynconend; dyncon++)
9331 {
9332 Elf_Internal_Dyn dyn;
9333 asection *s;
9334
cec5225b 9335 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
a06ea964
NC
9336
9337 switch (dyn.d_tag)
9338 {
9339 default:
9340 continue;
9341
9342 case DT_PLTGOT:
9343 s = htab->root.sgotplt;
9344 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
9345 break;
9346
9347 case DT_JMPREL:
4ade44b7
AM
9348 s = htab->root.srelplt;
9349 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
a06ea964
NC
9350 break;
9351
9352 case DT_PLTRELSZ:
c955de36 9353 s = htab->root.srelplt;
a06ea964
NC
9354 dyn.d_un.d_val = s->size;
9355 break;
9356
a06ea964
NC
9357 case DT_TLSDESC_PLT:
9358 s = htab->root.splt;
9359 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
9360 + htab->tlsdesc_plt;
9361 break;
9362
9363 case DT_TLSDESC_GOT:
9364 s = htab->root.sgot;
9365 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
9366 + htab->dt_tlsdesc_got;
9367 break;
9368 }
9369
cec5225b 9370 bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
a06ea964
NC
9371 }
9372
9373 }
9374
9375 /* Fill in the special first entry in the procedure linkage table. */
9376 if (htab->root.splt && htab->root.splt->size > 0)
9377 {
cec5225b 9378 elfNN_aarch64_init_small_plt0_entry (output_bfd, htab);
a06ea964
NC
9379
9380 elf_section_data (htab->root.splt->output_section)->
9381 this_hdr.sh_entsize = htab->plt_entry_size;
9382
9383
9384 if (htab->tlsdesc_plt)
9385 {
cec5225b 9386 bfd_put_NN (output_bfd, (bfd_vma) 0,
a06ea964
NC
9387 htab->root.sgot->contents + htab->dt_tlsdesc_got);
9388
9389 memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
cec5225b
YZ
9390 elfNN_aarch64_tlsdesc_small_plt_entry,
9391 sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));
a06ea964
NC
9392
9393 {
9394 bfd_vma adrp1_addr =
9395 htab->root.splt->output_section->vma
9396 + htab->root.splt->output_offset + htab->tlsdesc_plt + 4;
9397
caed7120 9398 bfd_vma adrp2_addr = adrp1_addr + 4;
a06ea964
NC
9399
9400 bfd_vma got_addr =
9401 htab->root.sgot->output_section->vma
9402 + htab->root.sgot->output_offset;
9403
9404 bfd_vma pltgot_addr =
9405 htab->root.sgotplt->output_section->vma
9406 + htab->root.sgotplt->output_offset;
9407
9408 bfd_vma dt_tlsdesc_got = got_addr + htab->dt_tlsdesc_got;
caed7120
YZ
9409
9410 bfd_byte *plt_entry =
9411 htab->root.splt->contents + htab->tlsdesc_plt;
a06ea964
NC
9412
9413 /* adrp x2, DT_TLSDESC_GOT */
caed7120
YZ
9414 elf_aarch64_update_plt_entry (output_bfd,
9415 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
9416 plt_entry + 4,
9417 (PG (dt_tlsdesc_got)
9418 - PG (adrp1_addr)));
a06ea964
NC
9419
9420 /* adrp x3, 0 */
caed7120
YZ
9421 elf_aarch64_update_plt_entry (output_bfd,
9422 BFD_RELOC_AARCH64_ADR_HI21_PCREL,
9423 plt_entry + 8,
9424 (PG (pltgot_addr)
9425 - PG (adrp2_addr)));
a06ea964
NC
9426
9427 /* ldr x2, [x2, #0] */
caed7120
YZ
9428 elf_aarch64_update_plt_entry (output_bfd,
9429 BFD_RELOC_AARCH64_LDSTNN_LO12,
9430 plt_entry + 12,
9431 PG_OFFSET (dt_tlsdesc_got));
a06ea964
NC
9432
9433 /* add x3, x3, 0 */
caed7120
YZ
9434 elf_aarch64_update_plt_entry (output_bfd,
9435 BFD_RELOC_AARCH64_ADD_LO12,
9436 plt_entry + 16,
9437 PG_OFFSET (pltgot_addr));
a06ea964
NC
9438 }
9439 }
9440 }
9441
9442 if (htab->root.sgotplt)
9443 {
9444 if (bfd_is_abs_section (htab->root.sgotplt->output_section))
9445 {
4eca0228 9446 _bfd_error_handler
871b3ab2 9447 (_("discarded output section: `%pA'"), htab->root.sgotplt);
a06ea964
NC
9448 return FALSE;
9449 }
9450
9451 /* Fill in the first three entries in the global offset table. */
9452 if (htab->root.sgotplt->size > 0)
9453 {
8db339a6
MS
9454 bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
9455
a06ea964 9456 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
cec5225b 9457 bfd_put_NN (output_bfd,
a06ea964
NC
9458 (bfd_vma) 0,
9459 htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
cec5225b 9460 bfd_put_NN (output_bfd,
a06ea964
NC
9461 (bfd_vma) 0,
9462 htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
9463 }
9464
8db339a6
MS
9465 if (htab->root.sgot)
9466 {
9467 if (htab->root.sgot->size > 0)
9468 {
9469 bfd_vma addr =
9470 sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
9471 bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
9472 }
9473 }
9474
a06ea964
NC
9475 elf_section_data (htab->root.sgotplt->output_section)->
9476 this_hdr.sh_entsize = GOT_ENTRY_SIZE;
9477 }
9478
9479 if (htab->root.sgot && htab->root.sgot->size > 0)
9480 elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
9481 = GOT_ENTRY_SIZE;
9482
1419bbe5
WN
9483 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
9484 htab_traverse (htab->loc_hash_table,
9485 elfNN_aarch64_finish_local_dynamic_symbol,
9486 info);
9487
a06ea964
NC
9488 return TRUE;
9489}
9490
9491/* Return address for Ith PLT stub in section PLT, for relocation REL
9492 or (bfd_vma) -1 if it should not be included. */
9493
9494static bfd_vma
cec5225b 9495elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
a06ea964
NC
9496 const arelent *rel ATTRIBUTE_UNUSED)
9497{
9498 return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
9499}
9500
d691934d
NC
9501/* Returns TRUE if NAME is an AArch64 mapping symbol.
9502 The ARM ELF standard defines $x (for A64 code) and $d (for data).
9503 It also allows a period initiated suffix to be added to the symbol, ie:
9504 "$[adtx]\.[:sym_char]+". */
9505
9506static bfd_boolean
9507is_aarch64_mapping_symbol (const char * name)
9508{
9509 return name != NULL /* Paranoia. */
9510 && name[0] == '$' /* Note: if objcopy --prefix-symbols has been used then
9511 the mapping symbols could have acquired a prefix.
9512 We do not support this here, since such symbols no
9513 longer conform to the ARM ELF ABI. */
9514 && (name[1] == 'd' || name[1] == 'x')
9515 && (name[2] == 0 || name[2] == '.');
9516 /* FIXME: Strictly speaking the symbol is only a valid mapping symbol if
9517 any characters that follow the period are legal characters for the body
9518 of a symbol's name. For now we just assume that this is the case. */
9519}
9520
9521/* Make sure that mapping symbols in object files are not removed via the
9522 "strip --strip-unneeded" tool. These symbols might needed in order to
9523 correctly generate linked files. Once an object file has been linked,
9524 it should be safe to remove them. */
9525
9526static void
9527elfNN_aarch64_backend_symbol_processing (bfd *abfd, asymbol *sym)
9528{
9529 if (((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
9530 && sym->section != bfd_abs_section_ptr
9531 && is_aarch64_mapping_symbol (sym->name))
9532 sym->flags |= BSF_KEEP;
9533}
9534
a06ea964
NC
9535
9536/* We use this so we can override certain functions
9537 (though currently we don't). */
9538
cec5225b 9539const struct elf_size_info elfNN_aarch64_size_info =
a06ea964 9540{
cec5225b
YZ
9541 sizeof (ElfNN_External_Ehdr),
9542 sizeof (ElfNN_External_Phdr),
9543 sizeof (ElfNN_External_Shdr),
9544 sizeof (ElfNN_External_Rel),
9545 sizeof (ElfNN_External_Rela),
9546 sizeof (ElfNN_External_Sym),
9547 sizeof (ElfNN_External_Dyn),
a06ea964
NC
9548 sizeof (Elf_External_Note),
9549 4, /* Hash table entry size. */
9550 1, /* Internal relocs per external relocs. */
cec5225b
YZ
9551 ARCH_SIZE, /* Arch size. */
9552 LOG_FILE_ALIGN, /* Log_file_align. */
9553 ELFCLASSNN, EV_CURRENT,
9554 bfd_elfNN_write_out_phdrs,
9555 bfd_elfNN_write_shdrs_and_ehdr,
9556 bfd_elfNN_checksum_contents,
9557 bfd_elfNN_write_relocs,
9558 bfd_elfNN_swap_symbol_in,
9559 bfd_elfNN_swap_symbol_out,
9560 bfd_elfNN_slurp_reloc_table,
9561 bfd_elfNN_slurp_symbol_table,
9562 bfd_elfNN_swap_dyn_in,
9563 bfd_elfNN_swap_dyn_out,
9564 bfd_elfNN_swap_reloc_in,
9565 bfd_elfNN_swap_reloc_out,
9566 bfd_elfNN_swap_reloca_in,
9567 bfd_elfNN_swap_reloca_out
a06ea964
NC
9568};
9569
9570#define ELF_ARCH bfd_arch_aarch64
9571#define ELF_MACHINE_CODE EM_AARCH64
9572#define ELF_MAXPAGESIZE 0x10000
9573#define ELF_MINPAGESIZE 0x1000
9574#define ELF_COMMONPAGESIZE 0x1000
9575
07d6d2b8 9576#define bfd_elfNN_close_and_cleanup \
cec5225b 9577 elfNN_aarch64_close_and_cleanup
a06ea964 9578
07d6d2b8 9579#define bfd_elfNN_bfd_free_cached_info \
cec5225b 9580 elfNN_aarch64_bfd_free_cached_info
a06ea964 9581
cec5225b
YZ
9582#define bfd_elfNN_bfd_is_target_special_symbol \
9583 elfNN_aarch64_is_target_special_symbol
a06ea964 9584
07d6d2b8 9585#define bfd_elfNN_bfd_link_hash_table_create \
cec5225b 9586 elfNN_aarch64_link_hash_table_create
a06ea964 9587
cec5225b
YZ
9588#define bfd_elfNN_bfd_merge_private_bfd_data \
9589 elfNN_aarch64_merge_private_bfd_data
a06ea964 9590
cec5225b
YZ
9591#define bfd_elfNN_bfd_print_private_bfd_data \
9592 elfNN_aarch64_print_private_bfd_data
a06ea964 9593
cec5225b
YZ
9594#define bfd_elfNN_bfd_reloc_type_lookup \
9595 elfNN_aarch64_reloc_type_lookup
a06ea964 9596
cec5225b
YZ
9597#define bfd_elfNN_bfd_reloc_name_lookup \
9598 elfNN_aarch64_reloc_name_lookup
a06ea964 9599
cec5225b
YZ
9600#define bfd_elfNN_bfd_set_private_flags \
9601 elfNN_aarch64_set_private_flags
a06ea964 9602
cec5225b
YZ
9603#define bfd_elfNN_find_inliner_info \
9604 elfNN_aarch64_find_inliner_info
a06ea964 9605
cec5225b
YZ
9606#define bfd_elfNN_find_nearest_line \
9607 elfNN_aarch64_find_nearest_line
a06ea964 9608
cec5225b
YZ
9609#define bfd_elfNN_mkobject \
9610 elfNN_aarch64_mkobject
a06ea964 9611
cec5225b
YZ
9612#define bfd_elfNN_new_section_hook \
9613 elfNN_aarch64_new_section_hook
a06ea964
NC
9614
9615#define elf_backend_adjust_dynamic_symbol \
cec5225b 9616 elfNN_aarch64_adjust_dynamic_symbol
a06ea964
NC
9617
9618#define elf_backend_always_size_sections \
cec5225b 9619 elfNN_aarch64_always_size_sections
a06ea964
NC
9620
9621#define elf_backend_check_relocs \
cec5225b 9622 elfNN_aarch64_check_relocs
a06ea964
NC
9623
9624#define elf_backend_copy_indirect_symbol \
cec5225b 9625 elfNN_aarch64_copy_indirect_symbol
a06ea964
NC
9626
9627/* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
9628 to them in our hash. */
9629#define elf_backend_create_dynamic_sections \
cec5225b 9630 elfNN_aarch64_create_dynamic_sections
a06ea964
NC
9631
9632#define elf_backend_init_index_section \
9633 _bfd_elf_init_2_index_sections
9634
a06ea964 9635#define elf_backend_finish_dynamic_sections \
cec5225b 9636 elfNN_aarch64_finish_dynamic_sections
a06ea964
NC
9637
9638#define elf_backend_finish_dynamic_symbol \
cec5225b 9639 elfNN_aarch64_finish_dynamic_symbol
a06ea964 9640
a06ea964 9641#define elf_backend_object_p \
cec5225b 9642 elfNN_aarch64_object_p
a06ea964 9643
07d6d2b8 9644#define elf_backend_output_arch_local_syms \
cec5225b 9645 elfNN_aarch64_output_arch_local_syms
a06ea964
NC
9646
9647#define elf_backend_plt_sym_val \
cec5225b 9648 elfNN_aarch64_plt_sym_val
a06ea964
NC
9649
9650#define elf_backend_post_process_headers \
cec5225b 9651 elfNN_aarch64_post_process_headers
a06ea964
NC
9652
9653#define elf_backend_relocate_section \
cec5225b 9654 elfNN_aarch64_relocate_section
a06ea964
NC
9655
9656#define elf_backend_reloc_type_class \
cec5225b 9657 elfNN_aarch64_reloc_type_class
a06ea964 9658
a06ea964 9659#define elf_backend_section_from_shdr \
cec5225b 9660 elfNN_aarch64_section_from_shdr
a06ea964
NC
9661
9662#define elf_backend_size_dynamic_sections \
cec5225b 9663 elfNN_aarch64_size_dynamic_sections
a06ea964
NC
9664
9665#define elf_backend_size_info \
cec5225b 9666 elfNN_aarch64_size_info
a06ea964 9667
68fcca92
JW
9668#define elf_backend_write_section \
9669 elfNN_aarch64_write_section
9670
d691934d
NC
9671#define elf_backend_symbol_processing \
9672 elfNN_aarch64_backend_symbol_processing
9673
a06ea964 9674#define elf_backend_can_refcount 1
59c108f7 9675#define elf_backend_can_gc_sections 1
a06ea964
NC
9676#define elf_backend_plt_readonly 1
9677#define elf_backend_want_got_plt 1
9678#define elf_backend_want_plt_sym 0
5474d94f 9679#define elf_backend_want_dynrelro 1
a06ea964
NC
9680#define elf_backend_may_use_rel_p 0
9681#define elf_backend_may_use_rela_p 1
9682#define elf_backend_default_use_rela_p 1
07d6d2b8 9683#define elf_backend_rela_normal 1
64f52338 9684#define elf_backend_dtrel_excludes_plt 1
a06ea964 9685#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
c495064d 9686#define elf_backend_default_execstack 0
32f573bc 9687#define elf_backend_extern_protected_data 1
7f784814 9688#define elf_backend_hash_symbol elf_aarch64_hash_symbol
a06ea964 9689
07d6d2b8 9690#undef elf_backend_obj_attrs_section
a06ea964
NC
9691#define elf_backend_obj_attrs_section ".ARM.attributes"
9692
cec5225b 9693#include "elfNN-target.h"
a75cf613
ES
9694
9695/* CloudABI support. */
9696
9697#undef TARGET_LITTLE_SYM
9698#define TARGET_LITTLE_SYM aarch64_elfNN_le_cloudabi_vec
9699#undef TARGET_LITTLE_NAME
9700#define TARGET_LITTLE_NAME "elfNN-littleaarch64-cloudabi"
9701#undef TARGET_BIG_SYM
9702#define TARGET_BIG_SYM aarch64_elfNN_be_cloudabi_vec
9703#undef TARGET_BIG_NAME
9704#define TARGET_BIG_NAME "elfNN-bigaarch64-cloudabi"
9705
9706#undef ELF_OSABI
9707#define ELF_OSABI ELFOSABI_CLOUDABI
9708
9709#undef elfNN_bed
9710#define elfNN_bed elfNN_aarch64_cloudabi_bed
9711
9712#include "elfNN-target.h"