1 /* AArch64-specific support for ELF.
2 Copyright (C) 2009-2019 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_reloc_code_real_type r_type
,
399 bfd_vma place
, bfd_vma value
,
400 bfd_vma addend
, bfd_boolean weak_undef_p
)
404 case BFD_RELOC_AARCH64_NONE
:
405 case BFD_RELOC_AARCH64_TLSDESC_CALL
:
408 case BFD_RELOC_AARCH64_16_PCREL
:
409 case BFD_RELOC_AARCH64_32_PCREL
:
410 case BFD_RELOC_AARCH64_64_PCREL
:
411 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
412 case BFD_RELOC_AARCH64_BRANCH19
:
413 case BFD_RELOC_AARCH64_LD_LO19_PCREL
:
414 case BFD_RELOC_AARCH64_MOVW_PREL_G0
:
415 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC
:
416 case BFD_RELOC_AARCH64_MOVW_PREL_G1
:
417 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC
:
418 case BFD_RELOC_AARCH64_MOVW_PREL_G2
:
419 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC
:
420 case BFD_RELOC_AARCH64_MOVW_PREL_G3
:
421 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
:
422 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
:
423 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21
:
424 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
:
425 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21
:
426 case BFD_RELOC_AARCH64_TSTBR14
:
429 value
= value
+ addend
- place
;
432 case BFD_RELOC_AARCH64_CALL26
:
433 case BFD_RELOC_AARCH64_JUMP26
:
434 value
= value
+ addend
- place
;
437 case BFD_RELOC_AARCH64_16
:
438 case BFD_RELOC_AARCH64_32
:
439 case BFD_RELOC_AARCH64_MOVW_G0
:
440 case BFD_RELOC_AARCH64_MOVW_G0_NC
:
441 case BFD_RELOC_AARCH64_MOVW_G0_S
:
442 case BFD_RELOC_AARCH64_MOVW_G1
:
443 case BFD_RELOC_AARCH64_MOVW_G1_NC
:
444 case BFD_RELOC_AARCH64_MOVW_G1_S
:
445 case BFD_RELOC_AARCH64_MOVW_G2
:
446 case BFD_RELOC_AARCH64_MOVW_G2_NC
:
447 case BFD_RELOC_AARCH64_MOVW_G2_S
:
448 case BFD_RELOC_AARCH64_MOVW_G3
:
449 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
:
450 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1
:
451 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC
:
452 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1
:
453 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12
:
454 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12
:
455 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
:
456 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12
:
457 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12
:
458 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
:
459 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12
:
460 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0
:
461 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC
:
462 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1
:
463 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC
:
464 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2
:
465 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
:
466 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
:
467 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
:
468 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
:
469 value
= value
+ addend
;
472 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
:
473 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
476 value
= PG (value
+ addend
) - PG (place
);
479 case BFD_RELOC_AARCH64_GOT_LD_PREL19
:
480 value
= value
+ addend
- place
;
483 case BFD_RELOC_AARCH64_ADR_GOT_PAGE
:
484 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
:
485 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
:
486 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
:
487 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21
:
488 value
= PG (value
+ addend
) - PG (place
);
491 /* Caller must make sure addend is the base address of .got section. */
492 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14
:
493 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
:
494 addend
= PG (addend
);
496 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15
:
497 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC
:
498 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1
:
499 value
= value
- addend
;
502 case BFD_RELOC_AARCH64_ADD_LO12
:
503 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
:
504 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
:
505 case BFD_RELOC_AARCH64_LDST128_LO12
:
506 case BFD_RELOC_AARCH64_LDST16_LO12
:
507 case BFD_RELOC_AARCH64_LDST32_LO12
:
508 case BFD_RELOC_AARCH64_LDST64_LO12
:
509 case BFD_RELOC_AARCH64_LDST8_LO12
:
510 case BFD_RELOC_AARCH64_TLSDESC_ADD
:
511 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
:
512 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
:
513 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12
:
514 case BFD_RELOC_AARCH64_TLSDESC_LDR
:
515 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
:
516 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
:
517 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
:
518 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC
:
519 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
:
520 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC
:
521 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC
:
522 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
:
523 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
:
524 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
:
525 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
:
526 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
:
527 value
= PG_OFFSET (value
+ addend
);
530 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
:
531 value
= value
+ addend
;
534 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
:
535 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
:
536 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
:
537 value
= (value
+ addend
) & (bfd_vma
) 0xffff0000;
539 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
:
540 /* Mask off low 12bits, keep all other high bits, so that the later
541 generic code could check whehter there is overflow. */
542 value
= (value
+ addend
) & ~(bfd_vma
) 0xfff;
545 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
:
546 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
:
547 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
:
548 value
= (value
+ addend
) & (bfd_vma
) 0xffff;
551 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
:
552 value
= (value
+ addend
) & ~(bfd_vma
) 0xffffffff;
553 value
-= place
& ~(bfd_vma
) 0xffffffff;
563 /* Support for core dump NOTE sections. */
566 _bfd_aarch64_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
571 switch (note
->descsz
)
576 case 392: /* sizeof(struct elf_prstatus) on Linux/arm64. */
578 elf_tdata (abfd
)->core
->signal
579 = bfd_get_16 (abfd
, note
->descdata
+ 12);
582 elf_tdata (abfd
)->core
->lwpid
583 = bfd_get_32 (abfd
, note
->descdata
+ 32);
592 /* Make a ".reg/999" section. */
593 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
594 size
, note
->descpos
+ offset
);
598 _bfd_aarch64_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
600 switch (note
->descsz
)
605 case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/aarch64. */
606 elf_tdata (abfd
)->core
->pid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
607 elf_tdata (abfd
)->core
->program
608 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
609 elf_tdata (abfd
)->core
->command
610 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
613 /* Note that for some reason, a spurious space is tacked
614 onto the end of the args in some (at least one anyway)
615 implementations, so strip it off if it exists. */
618 char *command
= elf_tdata (abfd
)->core
->command
;
619 int n
= strlen (command
);
621 if (0 < n
&& command
[n
- 1] == ' ')
622 command
[n
- 1] = '\0';
629 _bfd_aarch64_elf_write_core_note (bfd
*abfd
, char *buf
, int *bufsiz
, int note_type
,
639 char data
[136] ATTRIBUTE_NONSTRING
;
642 va_start (ap
, note_type
);
643 memset (data
, 0, sizeof (data
));
644 strncpy (data
+ 40, va_arg (ap
, const char *), 16);
645 #if GCC_VERSION == 8000 || GCC_VERSION == 8001
647 /* GCC 8.0 and 8.1 warn about 80 equals destination size with
648 -Wstringop-truncation:
649 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643
651 DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION
;
653 strncpy (data
+ 56, va_arg (ap
, const char *), 80);
654 #if GCC_VERSION == 8000 || GCC_VERSION == 8001
659 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE",
660 note_type
, data
, sizeof (data
));
671 va_start (ap
, note_type
);
672 memset (data
, 0, sizeof (data
));
673 pid
= va_arg (ap
, long);
674 bfd_put_32 (abfd
, pid
, data
+ 32);
675 cursig
= va_arg (ap
, int);
676 bfd_put_16 (abfd
, cursig
, data
+ 12);
677 greg
= va_arg (ap
, const void *);
678 memcpy (data
+ 112, greg
, 272);
681 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE",
682 note_type
, data
, sizeof (data
));
687 /* Find the first input bfd with GNU property and merge it with GPROP. If no
688 such input is found, add it to a new section at the last input. Update
689 GPROP accordingly. */
691 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info
*info
,
699 uint32_t gnu_prop
= *gprop
;
701 /* Find a normal input file with GNU property note. */
702 for (pbfd
= info
->input_bfds
;
704 pbfd
= pbfd
->link
.next
)
705 if (bfd_get_flavour (pbfd
) == bfd_target_elf_flavour
706 && bfd_count_sections (pbfd
) != 0)
710 if (elf_properties (pbfd
) != NULL
)
714 /* If ebfd != NULL it is either an input with property note or the last
715 input. Either way if we have gnu_prop, we should add it (by creating
716 a section if needed). */
717 if (ebfd
!= NULL
&& gnu_prop
)
719 prop
= _bfd_elf_get_property (ebfd
,
720 GNU_PROPERTY_AARCH64_FEATURE_1_AND
,
722 if (gnu_prop
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
723 && !(prop
->u
.number
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
))
724 _bfd_error_handler (_("%pB: warning: BTI turned on by --force-bti "
725 "when all inputs do not have BTI in NOTE "
727 prop
->u
.number
|= gnu_prop
;
728 prop
->pr_kind
= property_number
;
730 /* pbfd being NULL implies ebfd is the last input. Create the GNU
731 property note section. */
734 sec
= bfd_make_section_with_flags (ebfd
,
735 NOTE_GNU_PROPERTY_SECTION_NAME
,
743 info
->callbacks
->einfo (
744 _("%F%P: failed to create GNU property section\n"));
746 elf_section_type (sec
) = SHT_NOTE
;
750 pbfd
= _bfd_elf_link_setup_gnu_properties (info
);
752 if (bfd_link_relocatable (info
))
755 /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
756 gnu_prop accordingly. */
759 elf_property_list
*p
;
761 /* The property list is sorted in order of type. */
762 for (p
= elf_properties (pbfd
); p
; p
= p
->next
)
764 /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND. */
765 if (GNU_PROPERTY_AARCH64_FEATURE_1_AND
== p
->property
.pr_type
)
767 gnu_prop
= (p
->property
.u
.number
768 & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
769 | GNU_PROPERTY_AARCH64_FEATURE_1_BTI
));
772 else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND
< p
->property
.pr_type
)
780 /* Define elf_backend_parse_gnu_properties for AArch64. */
781 enum elf_property_kind
782 _bfd_aarch64_elf_parse_gnu_properties (bfd
*abfd
, unsigned int type
,
783 bfd_byte
*ptr
, unsigned int datasz
)
789 case GNU_PROPERTY_AARCH64_FEATURE_1_AND
:
793 ( _("error: %pB: <corrupt AArch64 used size: 0x%x>"),
795 return property_corrupt
;
797 prop
= _bfd_elf_get_property (abfd
, type
, datasz
);
798 /* Combine properties of the same type. */
799 prop
->u
.number
|= bfd_h_get_32 (abfd
, ptr
);
800 prop
->pr_kind
= property_number
;
804 return property_ignored
;
807 return property_number
;
810 /* Merge AArch64 GNU property BPROP with APROP also accounting for PROP.
811 If APROP isn't NULL, merge it with BPROP and/or PROP. Vice-versa if BROP
812 isn't NULL. Return TRUE if there is any update to APROP or if BPROP should
813 be merge with ABFD. */
815 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info
*info
817 bfd
*abfd ATTRIBUTE_UNUSED
,
822 unsigned int orig_number
;
823 bfd_boolean updated
= FALSE
;
824 unsigned int pr_type
= aprop
!= NULL
? aprop
->pr_type
: bprop
->pr_type
;
828 case GNU_PROPERTY_AARCH64_FEATURE_1_AND
:
830 if (aprop
!= NULL
&& bprop
!= NULL
)
832 orig_number
= aprop
->u
.number
;
833 aprop
->u
.number
= (orig_number
& bprop
->u
.number
) | prop
;
834 updated
= orig_number
!= aprop
->u
.number
;
835 /* Remove the property if all feature bits are cleared. */
836 if (aprop
->u
.number
== 0)
837 aprop
->pr_kind
= property_remove
;
840 /* If either is NULL, the AND would be 0 so, if there is
841 any PROP, asign it to the input that is not NULL. */
846 orig_number
= aprop
->u
.number
;
847 aprop
->u
.number
= prop
;
848 updated
= orig_number
!= aprop
->u
.number
;
852 bprop
->u
.number
= prop
;
856 /* No PROP and BPROP is NULL, so remove APROP. */
857 else if (aprop
!= NULL
)
859 aprop
->pr_kind
= property_remove
;
872 /* Fix up AArch64 GNU properties. */
874 _bfd_aarch64_elf_link_fixup_gnu_properties
875 (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
876 elf_property_list
**listp
)
878 elf_property_list
*p
, *prev
;
880 for (p
= *listp
, prev
= *listp
; p
; p
= p
->next
)
882 unsigned int type
= p
->property
.pr_type
;
883 if (type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
)
885 if (p
->property
.pr_kind
== property_remove
)
887 /* Remove empty property. */
894 prev
->next
= p
->next
;
899 else if (type
> GNU_PROPERTY_HIPROC
)
901 /* The property list is sorted in order of type. */