Home | History | Annotate | Line # | Download | only in bfd
elfxx-aarch64.c revision 1.9.2.1
      1 /* AArch64-specific support for ELF.
      2    Copyright (C) 2009-2022 Free Software Foundation, Inc.
      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 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "elf-bfd.h"
     24 #include "elfxx-aarch64.h"
     25 #include <stdarg.h>
     26 #include <string.h>
     27 
     28 #define MASK(n) ((1u << (n)) - 1)
     29 
     30 /* Sign-extend VALUE, which has the indicated number of BITS.  */
     31 
     32 bfd_signed_vma
     33 _bfd_aarch64_sign_extend (bfd_vma value, int bits)
     34 {
     35   if (value & ((bfd_vma) 1 << (bits - 1)))
     36     /* VALUE is negative.  */
     37     value |= ((bfd_vma) - 1) << bits;
     38 
     39   return value;
     40 }
     41 
     42 /* Decode the IMM field of ADRP.  */
     43 
     44 uint32_t
     45 _bfd_aarch64_decode_adrp_imm (uint32_t insn)
     46 {
     47   return (((insn >> 5) & MASK (19)) << 2) | ((insn >> 29) & MASK (2));
     48 }
     49 
     50 /* Reencode the imm field of add immediate.  */
     51 static inline uint32_t
     52 reencode_add_imm (uint32_t insn, uint32_t imm)
     53 {
     54   return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10);
     55 }
     56 
     57 /* Reencode the IMM field of ADR.  */
     58 
     59 uint32_t
     60 _bfd_aarch64_reencode_adr_imm (uint32_t insn, uint32_t imm)
     61 {
     62   return (insn & ~((MASK (2) << 29) | (MASK (19) << 5)))
     63     | ((imm & MASK (2)) << 29) | ((imm & (MASK (19) << 2)) << 3);
     64 }
     65 
     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)
     69 {
     70   return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10);
     71 }
     72 
     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)
     76 {
     77   return (insn & ~MASK (26)) | (ofs & MASK (26));
     78 }
     79 
     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)
     83 {
     84   return (insn & ~(MASK (19) << 5)) | ((ofs & MASK (19)) << 5);
     85 }
     86 
     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)
     90 {
     91   return (insn & ~(MASK (19) << 5)) | ((ofs & MASK (19)) << 5);
     92 }
     93 
     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)
     97 {
     98   return (insn & ~(MASK (14) << 5)) | ((ofs & MASK (14)) << 5);
     99 }
    100 
    101 /* Reencode the imm field of move wide.  */
    102 static inline uint32_t
    103 reencode_movw_imm (uint32_t insn, uint32_t imm)
    104 {
    105   return (insn & ~(MASK (16) << 5)) | ((imm & MASK (16)) << 5);
    106 }
    107 
    108 /* Reencode mov[zn] to movz.  */
    109 static inline uint32_t
    110 reencode_movzn_to_movz (uint32_t opcode)
    111 {
    112   return opcode | (1 << 30);
    113 }
    114 
    115 /* Reencode mov[zn] to movn.  */
    116 static inline uint32_t
    117 reencode_movzn_to_movn (uint32_t opcode)
    118 {
    119   return opcode & ~(1 << 30);
    120 }
    121 
    122 /* Return non-zero if the indicated VALUE has overflowed the maximum
    123    range expressible by a unsigned number with the indicated number of
    124    BITS.  */
    125 
    126 static bfd_reloc_status_type
    127 aarch64_unsigned_overflow (bfd_vma value, unsigned int bits)
    128 {
    129   bfd_vma lim;
    130   if (bits >= sizeof (bfd_vma) * 8)
    131     return bfd_reloc_ok;
    132   lim = (bfd_vma) 1 << bits;
    133   if (value >= lim)
    134     return bfd_reloc_overflow;
    135   return bfd_reloc_ok;
    136 }
    137 
    138 /* Return non-zero if the indicated VALUE has overflowed the maximum
    139    range expressible by an signed number with the indicated number of
    140    BITS.  */
    141 
    142 static bfd_reloc_status_type
    143 aarch64_signed_overflow (bfd_vma value, unsigned int bits)
    144 {
    145   bfd_signed_vma svalue = (bfd_signed_vma) value;
    146   bfd_signed_vma lim;
    147 
    148   if (bits >= sizeof (bfd_vma) * 8)
    149     return bfd_reloc_ok;
    150   lim = (bfd_signed_vma) 1 << (bits - 1);
    151   if (svalue < -lim || svalue >= lim)
    152     return bfd_reloc_overflow;
    153   return bfd_reloc_ok;
    154 }
    155 
    156 /* Insert the addend/value into the instruction or data object being
    157    relocated.  */
    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)
    162 {
    163   bfd_reloc_status_type status = bfd_reloc_ok;
    164   bfd_signed_vma old_addend = addend;
    165   bfd_vma contents;
    166   int size;
    167 
    168   size = bfd_get_reloc_size (howto);
    169   switch (size)
    170     {
    171     case 0:
    172       return status;
    173     case 2:
    174       contents = bfd_get_16 (abfd, address);
    175       break;
    176     case 4:
    177       if (howto->src_mask != 0xffffffff)
    178 	/* Must be 32-bit instruction, always little-endian.  */
    179 	contents = bfd_getl32 (address);
    180       else
    181 	/* Must be 32-bit data (endianness dependent).  */
    182 	contents = bfd_get_32 (abfd, address);
    183       break;
    184     case 8:
    185       contents = bfd_get_64 (abfd, address);
    186       break;
    187     default:
    188       abort ();
    189     }
    190 
    191   switch (howto->complain_on_overflow)
    192     {
    193     case complain_overflow_dont:
    194       break;
    195     case complain_overflow_signed:
    196       status = aarch64_signed_overflow (addend,
    197 					howto->bitsize + howto->rightshift);
    198       break;
    199     case complain_overflow_unsigned:
    200       status = aarch64_unsigned_overflow (addend,
    201 					  howto->bitsize + howto->rightshift);
    202       break;
    203     case complain_overflow_bitfield:
    204     default:
    205       abort ();
    206     }
    207 
    208   addend >>= howto->rightshift;
    209 
    210   switch (r_type)
    211     {
    212     case BFD_RELOC_AARCH64_CALL26:
    213     case BFD_RELOC_AARCH64_JUMP26:
    214       contents = reencode_branch_ofs_26 (contents, addend);
    215       break;
    216 
    217     case BFD_RELOC_AARCH64_BRANCH19:
    218       contents = reencode_cond_branch_ofs_19 (contents, addend);
    219       break;
    220 
    221     case BFD_RELOC_AARCH64_TSTBR14:
    222       contents = reencode_tst_branch_ofs_14 (contents, addend);
    223       break;
    224 
    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);
    232       break;
    233 
    234     case BFD_RELOC_AARCH64_TLSDESC_CALL:
    235       break;
    236 
    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);
    249       break;
    250 
    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);
    266       break;
    267 
    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);
    303       break;
    304 
    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
    308 	 value.  */
    309 
    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.  */
    324       if (addend < 0)
    325 	{
    326 	  /* Force use of MOVN.  */
    327 	  addend = ~addend;
    328 	  contents = reencode_movzn_to_movn (contents);
    329 	}
    330       else
    331 	{
    332 	  /* Force use of MOVZ.  */
    333 	  contents = reencode_movzn_to_movz (contents);
    334 	}
    335       /* Fall through.  */
    336 
    337       /* Group relocations to create a 16, 32, 48 or 64 bit unsigned
    338 	 data or abs address inline.  */
    339 
    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);
    363       break;
    364 
    365     default:
    366       /* Repack simple data */
    367       if (howto->dst_mask & (howto->dst_mask + 1))
    368 	return bfd_reloc_notsupported;
    369 
    370       contents = ((contents & ~howto->dst_mask) | (addend & howto->dst_mask));
    371       break;
    372     }
    373 
    374   switch (size)
    375     {
    376     case 2:
    377       bfd_put_16 (abfd, contents, address);
    378       break;
    379     case 4:
    380       if (howto->dst_mask != 0xffffffff)
    381 	/* must be 32-bit instruction, always little-endian */
    382 	bfd_putl32 (contents, address);
    383       else
    384 	/* must be 32-bit data (endianness dependent) */
    385 	bfd_put_32 (abfd, contents, address);
    386       break;
    387     case 8:
    388       bfd_put_64 (abfd, contents, address);
    389       break;
    390     default:
    391       abort ();
    392     }
    393 
    394   return status;
    395 }
    396 
    397 bfd_vma
    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)
    402 {
    403   bool tls_reloc = true;
    404   switch (r_type)
    405     {
    406     case BFD_RELOC_AARCH64_NONE:
    407     case BFD_RELOC_AARCH64_TLSDESC_CALL:
    408       break;
    409 
    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:
    429       if (weak_undef_p)
    430 	value = place;
    431       value = value + addend - place;
    432       break;
    433 
    434     case BFD_RELOC_AARCH64_CALL26:
    435     case BFD_RELOC_AARCH64_JUMP26:
    436       value = value + addend - place;
    437       break;
    438 
    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:
    451       tls_reloc = false;
    452       /* fall-through.  */
    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)
    476 	{
    477 	  _bfd_error_handler (_("%pB: warning: Weak TLS is implementation "
    478 				"defined and may not work as expected"),
    479 				input_bfd);
    480 	  value = place;
    481 	}
    482       value = value + addend;
    483       break;
    484 
    485     case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
    486     case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
    487       if (weak_undef_p)
    488 	value = PG (place);
    489       value = PG (value + addend) - PG (place);
    490       break;
    491 
    492     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
    493       value = value + addend - place;
    494       break;
    495 
    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);
    502       break;
    503 
    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);
    508       /* Fall through.  */
    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;
    513       break;
    514 
    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);
    541       break;
    542 
    543     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
    544       value = value + addend;
    545       break;
    546 
    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;
    551       break;
    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;
    556       break;
    557 
    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;
    562       break;
    563 
    564     case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
    565       value = (value + addend) & ~(bfd_vma) 0xffffffff;
    566       value -= place & ~(bfd_vma) 0xffffffff;
    567       break;
    568 
    569     default:
    570       break;
    571     }
    572 
    573   return value;
    574 }
    575 
    576 /* Support for core dump NOTE sections.  */
    577 
    578 bool
    579 _bfd_aarch64_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
    580 {
    581   int offset;
    582   size_t size;
    583 
    584   switch (note->descsz)
    585     {
    586       default:
    587 	return false;
    588 
    589       case 392:		/* sizeof(struct elf_prstatus) on Linux/arm64.  */
    590 	/* pr_cursig */
    591 	elf_tdata (abfd)->core->signal
    592 	  = bfd_get_16 (abfd, note->descdata + 12);
    593 
    594 	/* pr_pid */
    595 	elf_tdata (abfd)->core->lwpid
    596 	  = bfd_get_32 (abfd, note->descdata + 32);
    597 
    598 	/* pr_reg */
    599 	offset = 112;
    600 	size = 272;
    601 
    602 	break;
    603     }
    604 
    605   /* Make a ".reg/999" section.  */
    606   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
    607 					  size, note->descpos + offset);
    608 }
    609 
    610 bool
    611 _bfd_aarch64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
    612 {
    613   switch (note->descsz)
    614     {
    615     default:
    616       return false;
    617 
    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);
    624     }
    625 
    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.  */
    629 
    630   {
    631     char *command = elf_tdata (abfd)->core->command;
    632     int n = strlen (command);
    633 
    634     if (0 < n && command[n - 1] == ' ')
    635       command[n - 1] = '\0';
    636   }
    637 
    638   return true;
    639 }
    640 
    641 char *
    642 _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
    643 				  ...)
    644 {
    645   switch (note_type)
    646     {
    647     default:
    648       return NULL;
    649 
    650     case NT_PRPSINFO:
    651       {
    652 	char data[136] ATTRIBUTE_NONSTRING;
    653 	va_list ap;
    654 
    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
    659 	DIAGNOSTIC_PUSH;
    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
    663 	 */
    664 	DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION;
    665 #endif
    666 	strncpy (data + 56, va_arg (ap, const char *), 80);
    667 #if GCC_VERSION == 8000 || GCC_VERSION == 8001
    668 	DIAGNOSTIC_POP;
    669 #endif
    670 	va_end (ap);
    671 
    672 	return elfcore_write_note (abfd, buf, bufsiz, "CORE",
    673 				   note_type, data, sizeof (data));
    674       }
    675 
    676     case NT_PRSTATUS:
    677       {
    678 	char data[392];
    679 	va_list ap;
    680 	long pid;
    681 	int cursig;
    682 	const void *greg;
    683 
    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);
    692 	va_end (ap);
    693 
    694 	return elfcore_write_note (abfd, buf, bufsiz, "CORE",
    695 				   note_type, data, sizeof (data));
    696       }
    697     }
    698 }
    699 
    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.  */
    703 bfd *
    704 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
    705 					    uint32_t *gprop)
    706 {
    707   asection *sec;
    708   bfd *pbfd;
    709   bfd *ebfd = NULL;
    710   elf_property *prop;
    711   unsigned align;
    712 
    713   uint32_t gnu_prop = *gprop;
    714 
    715   /* Find a normal input file with GNU property note.  */
    716   for (pbfd = info->input_bfds;
    717        pbfd != NULL;
    718        pbfd = pbfd->link.next)
    719     if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
    720 	&& bfd_count_sections (pbfd) != 0)
    721       {
    722 	ebfd = pbfd;
    723 
    724 	if (elf_properties (pbfd) != NULL)
    725 	  break;
    726       }
    727 
    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)
    732     {
    733       prop = _bfd_elf_get_property (ebfd,
    734 				    GNU_PROPERTY_AARCH64_FEATURE_1_AND,
    735 				    4);
    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 "
    740 				  "section."), ebfd);
    741       prop->u.number |= gnu_prop;
    742       prop->pr_kind = property_number;
    743 
    744       /* pbfd being NULL implies ebfd is the last input.  Create the GNU
    745 	 property note section.  */
    746       if (pbfd == NULL)
    747 	{
    748 	  sec = bfd_make_section_with_flags (ebfd,
    749 					     NOTE_GNU_PROPERTY_SECTION_NAME,
    750 					     (SEC_ALLOC
    751 					      | SEC_LOAD
    752 					      | SEC_IN_MEMORY
    753 					      | SEC_READONLY
    754 					      | SEC_HAS_CONTENTS
    755 					      | SEC_DATA));
    756 	  if (sec == NULL)
    757 	    info->callbacks->einfo (
    758 	      _("%F%P: failed to create GNU property section\n"));
    759 
    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"),
    763 				    sec);
    764 
    765 	  elf_section_type (sec) = SHT_NOTE;
    766 	}
    767     }
    768 
    769   pbfd = _bfd_elf_link_setup_gnu_properties (info);
    770 
    771   if (bfd_link_relocatable (info))
    772     return pbfd;
    773 
    774   /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
    775      gnu_prop accordingly.  */
    776   if (pbfd != NULL)
    777     {
    778       elf_property_list *p;
    779 
    780       /* The property list is sorted in order of type.  */
    781       for (p = elf_properties (pbfd); p; p = p->next)
    782 	{
    783 	  /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND.  */
    784 	  if (GNU_PROPERTY_AARCH64_FEATURE_1_AND == p->property.pr_type)
    785 	    {
    786 	      gnu_prop = (p->property.u.number
    787 			  & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
    788 			      | GNU_PROPERTY_AARCH64_FEATURE_1_BTI));
    789 	      break;
    790 	    }
    791 	  else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type)
    792 	    break;
    793 	}
    794     }
    795   *gprop = gnu_prop;
    796   return pbfd;
    797 }
    798 
    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)
    803 {
    804   elf_property *prop;
    805 
    806   switch (type)
    807     {
    808     case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
    809       if (datasz != 4)
    810 	{
    811 	  _bfd_error_handler
    812 	    ( _("error: %pB: <corrupt AArch64 used size: 0x%x>"),
    813 	     abfd, datasz);
    814 	  return property_corrupt;
    815 	}
    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;
    820       break;
    821 
    822     default:
    823       return property_ignored;
    824     }
    825 
    826   return property_number;
    827 }
    828 
    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.  */
    833 bool
    834 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *info
    835 				       ATTRIBUTE_UNUSED,
    836 				       bfd *abfd ATTRIBUTE_UNUSED,
    837 				       elf_property *aprop,
    838 				       elf_property *bprop,
    839 				       uint32_t prop)
    840 {
    841   unsigned int orig_number;
    842   bool updated = false;
    843   unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
    844 
    845   switch (pr_type)
    846     {
    847     case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
    848       {
    849 	if (aprop != NULL && bprop != NULL)
    850 	  {
    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;
    857 	    break;
    858 	  }
    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.  */
    861 	if (prop)
    862 	  {
    863 	    if (aprop != NULL)
    864 	      {
    865 		orig_number = aprop->u.number;
    866 		aprop->u.number = prop;
    867 		updated = orig_number != aprop->u.number;
    868 	      }
    869 	    else
    870 	      {
    871 		bprop->u.number = prop;
    872 		updated = true;
    873 	      }
    874 	  }
    875 	/* No PROP and BPROP is NULL, so remove APROP.  */
    876 	else if (aprop != NULL)
    877 	  {
    878 	    aprop->pr_kind = property_remove;
    879 	    updated = true;
    880 	  }
    881       }
    882       break;
    883 
    884     default:
    885       abort ();
    886     }
    887 
    888   return updated;
    889 }
    890 
    891 /* Fix up AArch64 GNU properties.  */
    892 void
    893 _bfd_aarch64_elf_link_fixup_gnu_properties
    894   (struct bfd_link_info *info ATTRIBUTE_UNUSED,
    895    elf_property_list **listp)
    896 {
    897   elf_property_list *p, *prev;
    898 
    899   for (p = *listp, prev = *listp; p; p = p->next)
    900     {
    901       unsigned int type = p->property.pr_type;
    902       if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
    903 	{
    904 	  if (p->property.pr_kind == property_remove)
    905 	    {
    906 	      /* Remove empty property.  */
    907 	      if (prev == p)
    908 		{
    909 		  *listp = p->next;
    910 		  prev = *listp;
    911 		}
    912 	      else
    913 		  prev->next = p->next;
    914 	      continue;
    915 	    }
    916 	  prev = p;
    917 	}
    918       else if (type > GNU_PROPERTY_HIPROC)
    919 	{
    920 	  /* The property list is sorted in order of type.  */
    921 	  break;
    922 	}
    923     }
    924 }
    925