(root)/
binutils-2.41/
bfd/
elfxx-aarch64.c
       1  /* AArch64-specific support for ELF.
       2     Copyright (C) 2009-2023 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  }