1 /* AArch64-specific support for ELF.
2 Copyright (C) 2009-2023 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
24 #include "elfxx-aarch64.h"
28 #define MASK(n) ((1u << (n)) - 1)
30 /* Sign-extend VALUE, which has the indicated number of BITS. */
33 _bfd_aarch64_sign_extend (bfd_vma value
, int bits
)
35 if (value
& ((bfd_vma
) 1 << (bits
- 1)))
36 /* VALUE is negative. */
37 value
|= ((bfd_vma
) - 1) << bits
;
42 /* Decode the IMM field of ADRP. */
45 _bfd_aarch64_decode_adrp_imm (uint32_t insn
)
47 return (((insn
>> 5) & MASK (19)) << 2) | ((insn
>> 29) & MASK (2));
50 /* Reencode the imm field of add immediate. */
51 static inline uint32_t
52 reencode_add_imm (uint32_t insn
, uint32_t imm
)
54 return (insn
& ~(MASK (12) << 10)) | ((imm
& MASK (12)) << 10);
57 /* Reencode the IMM field of ADR. */
60 _bfd_aarch64_reencode_adr_imm (uint32_t insn
, uint32_t imm
)
62 return (insn
& ~((MASK (2) << 29) | (MASK (19) << 5)))
63 | ((imm
& MASK (2)) << 29) | ((imm
& (MASK (19) << 2)) << 3);
66 /* Reencode the imm field of ld/st pos immediate. */
67 static inline uint32_t
68 reencode_ldst_pos_imm (uint32_t insn
, uint32_t imm
)
70 return (insn
& ~(MASK (12) << 10)) | ((imm
& MASK (12)) << 10);
73 /* Encode the 26-bit offset of unconditional branch. */
74 static inline uint32_t
75 reencode_branch_ofs_26 (uint32_t insn
, uint32_t ofs
)
77 return (insn
& ~MASK (26)) | (ofs
& MASK (26));
80 /* Encode the 19-bit offset of conditional branch and compare & branch. */
81 static inline uint32_t
82 reencode_cond_branch_ofs_19 (uint32_t insn
, uint32_t ofs
)
84 return (insn
& ~(MASK (19) << 5)) | ((ofs
& MASK (19)) << 5);
87 /* Decode the 19-bit offset of load literal. */
88 static inline uint32_t
89 reencode_ld_lit_ofs_19 (uint32_t insn
, uint32_t ofs
)
91 return (insn
& ~(MASK (19) << 5)) | ((ofs
& MASK (19)) << 5);
94 /* Encode the 14-bit offset of test & branch. */
95 static inline uint32_t
96 reencode_tst_branch_ofs_14 (uint32_t insn
, uint32_t ofs
)
98 return (insn
& ~(MASK (14) << 5)) | ((ofs
& MASK (14)) << 5);
101 /* Reencode the imm field of move wide. */
102 static inline uint32_t
103 reencode_movw_imm (uint32_t insn
, uint32_t imm
)
105 return (insn
& ~(MASK (16) << 5)) | ((imm
& MASK (16)) << 5);
108 /* Reencode mov[zn] to movz. */
109 static inline uint32_t
110 reencode_movzn_to_movz (uint32_t opcode
)
112 return opcode
| (1 << 30);
115 /* Reencode mov[zn] to movn. */
116 static inline uint32_t
117 reencode_movzn_to_movn (uint32_t opcode
)
119 return opcode
& ~(1 << 30);
122 /* Return non-zero if the indicated VALUE has overflowed the maximum
123 range expressible by a unsigned number with the indicated number of
126 static bfd_reloc_status_type
127 aarch64_unsigned_overflow (bfd_vma value
, unsigned int bits
)
130 if (bits
>= sizeof (bfd_vma
) * 8)
132 lim
= (bfd_vma
) 1 << bits
;
134 return bfd_reloc_overflow
;
138 /* Return non-zero if the indicated VALUE has overflowed the maximum
139 range expressible by an signed number with the indicated number of
142 static bfd_reloc_status_type
143 aarch64_signed_overflow (bfd_vma value
, unsigned int bits
)
145 bfd_signed_vma svalue
= (bfd_signed_vma
) value
;
148 if (bits
>= sizeof (bfd_vma
) * 8)
150 lim
= (bfd_signed_vma
) 1 << (bits
- 1);
151 if (svalue
< -lim
|| svalue
>= lim
)
152 return bfd_reloc_overflow
;
156 /* Insert the addend/value into the instruction or data object being
158 bfd_reloc_status_type
159 _bfd_aarch64_elf_put_addend (bfd
*abfd
,
160 bfd_byte
*address
, bfd_reloc_code_real_type r_type
,
161 reloc_howto_type
*howto
, bfd_signed_vma addend
)
163 bfd_reloc_status_type status
= bfd_reloc_ok
;
164 bfd_signed_vma old_addend
= addend
;
168 size
= bfd_get_reloc_size (howto
);
174 contents
= bfd_get_16 (abfd
, address
);
177 if (howto
->src_mask
!= 0xffffffff)
178 /* Must be 32-bit instruction, always little-endian. */
179 contents
= bfd_getl32 (address
);
181 /* Must be 32-bit data (endianness dependent). */
182 contents
= bfd_get_32 (abfd
, address
);
185 contents
= bfd_get_64 (abfd
, address
);
191 switch (howto
->complain_on_overflow
)
193 case complain_overflow_dont
:
195 case complain_overflow_signed
:
196 status
= aarch64_signed_overflow (addend
,
197 howto
->bitsize
+ howto
->rightshift
);
199 case complain_overflow_unsigned
:
200 status
= aarch64_unsigned_overflow (addend
,
201 howto
->bitsize
+ howto
->rightshift
);
203 case complain_overflow_bitfield
:
208 addend
>>= howto
->rightshift
;
212 case BFD_RELOC_AARCH64_CALL26
:
213 case BFD_RELOC_AARCH64_JUMP26
:
214 contents
= reencode_branch_ofs_26 (contents
, addend
);
217 case BFD_RELOC_AARCH64_BRANCH19
:
218 contents
= reencode_cond_branch_ofs_19 (contents
, addend
);
221 case BFD_RELOC_AARCH64_TSTBR14
:
222 contents
= reencode_tst_branch_ofs_14 (contents
, addend
);
225 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
226 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
227 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
228 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
229 if (old_addend
& ((1 << howto
->rightshift
) - 1))
230 return bfd_reloc_overflow
;
231 contents
= reencode_ld_lit_ofs_19 (contents
, addend
);
234 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
237 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
238 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
239 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
240 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
241 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
242 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
243 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
244 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
245 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
246 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
247 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
248 contents
= _bfd_aarch64_reencode_adr_imm (contents
, addend
);
251 case BFD_RELOC_AARCH64_ADD_LO12
:
252 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
253 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
254 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
255 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
256 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
257 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC
:
258 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
259 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
260 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
261 /* Corresponds to: add rd, rn, #uimm12 to provide the low order
262 12 bits of the page offset following
263 BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the
264 (pc-relative) page base. */
265 contents
= reencode_add_imm (contents
, addend
);
268 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
269 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
270 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
271 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
272 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
273 case BFD_RELOC_AARCH64_LDST128_LO12
:
274 case BFD_RELOC_AARCH64_LDST16_LO12
:
275 case BFD_RELOC_AARCH64_LDST32_LO12
:
276 case BFD_RELOC_AARCH64_LDST64_LO12
:
277 case BFD_RELOC_AARCH64_LDST8_LO12
:
278 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
279 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
280 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
281 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
282 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
283 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
284 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
285 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
286 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
287 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
288 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
289 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
290 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
:
291 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
:
292 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
:
293 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
:
294 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
:
295 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
:
296 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
:
297 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
:
298 if (old_addend
& ((1 << howto
->rightshift
) - 1))
299 return bfd_reloc_overflow
;
300 /* Used for ldr*|str* rt, [rn, #uimm12] to provide the low order
301 12 bits address offset. */
302 contents
= reencode_ldst_pos_imm (contents
, addend
);
305 /* Group relocations to create high bits of a 16, 32, 48 or 64
306 bit signed data or abs address inline. Will change
307 instruction to MOVN or MOVZ depending on sign of calculated
310 case BFD_RELOC_AARCH64_MOVW_G0_S
:
311 case BFD_RELOC_AARCH64_MOVW_G1_S
:
312 case BFD_RELOC_AARCH64_MOVW_G2_S
:
313 case BFD_RELOC_AARCH64_MOVW_PREL_G0
:
314 case BFD_RELOC_AARCH64_MOVW_PREL_G1
:
315 case BFD_RELOC_AARCH64_MOVW_PREL_G2
:
316 case BFD_RELOC_AARCH64_MOVW_PREL_G3
:
317 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
318 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
319 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
320 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
321 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
322 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
323 /* NOTE: We can only come here with movz or movn. */
326 /* Force use of MOVN. */
328 contents
= reencode_movzn_to_movn (contents
);
332 /* Force use of MOVZ. */
333 contents
= reencode_movzn_to_movz (contents
);
337 /* Group relocations to create a 16, 32, 48 or 64 bit unsigned
338 data or abs address inline. */
340 case BFD_RELOC_AARCH64_MOVW_G0
:
341 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
342 case BFD_RELOC_AARCH64_MOVW_G1
:
343 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
344 case BFD_RELOC_AARCH64_MOVW_G2
:
345 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
346 case BFD_RELOC_AARCH64_MOVW_G3
:
347 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
348 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
349 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC
:
350 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC
:
351 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC
:
352 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
353 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
354 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
355 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
356 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
357 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
358 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
359 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
360 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
361 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
362 contents
= reencode_movw_imm (contents
, addend
);
366 /* Repack simple data */
367 if (howto
->dst_mask
& (howto
->dst_mask
+ 1))
368 return bfd_reloc_notsupported
;
370 contents
= ((contents
& ~howto
->dst_mask
) | (addend
& howto
->dst_mask
));
377 bfd_put_16 (abfd
, contents
, address
);
380 if (howto
->dst_mask
!= 0xffffffff)
381 /* must be 32-bit instruction, always little-endian */
382 bfd_putl32 (contents
, address
);
384 /* must be 32-bit data (endianness dependent) */
385 bfd_put_32 (abfd
, contents
, address
);
388 bfd_put_64 (abfd
, contents
, address
);
398 _bfd_aarch64_elf_resolve_relocation (bfd
*input_bfd
,
399 bfd_reloc_code_real_type r_type
,
400 bfd_vma place
, bfd_vma value
,
401 bfd_vma addend
, bool weak_undef_p
)
403 bool tls_reloc
= true;
406 case BFD_RELOC_AARCH64_NONE
:
407 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
410 case BFD_RELOC_AARCH64_16_PCREL
:
411 case BFD_RELOC_AARCH64_32_PCREL
:
412 case BFD_RELOC_AARCH64_64_PCREL
:
413 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
414 case BFD_RELOC_AARCH64_BRANCH19
:
415 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
416 case BFD_RELOC_AARCH64_MOVW_PREL_G0
:
417 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC
:
418 case BFD_RELOC_AARCH64_MOVW_PREL_G1
:
419 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC
:
420 case BFD_RELOC_AARCH64_MOVW_PREL_G2
:
421 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC
:
422 case BFD_RELOC_AARCH64_MOVW_PREL_G3
:
423 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
424 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
425 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
426 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
427 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
428 case BFD_RELOC_AARCH64_TSTBR14
:
431 value
= value
+ addend
- place
;
434 case BFD_RELOC_AARCH64_CALL26
:
435 case BFD_RELOC_AARCH64_JUMP26
:
436 value
= value
+ addend
- place
;
439 case BFD_RELOC_AARCH64_16
:
440 case BFD_RELOC_AARCH64_32
:
441 case BFD_RELOC_AARCH64_MOVW_G0
:
442 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
443 case BFD_RELOC_AARCH64_MOVW_G0_S
:
444 case BFD_RELOC_AARCH64_MOVW_G1
:
445 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
446 case BFD_RELOC_AARCH64_MOVW_G1_S
:
447 case BFD_RELOC_AARCH64_MOVW_G2
:
448 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
449 case BFD_RELOC_AARCH64_MOVW_G2_S
:
450 case BFD_RELOC_AARCH64_MOVW_G3
:
453 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
454 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
455 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
456 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
457 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
458 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
459 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
460 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
461 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
462 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
463 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
464 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
465 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
466 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
467 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
468 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
469 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
:
470 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
:
471 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
:
472 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
:
473 /* Weak Symbols and TLS relocations are implementation defined. For this
474 case we choose to emit 0. */
475 if (weak_undef_p
&& tls_reloc
)
477 _bfd_error_handler (_("%pB: warning: Weak TLS is implementation "
478 "defined and may not work as expected"),
482 value
= value
+ addend
;
485 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
486 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
489 value
= PG (value
+ addend
) - PG (place
);
492 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
493 value
= value
+ addend
- place
;
496 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
497 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
498 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
499 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
500 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
501 value
= PG (value
+ addend
) - PG (place
);
504 /* Caller must make sure addend is the base address of .got section. */
505 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
506 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
507 addend
= PG (addend
);
509 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
510 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
511 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
512 value
= value
- addend
;
515 case BFD_RELOC_AARCH64_ADD_LO12
:
516 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
517 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
518 case BFD_RELOC_AARCH64_LDST128_LO12
:
519 case BFD_RELOC_AARCH64_LDST16_LO12
:
520 case BFD_RELOC_AARCH64_LDST32_LO12
:
521 case BFD_RELOC_AARCH64_LDST64_LO12
:
522 case BFD_RELOC_AARCH64_LDST8_LO12
:
523 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
524 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
525 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
526 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
527 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
528 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
529 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
530 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
531 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
532 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
533 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
534 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
535 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
536 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
:
537 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
:
538 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
:
539 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
:
540 value
= PG_OFFSET (value
+ addend
);
543 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
544 value
= value
+ addend
;
547 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
548 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
549 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
550 value
= (value
+ addend
) & (bfd_vma
) 0xffff0000;
552 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
553 /* Mask off low 12bits, keep all other high bits, so that the later
554 generic code could check whehter there is overflow. */
555 value
= (value
+ addend
) & ~(bfd_vma
) 0xfff;
558 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
559 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
560 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
561 value
= (value
+ addend
) & (bfd_vma
) 0xffff;
564 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
565 value
= (value
+ addend
) & ~(bfd_vma
) 0xffffffff;
566 value
-= place
& ~(bfd_vma
) 0xffffffff;
576 /* Support for core dump NOTE sections. */
579 _bfd_aarch64_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
584 switch (note
->descsz
)
589 case 392: /* sizeof(struct elf_prstatus) on Linux/arm64. */
591 elf_tdata (abfd
)->core
->signal
592 = bfd_get_16 (abfd
, note
->descdata
+ 12);
595 elf_tdata (abfd
)->core
->lwpid
596 = bfd_get_32 (abfd
, note
->descdata
+ 32);
605 /* Make a ".reg/999" section. */
606 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
607 size
, note
->descpos
+ offset
);
611 _bfd_aarch64_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
613 switch (note
->descsz
)
618 case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/aarch64. */
619 elf_tdata (abfd
)->core
->pid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
620 elf_tdata (abfd
)->core
->program
621 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
622 elf_tdata (abfd
)->core
->command
623 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
626 /* Note that for some reason, a spurious space is tacked
627 onto the end of the args in some (at least one anyway)
628 implementations, so strip it off if it exists. */
631 char *command
= elf_tdata (abfd
)->core
->command
;
632 int n
= strlen (command
);
634 if (0 < n
&& command
[n
- 1] == ' ')
635 command
[n
- 1] = '\0';
642 _bfd_aarch64_elf_write_core_note (bfd
*abfd
, char *buf
, int *bufsiz
, int note_type
,
652 char data
[136] ATTRIBUTE_NONSTRING
;
655 va_start (ap
, note_type
);
656 memset (data
, 0, sizeof (data
));
657 strncpy (data
+ 40, va_arg (ap
, const char *), 16);
658 #if GCC_VERSION == 8000 || GCC_VERSION == 8001
660 /* GCC 8.0 and 8.1 warn about 80 equals destination size with
661 -Wstringop-truncation:
662 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643
664 DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION
;
666 strncpy (data
+ 56, va_arg (ap
, const char *), 80);
667 #if GCC_VERSION == 8000 || GCC_VERSION == 8001
672 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE",
673 note_type
, data
, sizeof (data
));
684 va_start (ap
, note_type
);
685 memset (data
, 0, sizeof (data
));
686 pid
= va_arg (ap
, long);
687 bfd_put_32 (abfd
, pid
, data
+ 32);
688 cursig
= va_arg (ap
, int);
689 bfd_put_16 (abfd
, cursig
, data
+ 12);
690 greg
= va_arg (ap
, const void *);
691 memcpy (data
+ 112, greg
, 272);
694 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE",
695 note_type
, data
, sizeof (data
));
700 /* Find the first input bfd with GNU property and merge it with GPROP. If no
701 such input is found, add it to a new section at the last input. Update
702 GPROP accordingly. */
704 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info
*info
,
713 uint32_t gnu_prop
= *gprop
;
715 /* Find a normal input file with GNU property note. */
716 for (pbfd
= info
->input_bfds
;
718 pbfd
= pbfd
->link
.next
)
719 if (bfd_get_flavour (pbfd
) == bfd_target_elf_flavour
720 && bfd_count_sections (pbfd
) != 0)
724 if (elf_properties (pbfd
) != NULL
)
728 /* If ebfd != NULL it is either an input with property note or the last
729 input. Either way if we have gnu_prop, we should add it (by creating
730 a section if needed). */
731 if (ebfd
!= NULL
&& gnu_prop
)
733 prop
= _bfd_elf_get_property (ebfd
,
734 GNU_PROPERTY_AARCH64_FEATURE_1_AND
,
736 if (gnu_prop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
737 && !(prop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
738 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti "
739 "when all inputs do not have BTI in NOTE "
741 prop
->u
.number
|= gnu_prop
;
742 prop
->pr_kind
= property_number
;
744 /* pbfd being NULL implies ebfd is the last input. Create the GNU
745 property note section. */
748 sec
= bfd_make_section_with_flags (ebfd
,
749 NOTE_GNU_PROPERTY_SECTION_NAME
,
757 info
->callbacks
->einfo (
758 _("%F%P: failed to create GNU property section\n"));
760 align
= (bfd_get_mach (ebfd
) & bfd_mach_aarch64_ilp32
) ? 2 : 3;
761 if (!bfd_set_section_alignment (sec
, align
))
762 info
->callbacks
->einfo (_("%F%pA: failed to align section\n"),
765 elf_section_type (sec
) = SHT_NOTE
;
769 pbfd
= _bfd_elf_link_setup_gnu_properties (info
);
771 if (bfd_link_relocatable (info
))
774 /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
775 gnu_prop accordingly. */
778 elf_property_list
*p
;
780 /* The property list is sorted in order of type. */
781 for (p
= elf_properties (pbfd
); p
; p
= p
->next
)
783 /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND. */
784 if (GNU_PROPERTY_AARCH64_FEATURE_1_AND
== p
->property
.pr_type
)
786 gnu_prop
= (p
->property
.u
.number
787 & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
788 | GNU_PROPERTY_AARCH64_FEATURE_1_BTI
));
791 else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND
< p
->property
.pr_type
)
799 /* Define elf_backend_parse_gnu_properties for AArch64. */
800 enum elf_property_kind
801 _bfd_aarch64_elf_parse_gnu_properties (bfd
*abfd
, unsigned int type
,
802 bfd_byte
*ptr
, unsigned int datasz
)
808 case GNU_PROPERTY_AARCH64_FEATURE_1_AND
:
812 ( _("error: %pB: <corrupt AArch64 used size: 0x%x>"),
814 return property_corrupt
;
816 prop
= _bfd_elf_get_property (abfd
, type
, datasz
);
817 /* Combine properties of the same type. */
818 prop
->u
.number
|= bfd_h_get_32 (abfd
, ptr
);
819 prop
->pr_kind
= property_number
;
823 return property_ignored
;
826 return property_number
;
829 /* Merge AArch64 GNU property BPROP with APROP also accounting for PROP.
830 If APROP isn't NULL, merge it with BPROP and/or PROP. Vice-versa if BROP
831 isn't NULL. Return TRUE if there is any update to APROP or if BPROP should
832 be merge with ABFD. */
834 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info
*info
836 bfd
*abfd ATTRIBUTE_UNUSED
,
841 unsigned int orig_number
;
842 bool updated
= false;
843 unsigned int pr_type
= aprop
!= NULL
? aprop
->pr_type
: bprop
->pr_type
;
847 case GNU_PROPERTY_AARCH64_FEATURE_1_AND
:
849 if (aprop
!= NULL
&& bprop
!= NULL
)
851 orig_number
= aprop
->u
.number
;
852 aprop
->u
.number
= (orig_number
& bprop
->u
.number
) | prop
;
853 updated
= orig_number
!= aprop
->u
.number
;
854 /* Remove the property if all feature bits are cleared. */
855 if (aprop
->u
.number
== 0)
856 aprop
->pr_kind
= property_remove
;
859 /* If either is NULL, the AND would be 0 so, if there is
860 any PROP, asign it to the input that is not NULL. */
865 orig_number
= aprop
->u
.number
;
866 aprop
->u
.number
= prop
;
867 updated
= orig_number
!= aprop
->u
.number
;
871 bprop
->u
.number
= prop
;
875 /* No PROP and BPROP is NULL, so remove APROP. */
876 else if (aprop
!= NULL
)
878 aprop
->pr_kind
= property_remove
;
891 /* Fix up AArch64 GNU properties. */
893 _bfd_aarch64_elf_link_fixup_gnu_properties
894 (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
895 elf_property_list
**listp
)
897 elf_property_list
*p
, *prev
;
899 for (p
= *listp
, prev
= *listp
; p
; p
= p
->next
)
901 unsigned int type
= p
->property
.pr_type
;
902 if (type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
)
904 if (p
->property
.pr_kind
== property_remove
)
906 /* Remove empty property. */
913 prev
->next
= p
->next
;
918 else if (type
> GNU_PROPERTY_HIPROC
)
920 /* The property list is sorted in order of type. */